blob: b0b51a7973d32f507e0c98bd108c2be34b66c7d4 [file] [log] [blame]
// Copyright 2018 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 "ash/wm/tablet_mode/internal_input_devices_event_blocker.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/touch/touch_devices_controller.h"
#include "services/ws/public/cpp/input_devices/input_device_controller_client.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/devices/input_device_manager.h"
#include "ui/events/keycodes/dom/dom_code.h"
namespace ash {
namespace {
ws::InputDeviceControllerClient* GetInputDeviceControllerClient() {
return Shell::Get()->shell_delegate()->GetInputDeviceControllerClient();
}
} // namespace
InternalInputDevicesEventBlocker::InternalInputDevicesEventBlocker() {
ui::InputDeviceManager::GetInstance()->AddObserver(this);
}
InternalInputDevicesEventBlocker::~InternalInputDevicesEventBlocker() {
ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
if (should_be_blocked_)
UpdateInternalInputDevices(/*should_block=*/false);
}
void InternalInputDevicesEventBlocker::OnInputDeviceConfigurationChanged(
uint8_t input_device_types) {
if (input_device_types & ui::InputDeviceEventObserver::kKeyboard) {
UpdateInternalKeyboard(should_be_blocked_);
}
if (input_device_types & ui::InputDeviceEventObserver::kTouchpad) {
UpdateInternalTouchpad(should_be_blocked_);
}
}
void InternalInputDevicesEventBlocker::UpdateInternalInputDevices(
bool should_be_blocked) {
should_be_blocked_ = should_be_blocked;
UpdateInternalTouchpad(should_be_blocked);
UpdateInternalKeyboard(should_be_blocked);
}
bool InternalInputDevicesEventBlocker::HasInternalTouchpad() {
for (const ui::InputDevice& touchpad :
ui::InputDeviceManager::GetInstance()->GetTouchpadDevices()) {
if (touchpad.type == ui::INPUT_DEVICE_INTERNAL)
return true;
}
return false;
}
bool InternalInputDevicesEventBlocker::HasInternalKeyboard() {
for (const ui::InputDevice& keyboard :
ui::InputDeviceManager::GetInstance()->GetKeyboardDevices()) {
if (keyboard.type == ui::INPUT_DEVICE_INTERNAL)
return true;
}
return false;
}
void InternalInputDevicesEventBlocker::UpdateInternalTouchpad(
bool should_be_blocked) {
if (should_be_blocked == is_touchpad_blocked_)
return;
if (HasInternalTouchpad()) {
Shell::Get()->touch_devices_controller()->SetTouchpadEnabled(
!should_be_blocked, TouchDeviceEnabledSource::GLOBAL);
is_touchpad_blocked_ = should_be_blocked;
VLOG(1) << "Internal touchpad is blocked: " << is_touchpad_blocked_;
}
}
void InternalInputDevicesEventBlocker::UpdateInternalKeyboard(
bool should_be_blocked) {
if (should_be_blocked == is_keyboard_blocked_)
return;
// Block or unblock the internal keyboard. Note InputDeviceControllerClient
// may be null in tests.
if (HasInternalKeyboard() && GetInputDeviceControllerClient()) {
std::vector<ui::DomCode> allowed_keys;
if (should_be_blocked) {
// Only allow the acccessible keys present on the side of some devices to
// continue working if the internal keyboard events should be blocked.
allowed_keys.push_back(ui::DomCode::VOLUME_DOWN);
allowed_keys.push_back(ui::DomCode::VOLUME_UP);
allowed_keys.push_back(ui::DomCode::POWER);
}
GetInputDeviceControllerClient()->SetInternalKeyboardFilter(
should_be_blocked, allowed_keys);
is_keyboard_blocked_ = should_be_blocked;
VLOG(1) << "Internal keyboard is blocked: " << is_keyboard_blocked_;
}
}
} // namespace ash