#include "ash/accelerators/accelerator_controller_impl.h"
#include <string>
#include <utility>
#include "ash/accelerators/accelerator_capslock_state_machine.h"
#include "ash/accelerators/accelerator_commands.h"
#include "ash/accelerators/accelerator_encoding.h"
#include "ash/accelerators/accelerator_launcher_state_machine.h"
#include "ash/accelerators/accelerator_notifications.h"
#include "ash/accelerators/accelerator_shift_disable_capslock_state_machine.h"
#include "ash/accelerators/accelerator_table.h"
#include "ash/accelerators/debug_commands.h"
#include "ash/accelerators/suspend_state_machine.h"
#include "ash/accelerators/system_shortcut_behavior_policy.h"
#include "ash/accelerators/top_row_key_usage_recorder.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/devicetype.h"
#include "ash/debug.h"
#include "ash/ime/ime_controller_impl.h"
#include "ash/ime/ime_switch_type.h"
#include "ash/public/cpp/accelerator_actions.h"
#include "ash/public/cpp/accelerators.h"
#include "ash/public/mojom/input_device_settings.mojom-shared.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/system/input_device_settings/input_device_settings_notification_controller.h"
#include "ash/system/power/power_button_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/screen_pinning_controller.h"
#include "ash/wm/window_state.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/containers/fixed_flat_set.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "base/strings/strcat.h"
#include "base/system/sys_info.h"
#include "chromeos/ash/components/audio/cras_audio_handler.h"
#include "chromeos/ash/components/dbus/biod/fake_biod_client.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/aura/env.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/accelerator_manager.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/screen.h"
#include "ui/events/ash/keyboard_capability.h"
#include "ui/events/ash/keyboard_layout_util.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/events/types/event_type.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/wm/core/focus_controller.h"
#include "ui/wm/core/window_util.h"
namespace ash {
namespace {
using ::base::UserMetricsAction;
using ::chromeos::WindowStateType;
using input_method::InputMethodManager;
using OverviewBasedScreenshotKeyboardType =
AcceleratorControllerImpl::OverviewBasedScreenshotKeyboardType;
static_assert(AcceleratorAction::kDesksActivate0 ==
AcceleratorAction::kDesksActivate1 - 1 &&
AcceleratorAction::kDesksActivate1 ==
AcceleratorAction::kDesksActivate2 - 1 &&
AcceleratorAction::kDesksActivate2 ==
AcceleratorAction::kDesksActivate3 - 1 &&
AcceleratorAction::kDesksActivate3 ==
AcceleratorAction::kDesksActivate4 - 1 &&
AcceleratorAction::kDesksActivate4 ==
AcceleratorAction::kDesksActivate5 - 1 &&
AcceleratorAction::kDesksActivate5 ==
AcceleratorAction::kDesksActivate6 - 1 &&
AcceleratorAction::kDesksActivate6 ==
AcceleratorAction::kDesksActivate7 - 1,
"DESKS_ACTIVATE* actions must be consecutive");
constexpr auto kSystemShortcutPolicyBlockedAccelerators =
base::MakeFixedFlatSet<std::pair<ui::KeyboardCode, ui::EventFlags>>(
{{ui::VKEY_D, ui::EF_COMMAND_DOWN},
{ui::VKEY_E, ui::EF_COMMAND_DOWN},
{ui::VKEY_F, ui::EF_COMMAND_DOWN},
{ui::VKEY_K, ui::EF_COMMAND_DOWN},
{ui::VKEY_M, ui::EF_COMMAND_DOWN},
{ui::VKEY_R, ui::EF_COMMAND_DOWN},
{ui::VKEY_S, ui::EF_COMMAND_DOWN},
{ui::VKEY_S, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
{ui::VKEY_T, ui::EF_COMMAND_DOWN},
{ui::VKEY_U, ui::EF_COMMAND_DOWN},
{ui::VKEY_X, ui::EF_COMMAND_DOWN},
{ui::VKEY_0, ui::EF_COMMAND_DOWN},
{ui::VKEY_1, ui::EF_COMMAND_DOWN},
{ui::VKEY_2, ui::EF_COMMAND_DOWN},
{ui::VKEY_3, ui::EF_COMMAND_DOWN},
{ui::VKEY_4, ui::EF_COMMAND_DOWN},
{ui::VKEY_5, ui::EF_COMMAND_DOWN},
{ui::VKEY_6, ui::EF_COMMAND_DOWN},
{ui::VKEY_7, ui::EF_COMMAND_DOWN},
{ui::VKEY_8, ui::EF_COMMAND_DOWN},
{ui::VKEY_9, ui::EF_COMMAND_DOWN}});
ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode,
int modifiers,
bool trigger_on_press) {
ui::Accelerator accelerator(keycode, modifiers);
accelerator.set_key_state(trigger_on_press
? ui::Accelerator::KeyState::PRESSED
: ui::Accelerator::KeyState::RELEASED);
return accelerator;
}
void RecordUmaHistogram(const char* histogram_name,
DeprecatedAcceleratorUsage sample) {
auto* histogram = base::LinearHistogram::FactoryGet(
histogram_name, 1, DEPRECATED_USAGE_COUNT, DEPRECATED_USAGE_COUNT + 1,
base::HistogramBase::kUmaTargetedHistogramFlag);
histogram->Add(sample);
}
void RecordActionUmaHistogram(AcceleratorAction action,
const ui::Accelerator& accelerator) {
base::UmaHistogramSparse(
base::StrCat(
{"Ash.Accelerators.Actions.", GetAcceleratorActionName(action)}),
GetEncodedShortcut(accelerator.modifiers(), accelerator.key_code()));
}
void RecordOverviewBasedScreenshotUmaHistogram(
AcceleratorAction action,
const ui::Accelerator& accelerator) {
switch (action) {
case ash::AcceleratorAction::kTakeScreenshot:
case ash::AcceleratorAction::kTakePartialScreenshot:
case ash::AcceleratorAction::kTakeWindowScreenshot:
break;
default:
return;
}
if (accelerator.key_code() != ui::VKEY_MEDIA_LAUNCH_APP1) {
return;
}
const OverviewBasedScreenshotKeyboardType keyboard_type = [&]() {
auto* keyboard_capability = Shell::Get()->keyboard_capability();
CHECK(keyboard_capability);
if (!keyboard_capability->IsChromeOSKeyboard(
accelerator.source_device_id())) {
return OverviewBasedScreenshotKeyboardType::kNonChromeOSKeyboard;
}
if (keyboard_capability->HasTopRowActionKey(
accelerator.source_device_id(), ui::TopRowActionKey::kScreenshot)) {
return OverviewBasedScreenshotKeyboardType::
kChromeOSKeyboardWithScreenshot;
} else {
return OverviewBasedScreenshotKeyboardType::
kChromeOSKeyboardWithoutScreenshot;
}
}();
base::UmaHistogramEnumeration(
base::StrCat({"Ash.Accelerators.OverviewBasedScreenshot.",
GetAcceleratorActionName(action)}),
keyboard_type);
}
void RecordImeSwitchByAccelerator() {
UMA_HISTOGRAM_ENUMERATION("InputMethod.ImeSwitch",
ImeSwitchType::kAccelerator);
}
void RecordImeSwitchByModeChangeKey() {
UMA_HISTOGRAM_ENUMERATION("InputMethod.ImeSwitch",
ImeSwitchType::kModeChangeKey);
}
void RecordCycleBackwardMru(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_TAB)
base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
}
void RecordCycleForwardMru(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_TAB)
base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
}
void RecordToggleAssistant(const ui::Accelerator& accelerator) {
base::RecordAction(
base::UserMetricsAction("Assistant.NewEntryPoint.AssistantKey"));
}
void RecordToggleAppList(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_LWIN) {
base::RecordAction(UserMetricsAction("Accel_Search_LWin"));
} else if (accelerator.key_code() == ui::VKEY_RWIN) {
base::RecordAction(UserMetricsAction("Accel_Search_RWin"));
}
}
void RecordSwitchToNextIme(const ui::Accelerator& accelerator) {
base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
if (accelerator.key_code() == ui::VKEY_MODECHANGE)
RecordImeSwitchByModeChangeKey();
else
RecordImeSwitchByAccelerator();
}
void RecordToggleFullscreen(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_ZOOM)
base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
}
void RecordNewTab(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_T)
base::RecordAction(UserMetricsAction("Accel_NewTab_T"));
}
void RecordSwitchToLastUsedIme(bool key_pressed) {
base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
if (key_pressed) {
RecordImeSwitchByAccelerator();
}
}
bool CanHandleSwitchIme(const ui::Accelerator& accelerator) {
return Shell::Get()->ime_controller()->CanSwitchImeWithAccelerator(
accelerator);
}
void HandleSwitchIme(const ui::Accelerator& accelerator) {
base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
RecordImeSwitchByAccelerator();
Shell::Get()->ime_controller()->SwitchImeWithAccelerator(accelerator);
}
bool CanHandleToggleAppList(
const ui::Accelerator& accelerator,
const ui::Accelerator& previous_accelerator,
const std::set<ui::KeyboardCode>& currently_pressed_keys,
const AcceleratorLauncherStateMachine* launcher_state_machine) {
if (accelerator.key_code() != ui::VKEY_LWIN &&
accelerator.key_code() != ui::VKEY_RWIN) {
return true;
}
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
CHECK(launcher_state_machine);
return launcher_state_machine->CanHandleLauncher();
}
for (auto key : currently_pressed_keys) {
if (key != ui::VKEY_LWIN && key != ui::VKEY_RWIN && key != ui::VKEY_SHIFT &&
key != ui::VKEY_BROWSER_SEARCH && key != ui::VKEY_ALL_APPLICATIONS) {
return false;
}
}
if (accelerator.key_code() == ui::VKEY_LWIN ||
accelerator.key_code() == ui::VKEY_RWIN) {
if (previous_accelerator.key_state() !=
ui::Accelerator::KeyState::PRESSED ||
previous_accelerator.key_code() != accelerator.key_code() ||
previous_accelerator.interrupted_by_mouse_event()) {
return false;
}
if (Shell::Get()->accessibility_controller()->spoken_feedback().enabled()) {
return false;
}
}
return true;
}
bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator,
const AcceleratorShiftDisableCapslockStateMachine&
shift_disable_state_machine) {
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
return shift_disable_state_machine.CanHandleCapsLock() &&
Shell::Get()->ime_controller()->IsCapsLockEnabled();
}
ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
if (previous_accelerator.key_state() == ui::Accelerator::KeyState::RELEASED ||
(previous_key_code != ui::VKEY_LSHIFT &&
previous_key_code != ui::VKEY_SHIFT &&
previous_key_code != ui::VKEY_RSHIFT)) {
return false;
}
return Shell::Get()->ime_controller()->IsCapsLockEnabled();
}
bool CanHandleLockButton(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_F13 &&
Shell::Get()->keyboard_capability()->HasFunctionKey(
accelerator.source_device_id())) {
CHECK(features::IsModifierSplitEnabled());
return false;
}
return true;
}
bool CanHandleToggleCapsLock(
const ui::Accelerator& accelerator,
const ui::Accelerator& previous_accelerator,
const std::set<ui::KeyboardCode>& currently_pressed_keys,
const AcceleratorCapslockStateMachine& capslock_state_machine,
InputDeviceSettingsNotificationController* notification_controller) {
if (accelerator.key_code() == ui::VKEY_CAPITAL) {
return false;
}
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
if (capslock_state_machine.CanHandleCapsLock()) {
if (Shell::Get()->keyboard_capability()->HasFunctionKey(
accelerator.source_device_id())) {
CHECK(features::IsModifierSplitEnabled());
notification_controller->ShowCapsLockRewritingNudge();
return false;
}
return true;
}
return false;
}
for (const auto& pressed_key : currently_pressed_keys) {
if (pressed_key != ui::VKEY_LWIN && pressed_key != ui::VKEY_RWIN &&
pressed_key != ui::VKEY_MENU) {
return false;
}
}
if ((accelerator.key_code() == ui::VKEY_LWIN ||
accelerator.key_code() == ui::VKEY_RWIN) &&
accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) {
if (previous_accelerator.key_state() ==
ui::Accelerator::KeyState::PRESSED &&
(previous_accelerator.key_code() == ui::VKEY_LWIN ||
previous_accelerator.key_code() == ui::VKEY_RWIN ||
previous_accelerator.key_code() == ui::VKEY_MENU)) {
return true;
}
}
if (accelerator.key_code() == ui::VKEY_MENU &&
accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) {
if (previous_accelerator.key_state() ==
ui::Accelerator::KeyState::PRESSED &&
(previous_accelerator.key_code() == ui::VKEY_LWIN ||
previous_accelerator.key_code() == ui::VKEY_RWIN ||
previous_accelerator.key_code() == ui::VKEY_MENU)) {
return true;
}
}
return false;
}
bool IsShortcutBlockedByPolicy(ui::Accelerator accelerator) {
auto system_shortcut_behavior = GetSystemShortcutBehavior();
switch (system_shortcut_behavior) {
case SystemShortcutBehaviorType::kNormalShortcutBehavior:
case SystemShortcutBehaviorType::kAllowSearchBasedPassthrough:
case SystemShortcutBehaviorType::kAllowSearchBasedPassthroughFullscreenOnly:
return false;
case SystemShortcutBehaviorType::kIgnoreCommonVdiShortcuts:
break;
case SystemShortcutBehaviorType::kIgnoreCommonVdiShortcutsFullscreenOnly: {
auto* focused_window =
Shell::Get()->focus_controller()->GetFocusedWindow();
if (!focused_window) {
return false;
}
auto* top_level_window = wm::GetToplevelWindow(focused_window);
if (!top_level_window) {
return false;
}
if (!WindowState::Get(top_level_window)->IsFullscreen()) {
return false;
}
}
}
return kSystemShortcutPolicyBlockedAccelerators.contains(
{accelerator.key_code(), accelerator.modifiers()});
}
}
AcceleratorControllerImpl::TestApi::TestApi(
AcceleratorControllerImpl* controller)
: controller_(controller) {
DCHECK(controller_);
}
bool AcceleratorControllerImpl::TestApi::TriggerTabletModeVolumeAdjustTimer() {
return controller_->tablet_volume_controller_
.TriggerTabletModeVolumeAdjustTimerForTest();
}
void AcceleratorControllerImpl::TestApi::RegisterAccelerators(
base::span<const AcceleratorData> accelerators) {
controller_->accelerator_configuration()->Initialize(accelerators);
if (!Shell::Get()->accelerator_prefs()->IsCustomizationAllowed()) {
controller_->RegisterAccelerators(accelerators);
}
}
void AcceleratorControllerImpl::TestApi::ObserveAcceleratorUpdates() {
CHECK(Shell::Get()->accelerator_prefs()->IsCustomizationAllowed());
if (!controller_->accelerator_configuration()->HasObserver(controller_)) {
controller_->accelerator_configuration()->AddObserver(controller_);
}
}
bool AcceleratorControllerImpl::TestApi::IsActionForAcceleratorEnabled(
const ui::Accelerator& accelerator) {
return controller_->IsActionForAcceleratorEnabled(accelerator);
}
const DeprecatedAcceleratorData*
AcceleratorControllerImpl::TestApi::GetDeprecatedAcceleratorData(
AcceleratorAction action) {
return controller_->accelerator_configuration()->GetDeprecatedAcceleratorData(
action);
}
ExitWarningHandler*
AcceleratorControllerImpl::TestApi::GetExitWarningHandler() {
return &controller_->exit_warning_handler_;
}
const TabletVolumeController::SideVolumeButtonLocation&
AcceleratorControllerImpl::TestApi::GetSideVolumeButtonLocation() {
return controller_->tablet_volume_controller_
.GetSideVolumeButtonLocationForTest();
}
void AcceleratorControllerImpl::TestApi::SetSideVolumeButtonFilePath(
base::FilePath path) {
controller_->tablet_volume_controller_
.SetSideVolumeButtonFilePathForTest(
path);
}
void AcceleratorControllerImpl::TestApi::SetSideVolumeButtonLocation(
const std::string& region,
const std::string& side) {
controller_->tablet_volume_controller_
.SetSideVolumeButtonLocationForTest(
region, side);
}
void AcceleratorControllerImpl::TestApi::SetCanHandleLauncher(bool can_handle) {
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
controller_->launcher_state_machine_->SetCanHandleLauncherForTesting(
can_handle);
}
}
void AcceleratorControllerImpl::TestApi::SetCanHandleCapsLock(bool can_handle) {
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
controller_->capslock_state_machine_->SetCanHandleCapsLockForTesting(
can_handle);
}
}
AcceleratorControllerImpl::AcceleratorControllerImpl(
AshAcceleratorConfiguration* config)
: accelerator_manager_(std::make_unique<ui::AcceleratorManager>()),
accelerator_history_(std::make_unique<AcceleratorHistoryImpl>()),
launcher_state_machine_(std::make_unique<AcceleratorLauncherStateMachine>(
ui::OzonePlatform::GetInstance()->GetInputController())),
capslock_state_machine_(std::make_unique<AcceleratorCapslockStateMachine>(
ui::OzonePlatform::GetInstance()->GetInputController())),
shift_disable_state_machine_(
std::make_unique<AcceleratorShiftDisableCapslockStateMachine>(
ui::OzonePlatform::GetInstance()->GetInputController())),
suspend_state_machine_(std::make_unique<SuspendStateMachine>(
ui::OzonePlatform::GetInstance()->GetInputController())),
top_row_key_usage_recorder_(std::make_unique<TopRowKeyUsageRecorder>()),
accelerator_configuration_(config),
output_volume_metric_delay_timer_(
FROM_HERE,
CrasAudioHandler::kMetricsDelayTimerInterval,
this,
&AcceleratorControllerImpl::RecordVolumeSource) {
if (::features::IsImprovedKeyboardShortcutsEnabled()) {
InputMethodManager::Get()->AddObserver(this);
}
Init();
if (Shell::Get()->accelerator_prefs()->IsCustomizationAllowed()) {
accelerator_configuration_->AddObserver(this);
}
if (Shell::Get()->accelerator_prefs()->IsUserEnterpriseManaged()) {
Shell::Get()->accelerator_prefs()->AddObserver(this);
}
aura::Env::GetInstance()->AddPreTargetHandler(
accelerator_history_.get(), ui::EventTarget::Priority::kAccessibility);
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
aura::Env::GetInstance()->AddPreTargetHandler(
launcher_state_machine_.get(),
ui::EventTarget::Priority::kAccessibility);
aura::Env::GetInstance()->AddPreTargetHandler(
capslock_state_machine_.get(),
ui::EventTarget::Priority::kAccessibility);
aura::Env::GetInstance()->AddPreTargetHandler(
shift_disable_state_machine_.get(),
ui::EventTarget::Priority::kAccessibility);
}
aura::Env::GetInstance()->AddPreTargetHandler(
suspend_state_machine_.get(), ui::EventTarget::Priority::kAccessibility);
aura::Env::GetInstance()->AddPreTargetHandler(
top_row_key_usage_recorder_.get(),
ui::EventTarget::Priority::kAccessibility);
}
AcceleratorControllerImpl::~AcceleratorControllerImpl() {
if (::features::IsImprovedKeyboardShortcutsEnabled()) {
InputMethodManager::Get()->RemoveObserver(this);
}
if (Shell::HasInstance() &&
Shell::Get()->accelerator_prefs()->IsCustomizationAllowed()) {
accelerator_configuration_->RemoveObserver(this);
}
if (Shell::HasInstance() &&
Shell::Get()->accelerator_prefs()->IsUserEnterpriseManaged()) {
Shell::Get()->accelerator_prefs()->RemoveObserver(this);
}
aura::Env::GetInstance()->RemovePreTargetHandler(accelerator_history_.get());
if (base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
aura::Env::GetInstance()->RemovePreTargetHandler(
launcher_state_machine_.get());
aura::Env::GetInstance()->RemovePreTargetHandler(
capslock_state_machine_.get());
aura::Env::GetInstance()->RemovePreTargetHandler(
shift_disable_state_machine_.get());
}
aura::Env::GetInstance()->RemovePreTargetHandler(
suspend_state_machine_.get());
aura::Env::GetInstance()->RemovePreTargetHandler(
top_row_key_usage_recorder_.get());
}
void AcceleratorControllerImpl::InputMethodChanged(InputMethodManager* manager,
Profile* profile,
bool show_message) {
DCHECK(::features::IsImprovedKeyboardShortcutsEnabled());
DCHECK(manager);
const bool use_positional_lookup =
manager->ArePositionalShortcutsUsedByCurrentInputMethod();
accelerator_configuration_->SetUsePositionalLookup(use_positional_lookup);
accelerator_manager_->SetUsePositionalLookup(use_positional_lookup);
}
void AcceleratorControllerImpl::OnAcceleratorsUpdated() {
CHECK(Shell::Get()->accelerator_prefs()->IsCustomizationAllowed());
UnregisterAll(this);
RegisterAccelerators(accelerator_configuration_->GetAllAccelerators());
}
void AcceleratorControllerImpl::OnShortcutPolicyUpdated() {
if (!Shell::Get()->accelerator_prefs()->IsCustomizationAllowed()) {
accelerator_configuration_->RemoveObserver(this);
}
else if (!accelerator_configuration_->HasObserver(this)) {
accelerator_configuration_->AddObserver(this);
}
}
void AcceleratorControllerImpl::Register(
const std::vector<ui::Accelerator>& accelerators,
ui::AcceleratorTarget* target) {
accelerator_manager_->Register(
accelerators, ui::AcceleratorManager::kNormalPriority, target);
}
void AcceleratorControllerImpl::Unregister(const ui::Accelerator& accelerator,
ui::AcceleratorTarget* target) {
accelerator_manager_->Unregister(accelerator, target);
}
void AcceleratorControllerImpl::UnregisterAll(ui::AcceleratorTarget* target) {
accelerator_manager_->UnregisterAll(target);
}
bool AcceleratorControllerImpl::Process(const ui::Accelerator& accelerator) {
return accelerator_manager_->Process(accelerator);
}
bool AcceleratorControllerImpl::IsDeprecated(
const ui::Accelerator& accelerator) const {
return accelerator_configuration_->IsDeprecated(accelerator);
}
bool AcceleratorControllerImpl::PerformActionIfEnabled(
AcceleratorAction action,
const ui::Accelerator& accelerator) {
if (CanPerformAction(action, accelerator)) {
PerformAction(action, accelerator);
return true;
}
return false;
}
bool AcceleratorControllerImpl::OnMenuAccelerator(
const ui::Accelerator& accelerator) {
accelerator_history_->StoreCurrentAccelerator(accelerator);
const AcceleratorAction* action_ptr =
accelerator_configuration_->FindAcceleratorAction(accelerator);
return action_ptr && !base::Contains(actions_keeping_menu_open_, *action_ptr);
}
bool AcceleratorControllerImpl::IsRegistered(
const ui::Accelerator& accelerator) const {
return accelerator_manager_->IsRegistered(accelerator);
}
AcceleratorHistoryImpl* AcceleratorControllerImpl::GetAcceleratorHistory() {
return accelerator_history_.get();
}
bool AcceleratorControllerImpl::DoesAcceleratorMatchAction(
const ui::Accelerator& accelerator,
AcceleratorAction action) {
const AcceleratorAction* action_ptr =
accelerator_configuration_->FindAcceleratorAction(accelerator);
return action_ptr && *action_ptr == action;
}
void AcceleratorControllerImpl::ApplyAcceleratorForTesting(
const ui::Accelerator& accelerator) {
if (!base::FeatureList::IsEnabled(features::kShortcutStateMachines)) {
return;
}
ui::KeyEvent key_event = accelerator.ToKeyEvent();
launcher_state_machine_->OnEvent(&key_event);
capslock_state_machine_->OnEvent(&key_event);
shift_disable_state_machine_->OnEvent(&key_event);
suspend_state_machine_->OnEvent(&key_event);
}
bool AcceleratorControllerImpl::IsPreferred(
const ui::Accelerator& accelerator) const {
const AcceleratorAction* action_ptr =
accelerator_configuration_->FindAcceleratorAction(accelerator);
return action_ptr && base::Contains(preferred_actions_, *action_ptr);
}
bool AcceleratorControllerImpl::IsReserved(
const ui::Accelerator& accelerator) const {
const AcceleratorAction* action_ptr =
accelerator_configuration_->FindAcceleratorAction(accelerator);
return action_ptr && base::Contains(reserved_actions_, *action_ptr);
}
bool AcceleratorControllerImpl::AcceleratorPressed(
const ui::Accelerator& accelerator) {
const AcceleratorAction* action =
accelerator_configuration_->FindAcceleratorAction(accelerator);
if (!action || !CanPerformAction(*action, accelerator)) {
return false;
}
if (MaybeDeprecatedAcceleratorPressed(*action, accelerator) ==
AcceleratorProcessingStatus::STOP) {
return false;
}
PerformAction(*action, accelerator);
return ShouldActionConsumeKeyEvent(*action);
}
bool AcceleratorControllerImpl::CanHandleAccelerators() const {
return true;
}
void AcceleratorControllerImpl::Init() {
for (const AcceleratorAction& action : kActionsAllowedAtLoginOrLockScreen) {
actions_allowed_at_login_screen_.insert(action);
actions_allowed_at_lock_screen_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedAtLockScreen) {
actions_allowed_at_lock_screen_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedAtPowerMenu) {
actions_allowed_at_power_menu_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedAtModalWindow) {
actions_allowed_at_modal_window_.insert(action);
}
for (const AcceleratorAction& action : kPreferredActions) {
preferred_actions_.insert(action);
}
for (const AcceleratorAction& action : kReservedActions) {
reserved_actions_.insert(action);
}
for (const AcceleratorAction& action : kRepeatableActions) {
repeatable_actions_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedInAppModeOrPinnedMode) {
actions_allowed_in_app_mode_.insert(action);
actions_allowed_in_pinned_mode_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedInPinnedMode) {
actions_allowed_in_pinned_mode_.insert(action);
}
for (const AcceleratorAction& action : kActionsAllowedInAppMode) {
actions_allowed_in_app_mode_.insert(action);
}
for (const AcceleratorAction& action : kActionsNeedingWindow) {
actions_needing_window_.insert(action);
}
for (const AcceleratorAction& action : kActionsKeepingMenuOpen) {
actions_keeping_menu_open_.insert(action);
}
RegisterAccelerators(accelerator_configuration_->GetAllAccelerators());
if (debug::DebugAcceleratorsEnabled()) {
for (const AcceleratorData& data : kDebugAcceleratorData) {
reserved_actions_.insert(data.action);
}
}
if (debug::DeveloperAcceleratorsEnabled()) {
for (const AcceleratorData& data : kDeveloperAcceleratorData) {
reserved_actions_.insert(data.action);
}
}
if (features::IsModifierSplitEnabled()) {
notification_controller_ =
std::make_unique<InputDeviceSettingsNotificationController>(
message_center::MessageCenter::Get());
}
}
void AcceleratorControllerImpl::RegisterAccelerators(
base::span<const AcceleratorData> accelerators) {
std::vector<ui::Accelerator> ui_accelerators;
ui_accelerators.reserve(accelerators.size());
for (const auto& accelerator_data : accelerators) {
ui::Accelerator accelerator =
CreateAccelerator(accelerator_data.keycode, accelerator_data.modifiers,
accelerator_data.trigger_on_press);
ui_accelerators.push_back(accelerator);
}
Register(std::move(ui_accelerators), this);
}
void AcceleratorControllerImpl::RegisterAccelerators(
std::vector<ui::Accelerator> accelerators) {
Register(std::move(accelerators), this);
}
bool AcceleratorControllerImpl::IsActionForAcceleratorEnabled(
const ui::Accelerator& accelerator) const {
const AcceleratorAction* action_ptr =
accelerator_configuration_->FindAcceleratorAction(accelerator);
return action_ptr && CanPerformAction(*action_ptr, accelerator);
}
bool AcceleratorControllerImpl::CanPerformAction(
AcceleratorAction action,
const ui::Accelerator& accelerator) const {
if (IsShortcutBlockedByPolicy(accelerator)) {
return false;
}
if (accelerator.IsRepeat() && !base::Contains(repeatable_actions_, action))
return false;
AcceleratorProcessingRestriction restriction =
GetAcceleratorProcessingRestriction(action);
if (restriction != RESTRICTION_NONE)
return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
const ui::Accelerator& previous_accelerator =
accelerator_history_->previous_accelerator();
switch (action) {
case AcceleratorAction::kAccessibilityAction:
return ::features::IsAccessibilityAcceleratorEnabled();
case AcceleratorAction::kCycleBackwardMru:
case AcceleratorAction::kCycleForwardMru:
return accelerators::CanCycleMru();
case AcceleratorAction::kCycleSameAppWindowsBackward:
case AcceleratorAction::kCycleSameAppWindowsForward:
return accelerators::CanCycleSameAppWindows();
case AcceleratorAction::kDesksActivateDeskLeft:
case AcceleratorAction::kDesksActivateDeskRight:
case AcceleratorAction::kDesksMoveActiveItemLeft:
case AcceleratorAction::kDesksMoveActiveItemRight:
case AcceleratorAction::kDesksNewDesk:
case AcceleratorAction::kDesksRemoveCurrentDesk:
case AcceleratorAction::kDesksActivate0:
case AcceleratorAction::kDesksActivate1:
case AcceleratorAction::kDesksActivate2:
case AcceleratorAction::kDesksActivate3:
case AcceleratorAction::kDesksActivate4:
case AcceleratorAction::kDesksActivate5:
case AcceleratorAction::kDesksActivate6:
case AcceleratorAction::kDesksActivate7:
case AcceleratorAction::kDesksToggleAssignToAllDesks:
return true;
case AcceleratorAction::kDebugKeyboardBacklightToggle:
case AcceleratorAction::kDebugMicrophoneMuteToggle:
case AcceleratorAction::kDebugPrintLayerHierarchy:
case AcceleratorAction::kDebugPrintViewHierarchy:
case AcceleratorAction::kDebugPrintWindowHierarchy:
case AcceleratorAction::kDebugShowInformedRestore:
case AcceleratorAction::kDebugShowToast:
case AcceleratorAction::kDebugShowSystemNudge:
case AcceleratorAction::kDebugShowTestWindow:
case AcceleratorAction::kDebugSystemUiStyleViewer:
case AcceleratorAction::kDebugStartSunfishSession:
case AcceleratorAction::kDebugToggleDarkMode:
case AcceleratorAction::kDebugToggleDynamicColor:
case AcceleratorAction::kDebugClearUseKMeansPref:
case AcceleratorAction::kDebugToggleFocusModeState:
case AcceleratorAction::kDebugTogglePowerButtonMenu:
case AcceleratorAction::kDebugToggleShowDebugBorders:
case AcceleratorAction::kDebugToggleShowFpsCounter:
case AcceleratorAction::kDebugToggleShowPaintRects:
case AcceleratorAction::kDebugToggleTouchPad:
case AcceleratorAction::kDebugToggleTouchScreen:
case AcceleratorAction::kDebugToggleTabletMode:
case AcceleratorAction::kDebugToggleWallpaperMode:
case AcceleratorAction::kDebugTriggerCrash:
case AcceleratorAction::kDebugToggleHudDisplay:
case AcceleratorAction::kDebugToggleVirtualTrackpad:
return debug::DebugAcceleratorsEnabled();
case AcceleratorAction::kDevAddRemoveDisplay:
case AcceleratorAction::kDevToggleAppList:
case AcceleratorAction::kDevToggleUnifiedDesktop:
return debug::DeveloperAcceleratorsEnabled();
case AcceleratorAction::kDisableCapsLock:
return CanHandleDisableCapsLock(previous_accelerator,
*shift_disable_state_machine_);
case AcceleratorAction::kLockScreen:
return accelerators::CanLock();
case AcceleratorAction::kMagnifierZoomIn:
case AcceleratorAction::kMagnifierZoomOut:
return accelerators::CanPerformMagnifierZoom();
case AcceleratorAction::kMicrophoneMuteToggle:
return true;
case AcceleratorAction::kMoveActiveWindowBetweenDisplays:
return accelerators::CanMoveActiveWindowBetweenDisplays();
case AcceleratorAction::kNewIncognitoWindow:
return accelerators::CanCreateNewIncognitoWindow();
case AcceleratorAction::kPasteClipboardHistoryPlainText:
return true;
case AcceleratorAction::kPrivacyScreenToggle:
return accelerators::CanTogglePrivacyScreen();
case AcceleratorAction::kRotateScreen:
return true;
case AcceleratorAction::kScaleUiDown:
case AcceleratorAction::kScaleUiReset:
case AcceleratorAction::kScaleUiUp:
return true;
case AcceleratorAction::kToggleStylusTools:
return accelerators::CanShowStylusTools();
case AcceleratorAction::kStartAssistant:
return true;
case AcceleratorAction::kStopScreenRecording:
return accelerators::CanStopScreenRecording();
case AcceleratorAction::kSwapPrimaryDisplay:
return accelerators::CanSwapPrimaryDisplay();
case AcceleratorAction::kSwitchIme:
return CanHandleSwitchIme(accelerator);
case AcceleratorAction::kSwitchToNextIme:
return accelerators::CanCycleInputMethod();
case AcceleratorAction::kSwitchToLastUsedIme:
return accelerators::CanCycleInputMethod();
case AcceleratorAction::kSwitchToPreviousUser:
case AcceleratorAction::kSwitchToNextUser:
return accelerators::CanCycleUser();
case AcceleratorAction::kTilingWindowResizeLeft:
case AcceleratorAction::kTilingWindowResizeRight:
case AcceleratorAction::kTilingWindowResizeUp:
case AcceleratorAction::kTilingWindowResizeDown:
return accelerators::CanTilingWindowResize();
case AcceleratorAction::kToggleAppList:
return CanHandleToggleAppList(
accelerator, previous_accelerator,
accelerator_history_->currently_pressed_keys(),
launcher_state_machine_.get());
case AcceleratorAction::kToggleCalendar:
return true;
case AcceleratorAction::kToggleCameraAllowed:
return features::IsToggleCameraShortcutEnabled();
case AcceleratorAction::kToggleCapsLock:
return CanHandleToggleCapsLock(
accelerator, previous_accelerator,
accelerator_history_->currently_pressed_keys(),
*capslock_state_machine_, notification_controller_.get());
case AcceleratorAction::kToggleClipboardHistory:
return true;
case AcceleratorAction::kToggleDoNotDisturb:
return features::IsDoNotDisturbShortcutEnabled();
case AcceleratorAction::kEnableSelectToSpeak:
return true;
case AcceleratorAction::kEnableOrToggleDictation:
return accelerators::CanEnableOrToggleDictation();
case AcceleratorAction::kToggleDockedMagnifier:
return true;
case AcceleratorAction::kToggleFloating:
return accelerators::CanToggleFloatingWindow();
case AcceleratorAction::kToggleFullscreenMagnifier:
return true;
case AcceleratorAction::kToggleGameDashboard:
return accelerators::CanToggleGameDashboard();
case AcceleratorAction::kToggleMessageCenterBubble:
return true;
case AcceleratorAction::kToggleMirrorMode:
return true;
case AcceleratorAction::kToggleMouseKeys:
return ::features::IsAccessibilityMouseKeysEnabled();
case AcceleratorAction::kToggleOverview:
return accelerators::CanToggleOverview();
case AcceleratorAction::kToggleSnapGroup:
return accelerators::CanToggleSnapGroup();
case AcceleratorAction::kToggleSnapGroupWindowsMinimizeAndRestore:
return false;
case AcceleratorAction::kToggleMultitaskMenu:
return accelerators::CanToggleMultitaskMenu();
case AcceleratorAction::kTouchHudClear:
case AcceleratorAction::kTouchHudModeChange:
return accelerators::CanActivateTouchHud();
case AcceleratorAction::kUnpin:
return accelerators::CanUnpinWindow();
case AcceleratorAction::kWindowCycleSnapLeft:
case AcceleratorAction::kWindowCycleSnapRight:
return accelerators::CanWindowSnap();
case AcceleratorAction::kFocusPip:
return accelerators::CanFindPipWidget();
case AcceleratorAction::kFocusCameraPreview:
return accelerators::CanFocusCameraPreview();
case AcceleratorAction::kMinimizeTopWindowOnBack:
return accelerators::CanMinimizeTopWindowOnBack();
case AcceleratorAction::kTakePartialScreenshot:
case AcceleratorAction::kTakeScreenshot:
case AcceleratorAction::kTakeWindowScreenshot:
return accelerators::CanScreenshot(action ==
AcceleratorAction::kTakeScreenshot);
case AcceleratorAction::kStartSunfishSession:
return accelerators::CanStartSunfishSession();
case AcceleratorAction::kToggleProjectorMarker:
return accelerators::CanToggleProjectorMarker();
case AcceleratorAction::kToggleResizeLockMenu:
return accelerators::CanToggleResizeLockMenu();
case AcceleratorAction::kDebugToggleVideoConferenceCameraTrayIcon:
return true;
case AcceleratorAction::kLockPressed:
case AcceleratorAction::kLockReleased:
return CanHandleLockButton(accelerator);
case AcceleratorAction::kResizePipWindow:
return accelerators::CanResizePipWindow();
case AcceleratorAction::kToggleGeminiApp:
return accelerators::CanToggleGeminiApp();
case AcceleratorAction::kBrightnessDown:
case AcceleratorAction::kBrightnessUp:
case AcceleratorAction::kExit:
case AcceleratorAction::kFocusNextPane:
case AcceleratorAction::kFocusPreviousPane:
case AcceleratorAction::kFocusShelf:
case AcceleratorAction::kKeyboardBacklightToggle:
case AcceleratorAction::kKeyboardBrightnessDown:
case AcceleratorAction::kKeyboardBrightnessUp:
case AcceleratorAction::kLaunchApp0:
case AcceleratorAction::kLaunchApp1:
case AcceleratorAction::kLaunchApp2:
case AcceleratorAction::kLaunchApp3:
case AcceleratorAction::kLaunchApp4:
case AcceleratorAction::kLaunchApp5:
case AcceleratorAction::kLaunchApp6:
case AcceleratorAction::kLaunchApp7:
case AcceleratorAction::kLaunchLastApp:
case AcceleratorAction::kMediaFastForward:
case AcceleratorAction::kMediaNextTrack:
case AcceleratorAction::kMediaPause:
case AcceleratorAction::kMediaPlay:
case AcceleratorAction::kMediaPlayPause:
case AcceleratorAction::kMediaPrevTrack:
case AcceleratorAction::kMediaRewind:
case AcceleratorAction::kMediaStop:
case AcceleratorAction::kNewTab:
case AcceleratorAction::kNewWindow:
case AcceleratorAction::kOpenCalculator:
case AcceleratorAction::kOpenCrosh:
case AcceleratorAction::kOpenDiagnostics:
case AcceleratorAction::kOpenFeedbackPage:
case AcceleratorAction::kOpenFileManager:
case AcceleratorAction::kOpenGetHelp:
case AcceleratorAction::kPowerPressed:
case AcceleratorAction::kPowerReleased:
case AcceleratorAction::kPrintUiHierarchies:
case AcceleratorAction::kRestoreTab:
case AcceleratorAction::kRotateWindow:
case AcceleratorAction::kShowEmojiPicker:
case AcceleratorAction::kToggleImeMenuBubble:
case AcceleratorAction::kToggleQuickInsert:
case AcceleratorAction::kShowShortcutViewer:
case AcceleratorAction::kShowTaskManager:
case AcceleratorAction::kSuspend:
case AcceleratorAction::kToggleFullscreen:
case AcceleratorAction::kToggleHighContrast:
case AcceleratorAction::kToggleMaximized:
case AcceleratorAction::kToggleSpokenFeedback:
case AcceleratorAction::kToggleSystemTrayBubble:
case AcceleratorAction::kToggleWifi:
case AcceleratorAction::kVolumeDown:
case AcceleratorAction::kVolumeMute:
case AcceleratorAction::kVolumeMuteToggle:
case AcceleratorAction::kVolumeUp:
case AcceleratorAction::kWindowMinimize:
return true;
case AcceleratorAction::kTouchFingerprintSensor1:
case AcceleratorAction::kTouchFingerprintSensor2:
case AcceleratorAction::kTouchFingerprintSensor3:
return FakeBiodClient::Get() != nullptr;
}
}
void AcceleratorControllerImpl::PerformAction(
AcceleratorAction action,
const ui::Accelerator& accelerator) {
AcceleratorProcessingRestriction restriction =
GetAcceleratorProcessingRestriction(action);
if (restriction != RESTRICTION_NONE)
return;
if ((action == AcceleratorAction::kVolumeDown ||
action == AcceleratorAction::kVolumeUp) &&
display::Screen::Get()->InTabletMode()) {
if (tablet_volume_controller_.ShouldSwapSideVolumeButtons(
accelerator.source_device_id()))
action = action == AcceleratorAction::kVolumeDown
? AcceleratorAction::kVolumeUp
: AcceleratorAction::kVolumeDown;
tablet_volume_controller_.StartTabletModeVolumeAdjustTimer(
action == AcceleratorAction::kVolumeUp);
}
const bool key_pressed =
accelerator.key_state() == ui::Accelerator::KeyState::PRESSED;
switch (action) {
case AcceleratorAction::kAccessibilityAction:
if (::features::IsAccessibilityAcceleratorEnabled()) {
accelerators::AccessibilityAction();
}
break;
case AcceleratorAction::kBrightnessDown: {
base::RecordAction(UserMetricsAction("Accel_BrightnessDown_F6"));
accelerators::BrightnessDown();
break;
}
case AcceleratorAction::kBrightnessUp: {
base::RecordAction(UserMetricsAction("Accel_BrightnessUp_F7"));
accelerators::BrightnessUp();
break;
}
case AcceleratorAction::kCycleBackwardMru:
RecordCycleBackwardMru(accelerator);
accelerators::CycleBackwardMru(false);
break;
case AcceleratorAction::kCycleForwardMru:
RecordCycleForwardMru(accelerator);
accelerators::CycleForwardMru(false);
break;
case AcceleratorAction::kCycleSameAppWindowsBackward:
accelerators::CycleBackwardMru(true);
break;
case AcceleratorAction::kCycleSameAppWindowsForward:
accelerators::CycleForwardMru(true);
break;
case AcceleratorAction::kDesksActivateDeskLeft:
accelerators::ActivateDesk(true);
break;
case AcceleratorAction::kDesksActivateDeskRight:
accelerators::ActivateDesk(false);
break;
case AcceleratorAction::kDesksMoveActiveItemLeft:
accelerators::MoveActiveItem(true);
break;
case AcceleratorAction::kDesksMoveActiveItemRight:
accelerators::MoveActiveItem(false);
break;
case AcceleratorAction::kDesksNewDesk:
accelerators::NewDesk();
break;
case AcceleratorAction::kDesksRemoveCurrentDesk:
accelerators::RemoveCurrentDesk();
break;
case AcceleratorAction::kDesksActivate0:
case AcceleratorAction::kDesksActivate1:
case AcceleratorAction::kDesksActivate2:
case AcceleratorAction::kDesksActivate3:
case AcceleratorAction::kDesksActivate4:
case AcceleratorAction::kDesksActivate5:
case AcceleratorAction::kDesksActivate6:
case AcceleratorAction::kDesksActivate7:
accelerators::ActivateDeskAtIndex(action);
break;
case AcceleratorAction::kDesksToggleAssignToAllDesks:
accelerators::ToggleAssignToAllDesk();
break;
case AcceleratorAction::kDebugKeyboardBacklightToggle:
case AcceleratorAction::kDebugMicrophoneMuteToggle:
case AcceleratorAction::kDebugPrintLayerHierarchy:
case AcceleratorAction::kDebugPrintViewHierarchy:
case AcceleratorAction::kDebugPrintWindowHierarchy:
case AcceleratorAction::kDebugShowInformedRestore:
case AcceleratorAction::kDebugShowToast:
case AcceleratorAction::kDebugShowSystemNudge:
case AcceleratorAction::kDebugShowTestWindow:
case AcceleratorAction::kDebugStartSunfishSession:
case AcceleratorAction::kDebugToggleDarkMode:
case AcceleratorAction::kDebugToggleDynamicColor:
case AcceleratorAction::kDebugClearUseKMeansPref:
case AcceleratorAction::kDebugToggleFocusModeState:
case AcceleratorAction::kDebugTogglePowerButtonMenu:
case AcceleratorAction::kDebugToggleVideoConferenceCameraTrayIcon:
case AcceleratorAction::kDebugSystemUiStyleViewer:
debug::PerformDebugActionIfEnabled(action);
break;
case AcceleratorAction::kDebugToggleShowDebugBorders:
debug::ToggleShowDebugBorders();
break;
case AcceleratorAction::kDebugToggleShowFpsCounter:
debug::ToggleShowFpsCounter();
break;
case AcceleratorAction::kDebugToggleShowPaintRects:
debug::ToggleShowPaintRects();
break;
case AcceleratorAction::kDebugToggleTouchPad:
case AcceleratorAction::kDebugToggleTouchScreen:
case AcceleratorAction::kDebugToggleTabletMode:
case AcceleratorAction::kDebugToggleWallpaperMode:
case AcceleratorAction::kDebugTriggerCrash:
case AcceleratorAction::kDebugToggleHudDisplay:
case AcceleratorAction::kDebugToggleVirtualTrackpad:
debug::PerformDebugActionIfEnabled(action);
break;
case AcceleratorAction::kDevAddRemoveDisplay:
Shell::Get()->display_manager()->AddRemoveDisplay();
break;
case AcceleratorAction::kDevToggleAppList:
RecordToggleAppList(accelerator);
accelerators::ToggleAppList(AppListShowSource::kSearchKey,
base::TimeTicks());
break;
case AcceleratorAction::kDevToggleUnifiedDesktop:
accelerators::ToggleUnifiedDesktop();
break;
case AcceleratorAction::kDisableCapsLock:
base::RecordAction(base::UserMetricsAction("Accel_Disable_Caps_Lock"));
accelerators::DisableCapsLock();
break;
case AcceleratorAction::kExit:
exit_warning_handler_.HandleAccelerator();
break;
case AcceleratorAction::kFocusNextPane:
base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
accelerators::RotatePaneFocus(FocusCycler::FORWARD);
break;
case AcceleratorAction::kFocusPreviousPane:
base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
accelerators::RotatePaneFocus(FocusCycler::BACKWARD);
break;
case AcceleratorAction::kFocusShelf:
base::RecordAction(UserMetricsAction("Accel_Focus_Shelf"));
accelerators::FocusShelf();
break;
case AcceleratorAction::kFocusCameraPreview:
accelerators::FocusCameraPreview();
break;
case AcceleratorAction::kFocusPip:
base::RecordAction(base::UserMetricsAction("Accel_Focus_Pip"));
accelerators::FocusPip();
break;
case AcceleratorAction::kKeyboardBacklightToggle:
base::RecordAction(base::UserMetricsAction("Accel_Keyboard_Backlight"));
accelerators::ToggleKeyboardBacklight();
break;
case AcceleratorAction::kKeyboardBrightnessDown: {
base::RecordAction(UserMetricsAction("Accel_KeyboardBrightnessDown_F6"));
accelerators::KeyboardBrightnessDown();
break;
}
case AcceleratorAction::kKeyboardBrightnessUp: {
base::RecordAction(UserMetricsAction("Accel_KeyboardBrightnessUp_F7"));
accelerators::KeyboardBrightnessUp();
break;
}
case AcceleratorAction::kLaunchApp0:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(0);
break;
case AcceleratorAction::kLaunchApp1:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(1);
break;
case AcceleratorAction::kLaunchApp2:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(2);
break;
case AcceleratorAction::kLaunchApp3:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(3);
break;
case AcceleratorAction::kLaunchApp4:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(4);
break;
case AcceleratorAction::kLaunchApp5:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(5);
break;
case AcceleratorAction::kLaunchApp6:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(6);
break;
case AcceleratorAction::kLaunchApp7:
base::RecordAction(base::UserMetricsAction("Accel_Launch_App"));
accelerators::LaunchAppN(7);
break;
case AcceleratorAction::kLaunchLastApp:
base::RecordAction(base::UserMetricsAction("Accel_Launch_Last_App"));
accelerators::LaunchLastApp();
break;
case AcceleratorAction::kLockPressed:
case AcceleratorAction::kLockReleased:
accelerators::LockPressed(action == AcceleratorAction::kLockPressed);
break;
case AcceleratorAction::kLockScreen:
base::RecordAction(base::UserMetricsAction("Accel_LockScreen_L"));
accelerators::LockScreen();
break;
case AcceleratorAction::kMagnifierZoomIn:
accelerators::ActiveMagnifierZoom(1);
break;
case AcceleratorAction::kMagnifierZoomOut:
accelerators::ActiveMagnifierZoom(-1);
break;
case AcceleratorAction::kMediaFastForward:
base::RecordAction(base::UserMetricsAction("Accel_Media_Fast_Forward"));
accelerators::MediaFastForward();
break;
case AcceleratorAction::kMediaNextTrack:
base::RecordAction(base::UserMetricsAction("Accel_Media_Next_Track"));
accelerators::MediaNextTrack();
break;
case AcceleratorAction::kMediaPause:
base::RecordAction(base::UserMetricsAction("Accel_Media_Pause"));
accelerators::MediaPause();
break;
case AcceleratorAction::kMediaPlay:
base::RecordAction(base::UserMetricsAction("Accel_Media_Play"));
accelerators::MediaPlay();
break;
case AcceleratorAction::kMediaPlayPause:
base::RecordAction(base::UserMetricsAction("Accel_Media_PlayPause"));
accelerators::MediaPlayPause();
break;
case AcceleratorAction::kMediaPrevTrack:
base::RecordAction(base::UserMetricsAction("Accel_Media_Prev_Track"));
accelerators::MediaPrevTrack();
break;
case AcceleratorAction::kMediaRewind:
base::RecordAction(base::UserMetricsAction("Accel_Media_Rewind"));
accelerators::MediaRewind();
break;
case AcceleratorAction::kMediaStop:
base::RecordAction(base::UserMetricsAction("Accel_Media_Stop"));
accelerators::MediaStop();
break;
case AcceleratorAction::kMicrophoneMuteToggle:
base::RecordAction(base::UserMetricsAction("Accel_Microphone_Mute"));
accelerators::MicrophoneMuteToggle();
break;
case AcceleratorAction::kMoveActiveWindowBetweenDisplays:
accelerators::MoveActiveWindowBetweenDisplays();
break;
case AcceleratorAction::kNewIncognitoWindow:
base::RecordAction(base::UserMetricsAction("Accel_New_Incognito_Window"));
accelerators::NewIncognitoWindow();
break;
case AcceleratorAction::kNewTab:
RecordNewTab(accelerator);
accelerators::NewTab();
break;
case AcceleratorAction::kNewWindow:
base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
accelerators::NewWindow();
break;
case AcceleratorAction::kOpenCalculator:
base::RecordAction(base::UserMetricsAction("Accel_Open_Calculator"));
accelerators::OpenCalculator();
break;
case AcceleratorAction::kOpenCrosh:
base::RecordAction(base::UserMetricsAction("Accel_Open_Crosh"));
accelerators::OpenCrosh();
break;
case AcceleratorAction::kOpenDiagnostics:
base::RecordAction(base::UserMetricsAction("Accel_Open_Diagnostics"));
accelerators::OpenDiagnostics();
break;
case AcceleratorAction::kOpenFeedbackPage:
base::RecordAction(base::UserMetricsAction("Accel_Open_Feedback_Page"));
accelerators::OpenFeedbackPage();
break;
case AcceleratorAction::kOpenFileManager:
base::RecordAction(base::UserMetricsAction("Accel_Open_File_Manager"));
accelerators::OpenFileManager();
break;
case AcceleratorAction::kOpenGetHelp:
accelerators::OpenHelp();
break;
case AcceleratorAction::kPasteClipboardHistoryPlainText:
accelerators::ToggleClipboardHistory(true);
break;
case AcceleratorAction::kPowerPressed:
case AcceleratorAction::kPowerReleased:
if (!base::SysInfo::IsRunningOnChromeOS()) {
accelerators::PowerPressed(action == AcceleratorAction::kPowerPressed);
}
break;
case AcceleratorAction::kPrintUiHierarchies:
debug::PrintUIHierarchies();
break;
case AcceleratorAction::kPrivacyScreenToggle:
base::RecordAction(UserMetricsAction("Accel_Toggle_Privacy_Screen"));
accelerators::TogglePrivacyScreen();
break;
case AcceleratorAction::kRotateScreen:
accelerators::RotateScreen();
break;
case AcceleratorAction::kRestoreTab:
base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
accelerators::RestoreTab();
break;
case AcceleratorAction::kRotateWindow:
base::RecordAction(UserMetricsAction("Accel_Rotate_Active_Window"));
accelerators::RotateActiveWindow();
break;
case AcceleratorAction::kScaleUiDown:
accelerators::ZoomDisplay(false );
break;
case AcceleratorAction::kScaleUiReset:
accelerators::ResetDisplayZoom();
break;
case AcceleratorAction::kScaleUiUp:
accelerators::ZoomDisplay(true );
break;
case AcceleratorAction::kShowEmojiPicker:
base::RecordAction(UserMetricsAction("Accel_Show_Emoji_Picker"));
accelerators::ShowEmojiPicker(accelerator.time_stamp());
break;
case AcceleratorAction::kToggleImeMenuBubble:
base::RecordAction(UserMetricsAction("Accel_Show_Ime_Menu_Bubble"));
accelerators::ToggleImeMenuBubble();
break;
case AcceleratorAction::kToggleQuickInsert:
accelerators::ToggleQuickInsert(accelerator.time_stamp());
break;
case AcceleratorAction::kToggleProjectorMarker:
accelerators::ToggleProjectorMarker();
break;
case AcceleratorAction::kShowShortcutViewer:
accelerators::ShowShortcutCustomizationApp();
break;
case AcceleratorAction::kToggleStylusTools:
base::RecordAction(UserMetricsAction("Accel_Show_Stylus_Tools"));
accelerators::ToggleStylusTools();
break;
case AcceleratorAction::kShowTaskManager:
base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
accelerators::ShowTaskManager();
break;
case AcceleratorAction::kStartAssistant:
RecordToggleAssistant(accelerator);
accelerators::ToggleAssistant();
break;
case AcceleratorAction::kStartSunfishSession:
accelerators::StartSunfishSession();
break;
case AcceleratorAction::kSuspend:
base::RecordAction(UserMetricsAction("Accel_Suspend"));
suspend_state_machine_->StartObservingToTriggerSuspend(accelerator);
break;
case AcceleratorAction::kSwapPrimaryDisplay:
base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
accelerators::ShiftPrimaryDisplay();
break;
case AcceleratorAction::kStopScreenRecording:
accelerators::StopScreenRecording();
break;
case AcceleratorAction::kSwitchIme:
HandleSwitchIme(accelerator);
break;
case AcceleratorAction::kSwitchToLastUsedIme:
RecordSwitchToLastUsedIme(key_pressed);
accelerators::SwitchToLastUsedIme(key_pressed);
break;
case AcceleratorAction::kSwitchToNextIme:
RecordSwitchToNextIme(accelerator);
accelerators::SwitchToNextIme();
break;
case AcceleratorAction::kSwitchToNextUser:
base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
accelerators::CycleUser(CycleUserDirection::NEXT);
break;
case AcceleratorAction::kSwitchToPreviousUser:
base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
accelerators::CycleUser(CycleUserDirection::PREVIOUS);
break;
case AcceleratorAction::kTakePartialScreenshot:
accelerators::MaybeTakePartialScreenshot();
break;
case AcceleratorAction::kTakeScreenshot:
base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
accelerators::TakeScreenshot(accelerator.key_code() == ui::VKEY_SNAPSHOT);
break;
case AcceleratorAction::kTakeWindowScreenshot:
accelerators::MaybeTakeWindowScreenshot();
break;
case AcceleratorAction::kTilingWindowResizeLeft:
case AcceleratorAction::kTilingWindowResizeRight:
case AcceleratorAction::kTilingWindowResizeUp:
case AcceleratorAction::kTilingWindowResizeDown:
accelerators::PerformTilingWindowResize(action);
break;
case AcceleratorAction::kToggleAppList: {
RecordToggleAppList(accelerator);
accelerators::ToggleAppList(AppListShowSource::kSearchKey,
base::TimeTicks());
break;
}
case AcceleratorAction::kToggleCameraAllowed:
accelerators::ToggleCameraAllowed();
break;
case AcceleratorAction::kToggleCalendar:
accelerators::ToggleCalendar();
break;
case AcceleratorAction::kToggleCapsLock:
base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
accelerators::ToggleCapsLock();
break;
case AcceleratorAction::kToggleClipboardHistory:
accelerators::ToggleClipboardHistory(false);
break;
case AcceleratorAction::kToggleDoNotDisturb:
accelerators::ToggleDoNotDisturb();
break;
case AcceleratorAction::kEnableSelectToSpeak:
accelerators::EnableSelectToSpeak();
break;
case AcceleratorAction::kEnableOrToggleDictation:
accelerators::EnableOrToggleDictation();
break;
case AcceleratorAction::kToggleDockedMagnifier:
base::RecordAction(UserMetricsAction("Accel_Toggle_Docked_Magnifier"));
accelerators::ToggleDockedMagnifier();
break;
case AcceleratorAction::kToggleFloating:
accelerators::ToggleFloating();
break;
case AcceleratorAction::kToggleFullscreen:
RecordToggleFullscreen(accelerator);
accelerators::ToggleFullscreen();
break;
case AcceleratorAction::kToggleFullscreenMagnifier:
base::RecordAction(
UserMetricsAction("Accel_Toggle_Fullscreen_Magnifier"));
accelerators::ToggleFullscreenMagnifier();
break;
case AcceleratorAction::kToggleGameDashboard:
accelerators::ToggleGameDashboard();
break;
case AcceleratorAction::kToggleHighContrast:
base::RecordAction(UserMetricsAction("Accel_Toggle_High_Contrast"));
accelerators::ToggleHighContrast();
break;
case AcceleratorAction::kToggleMaximized:
accelerators::ToggleMaximized();
break;
case AcceleratorAction::kToggleMessageCenterBubble:
base::RecordAction(
UserMetricsAction("Accel_Toggle_Message_Center_Bubble"));
accelerators::ToggleMessageCenterBubble();
break;
case AcceleratorAction::kToggleMirrorMode:
base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
accelerators::ToggleMirrorMode();
break;
case AcceleratorAction::kToggleMouseKeys:
if (::features::IsAccessibilityMouseKeysEnabled()) {
accelerators::ToggleMouseKeys();
}
break;
case AcceleratorAction::kToggleMultitaskMenu:
accelerators::ToggleMultitaskMenu();
return;
case AcceleratorAction::kToggleOverview:
base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
accelerators::ToggleOverview();
break;
case AcceleratorAction::kToggleSnapGroup:
accelerators::ToggleSnapGroup();
break;
case AcceleratorAction::kToggleSnapGroupWindowsMinimizeAndRestore:
accelerators::ToggleSnapGroupsMinimize();
break;
case AcceleratorAction::kToggleResizeLockMenu:
base::RecordAction(
base::UserMetricsAction("Accel_Toggle_Resize_Lock_Menu"));
accelerators::ToggleResizeLockMenu();
break;
case AcceleratorAction::kToggleSpokenFeedback:
base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
accelerators::ToggleSpokenFeedback();
break;
case AcceleratorAction::kToggleSystemTrayBubble:
base::RecordAction(UserMetricsAction("Accel_Toggle_System_Tray_Bubble"));
accelerators::ToggleSystemTrayBubble();
break;
case AcceleratorAction::kToggleWifi:
accelerators::ToggleWifi();
break;
case AcceleratorAction::kTouchHudClear:
accelerators::TouchHudClear();
break;
case AcceleratorAction::kTouchHudModeChange:
accelerators::TouchHudModeChange();
break;
case AcceleratorAction::kUnpin:
accelerators::UnpinWindow();
break;
case AcceleratorAction::kVolumeDown:
base::RecordAction(UserMetricsAction("Accel_VolumeDown_F9"));
output_volume_metric_delay_timer_.Reset();
accelerators::VolumeDown();
break;
case AcceleratorAction::kVolumeMute:
if (accelerator.key_code() == ui::VKEY_VOLUME_MUTE)
base::RecordAction(UserMetricsAction("Accel_VolumeMute_F8"));
accelerators::VolumeMute();
break;
case AcceleratorAction::kVolumeMuteToggle:
accelerators::VolumeMuteToggle();
break;
case AcceleratorAction::kVolumeUp:
base::RecordAction(UserMetricsAction("Accel_VolumeUp_F10"));
output_volume_metric_delay_timer_.Reset();
accelerators::VolumeUp();
break;
case AcceleratorAction::kWindowCycleSnapLeft:
base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
accelerators::WindowSnap(AcceleratorAction::kWindowCycleSnapLeft);
break;
case AcceleratorAction::kWindowCycleSnapRight:
base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
accelerators::WindowSnap(AcceleratorAction::kWindowCycleSnapRight);
break;
case AcceleratorAction::kWindowMinimize:
base::RecordAction(
base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
accelerators::WindowMinimize();
break;
case AcceleratorAction::kMinimizeTopWindowOnBack:
base::RecordAction(
base::UserMetricsAction("Accel_Minimize_Top_Window_On_Back"));
accelerators::TopWindowMinimizeOnBack();
break;
case kTouchFingerprintSensor1:
accelerators::TouchFingerprintSensor(1);
break;
case kTouchFingerprintSensor2:
accelerators::TouchFingerprintSensor(2);
break;
case kTouchFingerprintSensor3:
accelerators::TouchFingerprintSensor(3);
break;
case AcceleratorAction::kResizePipWindow:
accelerators::ResizePipWindow();
break;
case AcceleratorAction::kToggleGeminiApp:
accelerators::ToggleGeminiApp();
break;
}
RecordActionUmaHistogram(action, accelerator);
RecordOverviewBasedScreenshotUmaHistogram(action, accelerator);
NotifyActionPerformed(action);
if (::features::IsImprovedKeyboardShortcutsEnabled()) {
auto* input_method =
Shell::Get()->window_tree_host_manager()->input_method();
input_method->CancelComposition(input_method->GetTextInputClient());
}
}
bool AcceleratorControllerImpl::ShouldActionConsumeKeyEvent(
AcceleratorAction action) {
return true;
}
AcceleratorControllerImpl::AcceleratorProcessingRestriction
AcceleratorControllerImpl::GetAcceleratorProcessingRestriction(
int action) const {
if (ShouldPreventProcessingAccelerators()) {
return RESTRICTION_PREVENT_PROCESSING;
}
if (Shell::Get()->screen_pinning_controller()->IsPinned() &&
!base::Contains(actions_allowed_in_pinned_mode_, action)) {
return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
}
if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted() &&
!base::Contains(actions_allowed_at_login_screen_, action)) {
return RESTRICTION_PREVENT_PROCESSING;
}
if (Shell::Get()->session_controller()->IsScreenLocked() &&
!base::Contains(actions_allowed_at_lock_screen_, action)) {
return RESTRICTION_PREVENT_PROCESSING;
}
if (Shell::Get()->power_button_controller()->IsMenuOpened() &&
!base::Contains(actions_allowed_at_power_menu_, action)) {
return RESTRICTION_PREVENT_PROCESSING;
}
if (Shell::Get()->session_controller()->IsRunningInAppMode() &&
!base::Contains(actions_allowed_in_app_mode_, action)) {
return RESTRICTION_PREVENT_PROCESSING;
}
if (Shell::IsSystemModalWindowOpen() &&
!base::Contains(actions_allowed_at_modal_window_, action)) {
return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
}
if (base::Contains(actions_needing_window_, action) &&
Shell::Get()
->mru_window_tracker()
->BuildMruWindowList(kActiveDesk)
.empty()) {
Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert(
AccessibilityAlert::WINDOW_NEEDED);
return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
}
return RESTRICTION_NONE;
}
AcceleratorControllerImpl::AcceleratorProcessingStatus
AcceleratorControllerImpl::MaybeDeprecatedAcceleratorPressed(
AcceleratorAction action,
const ui::Accelerator& accelerator) const {
const DeprecatedAcceleratorData* deprecated_data =
accelerator_configuration_->GetDeprecatedAcceleratorData(action);
if (!deprecated_data) {
return AcceleratorProcessingStatus::PROCEED;
}
if (!accelerator_configuration_->IsDeprecated(accelerator)) {
RecordUmaHistogram(deprecated_data->uma_histogram_name, NEW_USED);
return AcceleratorProcessingStatus::PROCEED;
}
RecordUmaHistogram(deprecated_data->uma_histogram_name, DEPRECATED_USED);
MaybeShowDeprecatedAcceleratorNotification(
deprecated_data->uma_histogram_name,
deprecated_data->notification_message_id,
deprecated_data->new_shortcut_id, deprecated_data->replacement, action,
deprecated_data->pref_name);
if (!deprecated_data->deprecated_enabled)
return AcceleratorProcessingStatus::STOP;
return AcceleratorProcessingStatus::PROCEED;
}
void AcceleratorControllerImpl::SetPreventProcessingAccelerators(
bool prevent_processing_accelerators) {
prevent_processing_accelerators_ = prevent_processing_accelerators;
}
bool AcceleratorControllerImpl::ShouldPreventProcessingAccelerators() const {
return prevent_processing_accelerators_;
}
void AcceleratorControllerImpl::RecordVolumeSource() {
accelerators::RecordVolumeSource();
}
}