Commit f631084c authored by Xiaoqian Dai's avatar Xiaoqian Dai Committed by Commit Bot

Update device UI mode and virtual keyboard when BT adapter changes.

It's a speculative fix for
https://listnr.corp.google.com/product/5015361/report/85785278442. In
the report, the reporter observed (from offline email):
1. opened up my mewoth/brydge
2. noticed that brydge kb wasn't working, checked quick settings menu
   and noticed bluetooth was missing
3. tried to enter password but no virtual kb came up

Since there is not a consistently repro way to repro this, my guess is
the Bluetooth stack was broken somehow but Chrome didn't get notified.
With this CL, the device should be able (hopefully) to enter the correct
ui mode and have the virtual keyboard if Bluetooth stack is broken.

Bug: None. See description
Change-Id: Ic04a769c111f772211e99c25d187726b46429626
Reviewed-on: https://chromium-review.googlesource.com/c/1337011Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Commit-Queue: Xiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608261}
parent 7da26441
......@@ -10,11 +10,16 @@
namespace ash {
BluetoothDevicesObserver::BluetoothDevicesObserver(
const DeviceChangedCallback& device_changed_callback)
: device_changed_callback_(device_changed_callback), weak_factory_(this) {
device::BluetoothAdapterFactory::GetAdapter(
base::Bind(&BluetoothDevicesObserver::InitializeOnAdapterReady,
weak_factory_.GetWeakPtr()));
const AdapterOrDeviceChangedCallback& device_changed_callback)
: adapter_or_device_changed_callback_(device_changed_callback),
weak_factory_(this) {
if (device::BluetoothAdapterFactory::IsBluetoothSupported()) {
device::BluetoothAdapterFactory::GetAdapter(
base::Bind(&BluetoothDevicesObserver::InitializeOnAdapterReady,
weak_factory_.GetWeakPtr()));
} else {
adapter_or_device_changed_callback_.Run(/*device=*/nullptr);
}
}
BluetoothDevicesObserver::~BluetoothDevicesObserver() {
......@@ -22,9 +27,21 @@ BluetoothDevicesObserver::~BluetoothDevicesObserver() {
bluetooth_adapter_->RemoveObserver(this);
}
void BluetoothDevicesObserver::AdapterPresentChanged(
device::BluetoothAdapter* adapter,
bool present) {
adapter_or_device_changed_callback_.Run(/*device=*/nullptr);
}
void BluetoothDevicesObserver::AdapterPoweredChanged(
device::BluetoothAdapter* adapter,
bool powered) {
adapter_or_device_changed_callback_.Run(/*device=*/nullptr);
}
void BluetoothDevicesObserver::DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
device_changed_callback_.Run(device);
adapter_or_device_changed_callback_.Run(device);
}
void BluetoothDevicesObserver::InitializeOnAdapterReady(
......@@ -35,8 +52,11 @@ void BluetoothDevicesObserver::InitializeOnAdapterReady(
bool BluetoothDevicesObserver::IsConnectedBluetoothDevice(
const ui::InputDevice& input_device) const {
if (!bluetooth_adapter_ || !bluetooth_adapter_->IsPowered())
if (!bluetooth_adapter_ || !bluetooth_adapter_->IsPresent() ||
!bluetooth_adapter_->IsInitialized() ||
!bluetooth_adapter_->IsPowered()) {
return false;
}
// Since there is no map from an InputDevice to a BluetoothDevice. We just
// comparing their vendor id and product id to guess a match.
......
......@@ -20,14 +20,20 @@ namespace ash {
// bluetooth device changes.
class BluetoothDevicesObserver : public device::BluetoothAdapter::Observer {
public:
using DeviceChangedCallback =
// Note |device| can be nullptr here if only the bluetooth adapter status
// changes.
using AdapterOrDeviceChangedCallback =
base::RepeatingCallback<void(device::BluetoothDevice* device)>;
explicit BluetoothDevicesObserver(
const DeviceChangedCallback& device_changed_callback);
const AdapterOrDeviceChangedCallback& device_changed_callback);
~BluetoothDevicesObserver() override;
// device::BluetoothAdapter::Observer:
void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) override;
void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) override;
void DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
......@@ -50,8 +56,9 @@ class BluetoothDevicesObserver : public device::BluetoothAdapter::Observer {
// device change event.
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
// Callback function to be called when a bluetooth device status changes.
DeviceChangedCallback device_changed_callback_;
// Callback function to be called when the bluetooth adapter's status or a
// bluetooth device's status changes.
AdapterOrDeviceChangedCallback adapter_or_device_changed_callback_;
base::WeakPtrFactory<BluetoothDevicesObserver> weak_factory_;
......
......@@ -103,9 +103,10 @@ VirtualKeyboardController::VirtualKeyboardController()
keyboard::KeyboardController::Get()->AddObserver(this);
bluetooth_devices_observer_ = std::make_unique<BluetoothDevicesObserver>(
base::BindRepeating(&VirtualKeyboardController::UpdateBluetoothDevice,
base::Unretained(this)));
bluetooth_devices_observer_ =
std::make_unique<BluetoothDevicesObserver>(base::BindRepeating(
&VirtualKeyboardController::OnBluetoothAdapterOrDeviceChanged,
base::Unretained(this)));
}
VirtualKeyboardController::~VirtualKeyboardController() {
......@@ -301,16 +302,15 @@ void VirtualKeyboardController::OnActiveUserSessionChanged(
Shell::Get()->EnableKeyboard();
}
void VirtualKeyboardController::UpdateBluetoothDevice(
void VirtualKeyboardController::OnBluetoothAdapterOrDeviceChanged(
device::BluetoothDevice* device) {
// We only care about keyboard type bluetooth device change.
if (device->GetDeviceType() != device::BluetoothDeviceType::KEYBOARD &&
device->GetDeviceType() !=
if (!device ||
device->GetDeviceType() == device::BluetoothDeviceType::KEYBOARD ||
device->GetDeviceType() ==
device::BluetoothDeviceType::KEYBOARD_MOUSE_COMBO) {
return;
UpdateDevices();
}
UpdateDevices();
}
} // namespace ash
......@@ -73,9 +73,9 @@ class ASH_EXPORT VirtualKeyboardController
// Force enable the keyboard and show it, even in laptop mode.
void ForceShowKeyboard();
// Callback function of |bluetooth_devices_observer_|. Called when |device|
// changes.
void UpdateBluetoothDevice(device::BluetoothDevice* device);
// Callback function of |bluetooth_devices_observer_|. Called when the
// bluetooth adapter or |device| changes.
void OnBluetoothAdapterOrDeviceChanged(device::BluetoothDevice* device);
// True if an external keyboard is connected.
bool has_external_keyboard_;
......
......@@ -135,9 +135,10 @@ TabletModeController::TabletModeController()
Shell::Get()->window_tree_host_manager()->AddObserver(this);
chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
ui::InputDeviceManager::GetInstance()->AddObserver(this);
bluetooth_devices_observer_ = std::make_unique<BluetoothDevicesObserver>(
base::BindRepeating(&TabletModeController::UpdateBluetoothDevice,
base::Unretained(this)));
bluetooth_devices_observer_ =
std::make_unique<BluetoothDevicesObserver>(base::BindRepeating(
&TabletModeController::OnBluetoothAdapterOrDeviceChanged,
base::Unretained(this)));
}
chromeos::PowerManagerClient* power_manager_client =
chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
......@@ -613,20 +614,19 @@ void TabletModeController::HandlePointingDeviceAddedOrRemoved() {
}
}
void TabletModeController::UpdateBluetoothDevice(
void TabletModeController::OnBluetoothAdapterOrDeviceChanged(
device::BluetoothDevice* device) {
// We only care about pointing type bluetooth device change. Note KEYBOARD
// type is also included here as sometimes a bluetooth keyboard comes with a
// touch pad.
if (device->GetDeviceType() != device::BluetoothDeviceType::MOUSE &&
device->GetDeviceType() !=
device::BluetoothDeviceType::KEYBOARD_MOUSE_COMBO &&
device->GetDeviceType() != device::BluetoothDeviceType::KEYBOARD &&
device->GetDeviceType() != device::BluetoothDeviceType::TABLET) {
return;
if (!device ||
device->GetDeviceType() == device::BluetoothDeviceType::MOUSE ||
device->GetDeviceType() ==
device::BluetoothDeviceType::KEYBOARD_MOUSE_COMBO ||
device->GetDeviceType() == device::BluetoothDeviceType::KEYBOARD ||
device->GetDeviceType() == device::BluetoothDeviceType::TABLET) {
HandlePointingDeviceAddedOrRemoved();
}
HandlePointingDeviceAddedOrRemoved();
}
void TabletModeController::UpdateInternalInputDevicesEventBlocker() {
......
......@@ -205,9 +205,9 @@ class ASH_EXPORT TabletModeController
// sent from device manager. This will exit tablet mode if needed.
void HandlePointingDeviceAddedOrRemoved();
// Callback function for |bluetooth_devices_observer_|. Called when |device|
// changes.
void UpdateBluetoothDevice(device::BluetoothDevice* device);
// Callback function of |bluetooth_devices_observer_|. Called when the
// bluetooth adapter or |device| changes.
void OnBluetoothAdapterOrDeviceChanged(device::BluetoothDevice* device);
// Update the internal mouse and keyboard event blocker |event_blocker_|
// according to current configuration. The internal input events should be
......
......@@ -902,6 +902,7 @@ TEST_F(TabletModeControllerTest, ExternalTouchPadTest) {
// Set the current list of devices to empty so that they don't interfere
// with the test.
base::RunLoop().RunUntilIdle();
ws::InputDeviceClientTestApi().SetMouseDevices({});
ws::InputDeviceClientTestApi().SetTouchpadDevices({});
base::RunLoop().RunUntilIdle();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment