blob: d95890542ea4aca83bc7a12b9c6fcc08756ef078 [file] [log] [blame]
// Copyright 2016 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/ui/webui/settings/chromeos/device_keyboard_handler.h"
#include "ash/constants/ash_switches.h"
#include "ash/public/cpp/keyboard_shortcut_viewer.h"
#include "ash/public/cpp/tablet_mode.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/values.h"
#include "content/public/browser/web_ui.h"
#include "ui/chromeos/events/event_rewriter_chromeos.h"
#include "ui/chromeos/events/keyboard_layout_util.h"
namespace {
struct KeyboardsStateResult {
bool has_launcher_key = false; // ChromeOS launcher key.
bool has_external_apple_keyboard = false;
bool has_external_chromeos_keyboard = false;
bool has_external_generic_keyboard = false;
};
KeyboardsStateResult GetKeyboardsState() {
KeyboardsStateResult result;
for (const ui::InputDevice& keyboard :
ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) {
switch (ui::EventRewriterChromeOS::GetDeviceType(keyboard)) {
case ui::EventRewriterChromeOS::kDeviceInternalKeyboard:
result.has_launcher_key = true;
break;
case ui::EventRewriterChromeOS::kDeviceExternalAppleKeyboard:
result.has_external_apple_keyboard = true;
break;
case ui::EventRewriterChromeOS::kDeviceExternalChromeOsKeyboard:
result.has_external_chromeos_keyboard = true;
break;
case ui::EventRewriterChromeOS::kDeviceExternalGenericKeyboard:
case ui::EventRewriterChromeOS::kDeviceExternalUnknown:
result.has_external_generic_keyboard = true;
break;
case ui::EventRewriterChromeOS::kDeviceHotrodRemote:
case ui::EventRewriterChromeOS::kDeviceVirtualCoreKeyboard:
case ui::EventRewriterChromeOS::kDeviceUnknown:
break;
}
}
return result;
}
} // namespace
namespace chromeos {
namespace settings {
const char KeyboardHandler::kShowKeysChangedName[] = "show-keys-changed";
void KeyboardHandler::TestAPI::Initialize() {
base::ListValue args;
handler_->HandleInitialize(&args);
}
KeyboardHandler::KeyboardHandler() = default;
KeyboardHandler::~KeyboardHandler() = default;
void KeyboardHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"initializeKeyboardSettings",
base::BindRepeating(&KeyboardHandler::HandleInitialize,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"showKeyboardShortcutViewer",
base::BindRepeating(&KeyboardHandler::HandleShowKeyboardShortcutViewer,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"initializeKeyboardWatcher",
base::BindRepeating(&KeyboardHandler::HandleKeyboardChange,
base::Unretained(this)));
}
void KeyboardHandler::OnJavascriptAllowed() {
observation_.Observe(ui::DeviceDataManager::GetInstance());
}
void KeyboardHandler::OnJavascriptDisallowed() {
observation_.Reset();
}
void KeyboardHandler::OnInputDeviceConfigurationChanged(
uint8_t input_device_types) {
if (input_device_types & ui::InputDeviceEventObserver::kKeyboard) {
AllowJavascript();
UpdateShowKeys();
UpdateKeyboards();
}
}
void KeyboardHandler::HandleInitialize(const base::ListValue* args) {
AllowJavascript();
UpdateShowKeys();
UpdateKeyboards();
}
void KeyboardHandler::HandleShowKeyboardShortcutViewer(
const base::ListValue* args) const {
ash::ToggleKeyboardShortcutViewer();
}
void KeyboardHandler::HandleKeyboardChange(const base::ListValue* args) {
AllowJavascript();
UpdateKeyboards();
}
void KeyboardHandler::UpdateKeyboards() {
bool physical_keyboard = false;
// In tablet mode, physical keybards are disabled / ignored.
if (!ash::TabletMode::Get() || !ash::TabletMode::Get()->InTabletMode()) {
physical_keyboard = true;
}
if (!physical_keyboard) {
for (const ui::InputDevice& keyboard :
ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) {
if (keyboard.type != ui::InputDeviceType::INPUT_DEVICE_INTERNAL) {
physical_keyboard = true;
break;
}
}
}
FireWebUIListener("has-hardware-keyboard", base::Value(physical_keyboard));
}
void KeyboardHandler::UpdateShowKeys() {
// kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps
// Lock keys.
const KeyboardsStateResult keyboards_state = GetKeyboardsState();
const bool has_caps_lock = keyboards_state.has_external_apple_keyboard ||
keyboards_state.has_external_generic_keyboard ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kHasChromeOSKeyboard);
base::Value keyboard_params(base::Value::Type::DICTIONARY);
keyboard_params.SetKey("showCapsLock", base::Value(has_caps_lock));
keyboard_params.SetKey(
"showExternalMetaKey",
base::Value(keyboards_state.has_external_generic_keyboard));
keyboard_params.SetKey(
"showAppleCommandKey",
base::Value(keyboards_state.has_external_apple_keyboard));
// An external (USB/BT) ChromeOS keyboard is treated similarly to an internal
// ChromeOS keyboard. i.e. they are functionally the same.
keyboard_params.SetKey(
"hasLauncherKey",
base::Value(keyboards_state.has_launcher_key ||
keyboards_state.has_external_chromeos_keyboard));
const bool show_assistant_key_settings = ui::DeviceKeyboardHasAssistantKey();
keyboard_params.SetKey("hasAssistantKey",
base::Value(show_assistant_key_settings));
FireWebUIListener(kShowKeysChangedName, keyboard_params);
}
} // namespace settings
} // namespace chromeos