Skip to content

Commit

Permalink
ash: keyboard: Virtual Keyboard Listnr Logging
Browse files Browse the repository at this point in the history
Add Listnr Logging to the Virtual Keyboard in order to collate device
information used to determine whether the virtual keyboard is displayed
or not.

Bug: b:217559869
Change-Id: Ie5f9e9970874c205efb196df2aae96ff8cf6ceb8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3544926
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Commit-Queue: William Mahon <wmahon@google.com>
Reviewed-by: Darren Shen <shend@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1019462}
  • Loading branch information
William Mahon authored and Chromium LUCI CQ committed Jun 30, 2022
1 parent 771c884 commit eecd251
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 24 deletions.
56 changes: 36 additions & 20 deletions ash/keyboard/virtual_keyboard_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "ui/display/screen.h"
#include "ui/events/devices/device_data_manager.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/devices/touchscreen_device.h"

namespace ash {
namespace {
Expand All @@ -47,10 +46,9 @@ void ResetVirtualKeyboard() {
} // namespace

VirtualKeyboardController::VirtualKeyboardController()
: has_external_keyboard_(false),
has_internal_keyboard_(false),
has_touchscreen_(false),
ignore_external_keyboard_(false) {
: has_internal_keyboard_(false),
ignore_external_keyboard_(false),
ignore_internal_keyboard_(false) {
Shell::Get()->tablet_mode_controller()->AddObserver(this);
Shell::Get()->session_controller()->AddObserver(this);
ui::DeviceDataManager::GetInstance()->AddObserver(this);
Expand Down Expand Up @@ -109,42 +107,38 @@ void VirtualKeyboardController::UpdateDevices() {
ui::DeviceDataManager* device_data_manager =
ui::DeviceDataManager::GetInstance();

// Checks for touchscreens.
has_touchscreen_ = device_data_manager->GetTouchscreenDevices().size() > 0;

touchscreens_ = device_data_manager->GetTouchscreenDevices();
// Checks for keyboards.
has_external_keyboard_ = false;
external_keyboards_.clear();
has_internal_keyboard_ = false;
for (const ui::InputDevice& device :
device_data_manager->GetKeyboardDevices()) {
if (has_internal_keyboard_ && has_external_keyboard_)
break;
ui::InputDeviceType type = device.type;
if (type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL)
has_internal_keyboard_ = true;
if ((type == ui::InputDeviceType::INPUT_DEVICE_USB ||
(type == ui::InputDeviceType::INPUT_DEVICE_BLUETOOTH &&
bluetooth_devices_observer_->IsConnectedBluetoothDevice(device))) &&
!device.suspected_imposter) {
has_external_keyboard_ = true;
external_keyboards_.push_back(device);
}
}
// Update keyboard state.
UpdateKeyboardEnabled();
}

void VirtualKeyboardController::UpdateKeyboardEnabled() {
bool ignore_internal_keyboard = Shell::Get()
->tablet_mode_controller()
->AreInternalInputDeviceEventsBlocked();
bool ignore_internal_keyboard_ = Shell::Get()
->tablet_mode_controller()
->AreInternalInputDeviceEventsBlocked();
bool is_internal_keyboard_active =
has_internal_keyboard_ && !ignore_internal_keyboard;
has_internal_keyboard_ && !ignore_internal_keyboard_;
keyboard::SetTouchKeyboardEnabled(
!is_internal_keyboard_active && has_touchscreen_ &&
(!has_external_keyboard_ || ignore_external_keyboard_));
!is_internal_keyboard_active && !touchscreens_.empty() &&
(external_keyboards_.empty() || ignore_external_keyboard_));
Shell::Get()->system_tray_notifier()->NotifyVirtualKeyboardSuppressionChanged(
!is_internal_keyboard_active && has_touchscreen_ &&
has_external_keyboard_);
!is_internal_keyboard_active && !touchscreens_.empty() &&
!external_keyboards_.empty());
}

void VirtualKeyboardController::ForceShowKeyboard() {
Expand Down Expand Up @@ -198,4 +192,26 @@ void VirtualKeyboardController::OnBluetoothAdapterOrDeviceChanged(
}
}

bool VirtualKeyboardController::HasInternalKeyboard() const {
return has_internal_keyboard_;
}

const std::vector<ui::InputDevice>&
VirtualKeyboardController::GetExternalKeyboards() const {
return external_keyboards_;
}

const std::vector<ui::TouchscreenDevice>&
VirtualKeyboardController::GetTouchscreens() const {
return touchscreens_;
}

bool VirtualKeyboardController::IsInternalKeyboardIgnored() const {
return ignore_internal_keyboard_;
}

bool VirtualKeyboardController::IsExternalKeyboardIgnored() const {
return ignore_external_keyboard_;
}

} // namespace ash
26 changes: 22 additions & 4 deletions ash/keyboard/virtual_keyboard_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
#define ASH_KEYBOARD_VIRTUAL_KEYBOARD_CONTROLLER_H_

#include <stdint.h>
#include <vector>

#include "ash/ash_export.h"
#include "ash/bluetooth_devices_observer.h"
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/tablet_mode_observer.h"
#include "ui/base/ime/ash/ime_keyset.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/devices/input_device_event_observer.h"
#include "ui/events/devices/touchscreen_device.h"

namespace ash {

Expand Down Expand Up @@ -56,6 +59,18 @@ class ASH_EXPORT VirtualKeyboardController
// SessionObserver:
void OnActiveUserSessionChanged(const AccountId& account_id) override;

bool HasInternalKeyboard() const;

const std::vector<ui::InputDevice>& GetExternalKeyboards() const;

const std::vector<ui::TouchscreenDevice>& GetTouchscreens() const;

// Returns true if the device is in tablet mode, meaning the user does not
// have access to the internal keyboard.
bool IsInternalKeyboardIgnored() const;

bool IsExternalKeyboardIgnored() const;

private:
// Updates the list of active input devices.
void UpdateDevices();
Expand All @@ -70,14 +85,17 @@ class ASH_EXPORT VirtualKeyboardController
// bluetooth adapter or |device| changes.
void OnBluetoothAdapterOrDeviceChanged(device::BluetoothDevice* device);

// True if an external keyboard is connected.
bool has_external_keyboard_;
// True if an internal keyboard is connected.
bool has_internal_keyboard_;
// True if a touchscreen is connected.
bool has_touchscreen_;
// Contains any potential external keyboards (May contain imposter keyboards).
std::vector<ui::InputDevice> external_keyboards_;
// Contains all touch screens devices (both internal and external).
std::vector<ui::TouchscreenDevice> touchscreens_;

// True if the presence of an external keyboard should be ignored.
bool ignore_external_keyboard_;
// True if the presence of an internal keyboard should be ignored.
bool ignore_internal_keyboard_;

// Observer to observe the bluetooth devices.
std::unique_ptr<BluetoothDevicesObserver> bluetooth_devices_observer_;
Expand Down
129 changes: 129 additions & 0 deletions chrome/browser/ash/system_logs/virtual_keyboard_log_source.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/system_logs/virtual_keyboard_log_source.h"

#include <memory>
#include <string>
#include <utility>

#include "ash/keyboard/keyboard_controller_impl.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/keyboard/virtual_keyboard_controller.h"
#include "ash/public/cpp/keyboard/keyboard_types.h"
#include "ash/shell.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"

namespace system_logs {

namespace {

std::string LogEntryForBooleanField(const std::string& field_name, bool value) {
return base::StrCat({field_name, ": ", base::NumberToString(value), "\n"});
}

} // namespace

VirtualKeyboardLogSource::VirtualKeyboardLogSource()
: SystemLogsSource("VirtualKeyboard") {}

void VirtualKeyboardLogSource::Fetch(SysLogsSourceCallback callback) {
DCHECK(!callback.is_null());

auto response = std::make_unique<SystemLogsResponse>();

keyboard::KeyboardUIController* keyboard_ui_controller =
keyboard::KeyboardUIController::Get();
ash::VirtualKeyboardController* virtual_keyboard_controller =
ash::Shell::Get()->keyboard_controller()->virtual_keyboard_controller();

std::string log_data;

int touchscreen_count = 1;
for (const ui::InputDevice& device :
virtual_keyboard_controller->GetTouchscreens()) {
const std::string touchscreen_count_converted =
base::NumberToString(touchscreen_count);
log_data += base::StrCat({"Touchscreen ", touchscreen_count_converted,
" Product ID"}) +
": " + base::NumberToString(device.product_id) + "\n";
log_data += base::StrCat({"Touchscreen ", touchscreen_count_converted,
" Vendor ID"}) +
": " + base::NumberToString(device.vendor_id) + "\n";
++touchscreen_count;
}

log_data +=
"Has Internal Keyboard: " +
base::NumberToString(virtual_keyboard_controller->HasInternalKeyboard()) +
"\n";
log_data += "Is Internal Keyboard Ignored: " +
base::NumberToString(
virtual_keyboard_controller->IsInternalKeyboardIgnored()) +
"\n";

int external_keyboard_count = 1;
for (const ui::InputDevice& device :
virtual_keyboard_controller->GetExternalKeyboards()) {
const std::string external_keyboard_count_converted =
base::NumberToString(external_keyboard_count);
log_data +=
base::StrCat({"External Keyboard ", external_keyboard_count_converted,
" Product ID"}) +
": " + base::NumberToString(device.product_id) + "\n";
log_data +=
base::StrCat({"External Keyboard ", external_keyboard_count_converted,
" Vendor ID"}) +
": " + base::NumberToString(device.vendor_id) + "\n";
++external_keyboard_count;
}

log_data += LogEntryForBooleanField(
"Is External Keyboard Ignored: ",
virtual_keyboard_controller->IsExternalKeyboardIgnored());
log_data += LogEntryForBooleanField(
"kPolicyEnabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kPolicyEnabled));
log_data += LogEntryForBooleanField(
"kPolicyDisabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kPolicyDisabled));
log_data += LogEntryForBooleanField(
"kAndroidDisabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kAndroidDisabled));
log_data += LogEntryForBooleanField(
"kExtensionEnabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kExtensionEnabled));
log_data += LogEntryForBooleanField(
"kExtensionDisabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kExtensionDisabled));
log_data += LogEntryForBooleanField(
"kAccessibilityEnabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kAccessibilityEnabled));
log_data += LogEntryForBooleanField(
"kShelfEnabled Flag: ", keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kShelfEnabled));
log_data += LogEntryForBooleanField(
"kTouchEnabled Flag: ", keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kTouchEnabled));
log_data += LogEntryForBooleanField(
"kCommandLineEnabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kCommandLineEnabled));
log_data += LogEntryForBooleanField(
"kCommandLineDisabled Flag: ",
keyboard_ui_controller->IsEnableFlagSet(
keyboard::KeyboardEnableFlag::kCommandLineDisabled));
response->emplace("virtual_keyboard", log_data);

std::move(callback).Run(std::move(response));
}

} // namespace system_logs
27 changes: 27 additions & 0 deletions chrome/browser/ash/system_logs/virtual_keyboard_log_source.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_SYSTEM_LOGS_VIRTUAL_KEYBOARD_LOG_SOURCE_H_
#define CHROME_BROWSER_ASH_SYSTEM_LOGS_VIRTUAL_KEYBOARD_LOG_SOURCE_H_

#include "components/feedback/system_logs/system_logs_source.h"

namespace system_logs {

class VirtualKeyboardLogSource : public SystemLogsSource {
public:
VirtualKeyboardLogSource();
~VirtualKeyboardLogSource() override = default;

VirtualKeyboardLogSource(const VirtualKeyboardLogSource&) = delete;
VirtualKeyboardLogSource& operator=(const VirtualKeyboardLogSource&) = delete;

private:
// Overridden from SystemLogsSource:
void Fetch(SysLogsSourceCallback callback) override;
};

} // namespace system_logs

#endif // CHROME_BROWSER_ASH_SYSTEM_LOGS_VIRTUAL_KEYBOARD_LOG_SOURCE_H_
2 changes: 2 additions & 0 deletions chrome/browser/chromeos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,8 @@ source_set("chromeos") {
"../ash/system_logs/traffic_counters_log_source.h",
"../ash/system_logs/ui_hierarchy_log_source.cc",
"../ash/system_logs/ui_hierarchy_log_source.h",
"../ash/system_logs/virtual_keyboard_log_source.cc",
"../ash/system_logs/virtual_keyboard_log_source.h",
"../ash/system_token_cert_db_initializer.cc",
"../ash/system_token_cert_db_initializer.h",
"../ash/tether/fake_tether_service.cc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "chrome/browser/ash/system_logs/touch_log_source.h"
#include "chrome/browser/ash/system_logs/traffic_counters_log_source.h"
#include "chrome/browser/ash/system_logs/ui_hierarchy_log_source.h"
#include "chrome/browser/ash/system_logs/virtual_keyboard_log_source.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
Expand Down Expand Up @@ -70,6 +71,8 @@ SystemLogsFetcher* BuildChromeSystemLogsFetcher(bool scrub_data) {
// Data sources that directly scrub itentifiable information.
fetcher->AddSource(std::make_unique<DebugDaemonLogSource>(scrub_data));
fetcher->AddSource(std::make_unique<NetworkHealthSource>(scrub_data));

fetcher->AddSource(std::make_unique<VirtualKeyboardLogSource>());
#if BUILDFLAG(IS_CHROMEOS_WITH_HW_DETAILS)
fetcher->AddSource(std::make_unique<RevenLogSource>());
#endif
Expand Down

0 comments on commit eecd251

Please sign in to comment.