Add ICU message format support
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blob51417661cfb5cee0c6204a0b246ff28421c8ba96
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/accelerators/accelerator_controller.h"
7 #include <algorithm>
8 #include <cmath>
9 #include <string>
11 #include "ash/accelerators/accelerator_commands.h"
12 #include "ash/accelerators/debug_commands.h"
13 #include "ash/ash_switches.h"
14 #include "ash/debug.h"
15 #include "ash/display/window_tree_host_manager.h"
16 #include "ash/focus_cycler.h"
17 #include "ash/gpu_support.h"
18 #include "ash/ime_control_delegate.h"
19 #include "ash/magnifier/magnification_controller.h"
20 #include "ash/magnifier/partial_magnification_controller.h"
21 #include "ash/media_delegate.h"
22 #include "ash/multi_profile_uma.h"
23 #include "ash/new_window_delegate.h"
24 #include "ash/root_window_controller.h"
25 #include "ash/rotator/screen_rotation_animator.h"
26 #include "ash/rotator/window_rotation.h"
27 #include "ash/screenshot_delegate.h"
28 #include "ash/session/session_state_delegate.h"
29 #include "ash/shelf/shelf.h"
30 #include "ash/shelf/shelf_delegate.h"
31 #include "ash/shelf/shelf_model.h"
32 #include "ash/shelf/shelf_widget.h"
33 #include "ash/shell.h"
34 #include "ash/shell_delegate.h"
35 #include "ash/shell_window_ids.h"
36 #include "ash/system/brightness_control_delegate.h"
37 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
38 #include "ash/system/status_area_widget.h"
39 #include "ash/system/tray/system_tray.h"
40 #include "ash/system/tray/system_tray_delegate.h"
41 #include "ash/system/tray/system_tray_notifier.h"
42 #include "ash/system/web_notification/web_notification_tray.h"
43 #include "ash/touch/touch_hud_debug.h"
44 #include "ash/utility/partial_screenshot_controller.h"
45 #include "ash/volume_control_delegate.h"
46 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
47 #include "ash/wm/mru_window_tracker.h"
48 #include "ash/wm/overview/window_selector_controller.h"
49 #include "ash/wm/power_button_controller.h"
50 #include "ash/wm/window_cycle_controller.h"
51 #include "ash/wm/window_state.h"
52 #include "ash/wm/window_util.h"
53 #include "ash/wm/wm_event.h"
54 #include "base/bind.h"
55 #include "base/command_line.h"
56 #include "base/metrics/user_metrics.h"
57 #include "ui/aura/env.h"
58 #include "ui/base/accelerators/accelerator.h"
59 #include "ui/base/accelerators/accelerator_manager.h"
60 #include "ui/compositor/layer.h"
61 #include "ui/compositor/layer_animation_sequence.h"
62 #include "ui/compositor/layer_animator.h"
63 #include "ui/events/event.h"
64 #include "ui/events/keycodes/keyboard_codes.h"
65 #include "ui/gfx/screen.h"
66 #include "ui/views/controls/webview/webview.h"
68 #if defined(OS_CHROMEOS)
69 #include "ash/system/chromeos/keyboard_brightness_controller.h"
70 #include "base/sys_info.h"
71 #include "ui/base/ime/chromeos/ime_keyboard.h"
72 #include "ui/base/ime/chromeos/input_method_manager.h"
73 #endif // defined(OS_CHROMEOS)
75 namespace ash {
76 namespace {
78 using base::UserMetricsAction;
80 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
81 if (accelerator.key_code() == ui::VKEY_TAB)
82 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
84 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
85 WindowCycleController::BACKWARD);
88 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
89 if (accelerator.key_code() == ui::VKEY_TAB)
90 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
92 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
93 WindowCycleController::FORWARD);
96 void HandleRotatePaneFocus(Shell::Direction direction) {
97 Shell* shell = Shell::GetInstance();
98 switch (direction) {
99 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
100 case Shell::FORWARD: {
101 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
102 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
103 break;
105 case Shell::BACKWARD: {
106 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
107 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
108 break;
113 void HandleFocusShelf() {
114 Shell* shell = Shell::GetInstance();
115 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
116 shell->focus_cycler()->FocusWidget(
117 Shelf::ForPrimaryDisplay()->shelf_widget());
120 void HandleLaunchAppN(int n) {
121 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
122 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
125 void HandleLaunchLastApp() {
126 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
127 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
130 bool CanHandleMagnifyScreen() {
131 Shell* shell = Shell::GetInstance();
132 return shell->magnification_controller()->IsEnabled() ||
133 shell->partial_magnification_controller()->is_enabled();
136 // Magnify the screen
137 void HandleMagnifyScreen(int delta_index) {
138 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
139 // TODO(yoshiki): Move the following logic to MagnificationController.
140 float scale =
141 ash::Shell::GetInstance()->magnification_controller()->GetScale();
142 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
143 int scale_index = std::floor(
144 std::log(scale) / std::log(ui::kMagnificationScaleFactor) + 0.5);
146 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
148 ash::Shell::GetInstance()->magnification_controller()->SetScale(
149 std::pow(ui::kMagnificationScaleFactor, new_scale_index), true);
150 } else if (ash::Shell::GetInstance()->
151 partial_magnification_controller()->is_enabled()) {
152 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
153 ash::Shell::GetInstance()->partial_magnification_controller()->
154 SetScale(scale);
158 void HandleMediaNextTrack() {
159 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
162 void HandleMediaPlayPause() {
163 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
166 void HandleMediaPrevTrack() {
167 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
170 bool CanHandleNewIncognitoWindow() {
171 return Shell::GetInstance()->delegate()->IsIncognitoAllowed();
174 void HandleNewIncognitoWindow() {
175 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
176 Shell::GetInstance()->new_window_delegate()->NewWindow(
177 true /* is_incognito */);
180 void HandleNewTab(const ui::Accelerator& accelerator) {
181 if (accelerator.key_code() == ui::VKEY_T)
182 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
183 Shell::GetInstance()->new_window_delegate()->NewTab();
186 void HandleNewWindow() {
187 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
188 Shell::GetInstance()->new_window_delegate()->NewWindow(
189 false /* is_incognito */);
192 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
193 const ui::Accelerator& previous_accelerator) {
194 // This check is necessary e.g. not to process the Shift+Alt+
195 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
196 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
197 // is released.
198 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
199 if (previous_accelerator.type() == ui::ET_KEY_RELEASED &&
200 // Workaround for crbug.com/139556. CJK IME users tend to press
201 // Enter (or Space) and Shift+Alt almost at the same time to commit
202 // an IME string and then switch from the IME to the English layout.
203 // This workaround allows the user to trigger NEXT_IME even if the
204 // user presses Shift+Alt before releasing Enter.
205 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
206 previous_key_code != ui::VKEY_RETURN &&
207 previous_key_code != ui::VKEY_SPACE) {
208 // We totally ignore this accelerator.
209 // TODO(mazda): Fix crbug.com/158217
210 return false;
212 return ime_control_delegate && ime_control_delegate->CanCycleIme();
215 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
216 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
217 ime_control_delegate->HandleNextIme();
220 void HandleOpenFeedbackPage() {
221 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
222 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
225 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
226 return ime_control_delegate && ime_control_delegate->CanCycleIme();
229 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
230 const ui::Accelerator& accelerator) {
231 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
232 if (accelerator.type() == ui::ET_KEY_PRESSED)
233 ime_control_delegate->HandlePreviousIme();
234 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
237 void HandleRestoreTab() {
238 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
239 Shell::GetInstance()->new_window_delegate()->RestoreTab();
242 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
243 switch (current) {
244 case gfx::Display::ROTATE_0:
245 return gfx::Display::ROTATE_90;
246 case gfx::Display::ROTATE_90:
247 return gfx::Display::ROTATE_180;
248 case gfx::Display::ROTATE_180:
249 return gfx::Display::ROTATE_270;
250 case gfx::Display::ROTATE_270:
251 return gfx::Display::ROTATE_0;
253 NOTREACHED() << "Unknown rotation:" << current;
254 return gfx::Display::ROTATE_0;
257 // Rotates the screen.
258 void HandleRotateScreen() {
259 if (Shell::GetInstance()->display_manager()->IsInUnifiedMode())
260 return;
262 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
263 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
264 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
265 const DisplayInfo& display_info =
266 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
267 ash::ScreenRotationAnimator(display.id())
268 .Rotate(GetNextRotation(display_info.GetActiveRotation()),
269 gfx::Display::ROTATION_SOURCE_USER);
272 // Rotate the active window.
273 void HandleRotateActiveWindow() {
274 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
275 aura::Window* active_window = wm::GetActiveWindow();
276 if (active_window) {
277 // The rotation animation bases its target transform on the current
278 // rotation and position. Since there could be an animation in progress
279 // right now, queue this animation so when it starts it picks up a neutral
280 // rotation and position. Use replace so we only enqueue one at a time.
281 active_window->layer()->GetAnimator()->
282 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
283 active_window->layer()->GetAnimator()->StartAnimation(
284 new ui::LayerAnimationSequence(
285 new ash::WindowRotation(360, active_window->layer())));
289 void HandleShowKeyboardOverlay() {
290 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
291 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
294 bool CanHandleShowMessageCenterBubble() {
295 RootWindowController* controller =
296 RootWindowController::ForTargetRootWindow();
297 StatusAreaWidget* status_area_widget =
298 controller->shelf()->status_area_widget();
299 return status_area_widget &&
300 status_area_widget->web_notification_tray()->visible();
303 void HandleShowMessageCenterBubble() {
304 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
305 RootWindowController* controller =
306 RootWindowController::ForTargetRootWindow();
307 StatusAreaWidget* status_area_widget =
308 controller->shelf()->status_area_widget();
309 if (status_area_widget) {
310 WebNotificationTray* notification_tray =
311 status_area_widget->web_notification_tray();
312 if (notification_tray->visible())
313 notification_tray->ShowMessageCenterBubble();
317 void HandleShowSystemTrayBubble() {
318 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
319 RootWindowController* controller =
320 RootWindowController::ForTargetRootWindow();
321 if (!controller->GetSystemTray()->HasSystemBubble())
322 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
325 void HandleShowTaskManager() {
326 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
327 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
330 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
331 const ui::Accelerator& accelerator) {
332 return ime_control_delegate &&
333 ime_control_delegate->CanSwitchIme(accelerator);
336 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
337 const ui::Accelerator& accelerator) {
338 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
339 ime_control_delegate->HandleSwitchIme(accelerator);
342 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
343 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
344 DCHECK(screenshot_delegate);
345 Shell::GetInstance()
346 ->partial_screenshot_controller()
347 ->StartPartialScreenshotSession(screenshot_delegate);
350 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
351 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
352 DCHECK(screenshot_delegate);
353 if (screenshot_delegate->CanTakeScreenshot())
354 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
357 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
358 const ui::Accelerator& previous_accelerator) {
359 if (accelerator.key_code() == ui::VKEY_LWIN) {
360 // If something else was pressed between the Search key (LWIN)
361 // being pressed and released, then ignore the release of the
362 // Search key.
363 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
364 previous_accelerator.key_code() != ui::VKEY_LWIN) {
365 return false;
368 // When spoken feedback is enabled, we should neither toggle the list nor
369 // consume the key since Search+Shift is one of the shortcuts the a11y
370 // feature uses. crbug.com/132296
371 if (Shell::GetInstance()
372 ->accessibility_delegate()
373 ->IsSpokenFeedbackEnabled()) {
374 return false;
377 return true;
380 void HandleToggleAppList(const ui::Accelerator& accelerator) {
381 if (accelerator.key_code() == ui::VKEY_LWIN)
382 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
383 ash::Shell::GetInstance()->ToggleAppList(NULL);
386 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
387 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
388 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
389 accelerators::ToggleFullscreen();
392 void HandleToggleOverview() {
393 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
394 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
397 bool CanHandleWindowSnapOrDock() {
398 wm::WindowState* window_state = wm::GetActiveWindowState();
399 // Disable window snapping shortcut key for full screen window due to
400 // http://crbug.com/135487.
401 return (window_state && window_state->IsUserPositionable() &&
402 !window_state->IsFullscreen());
405 void HandleWindowSnapOrDock(AcceleratorAction action) {
406 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
407 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
408 else
409 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
411 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT ?
412 wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT :
413 wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
414 wm::GetActiveWindowState()->OnWMEvent(&event);
417 void HandleWindowMinimize() {
418 base::RecordAction(
419 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
420 accelerators::ToggleMinimized();
423 bool CanHandlePositionCenter() {
424 // Docked windows do not support centering.
425 wm::WindowState* window_state = wm::GetActiveWindowState();
426 return (window_state && !window_state->IsDocked());
429 void HandlePositionCenter() {
430 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
431 wm::CenterWindow(wm::GetActiveWindow());
434 #if defined(OS_CHROMEOS)
435 void HandleBrightnessDown(BrightnessControlDelegate* delegate,
436 const ui::Accelerator& accelerator) {
437 if (delegate)
438 delegate->HandleBrightnessDown(accelerator);
441 void HandleBrightnessUp(BrightnessControlDelegate* delegate,
442 const ui::Accelerator& accelerator) {
443 if (delegate)
444 delegate->HandleBrightnessUp(accelerator);
447 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
448 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
449 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
450 (previous_key_code != ui::VKEY_LSHIFT &&
451 previous_key_code != ui::VKEY_SHIFT &&
452 previous_key_code != ui::VKEY_RSHIFT)) {
453 // If something else was pressed between the Shift key being pressed
454 // and released, then ignore the release of the Shift key.
455 return false;
457 chromeos::input_method::InputMethodManager* ime =
458 chromeos::input_method::InputMethodManager::Get();
459 chromeos::input_method::ImeKeyboard* keyboard =
460 ime ? ime->GetImeKeyboard() : NULL;
461 return (keyboard && keyboard->CapsLockIsEnabled());
464 void HandleDisableCapsLock() {
465 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
466 chromeos::input_method::InputMethodManager* ime =
467 chromeos::input_method::InputMethodManager::Get();
468 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
471 void HandleKeyboardBrightnessDown(KeyboardBrightnessControlDelegate* delegate,
472 const ui::Accelerator& accelerator) {
473 if (delegate)
474 delegate->HandleKeyboardBrightnessDown(accelerator);
477 void HandleKeyboardBrightnessUp(KeyboardBrightnessControlDelegate* delegate,
478 const ui::Accelerator& accelerator) {
479 if (delegate)
480 delegate->HandleKeyboardBrightnessUp(accelerator);
483 void HandleLock() {
484 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
485 Shell::GetInstance()->session_state_delegate()->LockScreen();
488 void HandleCrosh() {
489 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
491 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
494 void HandleFileManager() {
495 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
497 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
500 void HandleGetHelp() {
501 Shell::GetInstance()->new_window_delegate()->OpenGetHelp();
504 bool CanHandleSilenceSpokenFeedback() {
505 AccessibilityDelegate* delegate =
506 Shell::GetInstance()->accessibility_delegate();
507 return delegate->IsSpokenFeedbackEnabled();
510 void HandleSilenceSpokenFeedback() {
511 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
512 Shell::GetInstance()->accessibility_delegate()->SilenceSpokenFeedback();
515 void HandleSwapPrimaryDisplay() {
516 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
517 Shell::GetInstance()->window_tree_host_manager()->SwapPrimaryDisplay();
520 bool CanHandleCycleUser() {
521 Shell* shell = Shell::GetInstance();
522 return shell->delegate()->IsMultiProfilesEnabled() &&
523 shell->session_state_delegate()->NumberOfLoggedInUsers() > 1;
526 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
527 MultiProfileUMA::RecordSwitchActiveUser(
528 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
529 switch (cycle_user) {
530 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
531 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
532 break;
533 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
534 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
535 break;
537 Shell::GetInstance()->session_state_delegate()->CycleActiveUser(cycle_user);
540 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
541 const ui::Accelerator& previous_accelerator) {
542 if (accelerator.key_code() == ui::VKEY_LWIN) {
543 // If something else was pressed between the Search key (LWIN)
544 // being pressed and released, then ignore the release of the
545 // Search key.
546 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
547 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
548 previous_accelerator.key_code() != ui::VKEY_LWIN)
549 return false;
551 chromeos::input_method::InputMethodManager* ime =
552 chromeos::input_method::InputMethodManager::Get();
553 return ime && ime->GetImeKeyboard();
556 void HandleToggleCapsLock() {
557 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
558 chromeos::input_method::InputMethodManager* ime =
559 chromeos::input_method::InputMethodManager::Get();
560 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
561 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
564 void HandleToggleMirrorMode() {
565 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
566 Shell::GetInstance()->window_tree_host_manager()->ToggleMirrorMode();
569 void HandleToggleSpokenFeedback() {
570 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
572 Shell::GetInstance()->accessibility_delegate()->
573 ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_SHOW);
576 bool CanHandleToggleTouchViewTesting() {
577 return base::CommandLine::ForCurrentProcess()->HasSwitch(
578 switches::kAshEnableTouchViewTesting);
581 void HandleToggleTouchViewTesting() {
582 // TODO(skuhne): This is only temporary! Remove this!
583 MaximizeModeController* controller = Shell::GetInstance()->
584 maximize_mode_controller();
585 controller->EnableMaximizeModeWindowManager(
586 !controller->IsMaximizeModeWindowManagerEnabled());
589 bool CanHandleTouchHud() {
590 return RootWindowController::ForTargetRootWindow()->touch_hud_debug();
593 void HandleTouchHudClear() {
594 RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear();
597 void HandleTouchHudModeChange() {
598 RootWindowController* controller =
599 RootWindowController::ForTargetRootWindow();
600 controller->touch_hud_debug()->ChangeToNextMode();
603 void HandleVolumeDown(const ui::Accelerator& accelerator) {
604 VolumeControlDelegate* volume_delegate =
605 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
606 if (volume_delegate)
607 volume_delegate->HandleVolumeDown(accelerator);
610 void HandleVolumeMute(const ui::Accelerator& accelerator) {
611 VolumeControlDelegate* volume_delegate =
612 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
613 if (volume_delegate)
614 volume_delegate->HandleVolumeMute(accelerator);
617 void HandleVolumeUp(const ui::Accelerator& accelerator) {
618 VolumeControlDelegate* volume_delegate =
619 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
620 if (volume_delegate)
621 volume_delegate->HandleVolumeUp(accelerator);
624 #endif // defined(OS_CHROMEOS)
626 } // namespace
628 ////////////////////////////////////////////////////////////////////////////////
629 // AcceleratorController, public:
631 AcceleratorController::AcceleratorController()
632 : accelerator_manager_(new ui::AcceleratorManager),
633 accelerator_history_(new ui::AcceleratorHistory) {
634 Init();
637 AcceleratorController::~AcceleratorController() {
640 void AcceleratorController::Register(const ui::Accelerator& accelerator,
641 ui::AcceleratorTarget* target) {
642 accelerator_manager_->Register(accelerator,
643 ui::AcceleratorManager::kNormalPriority,
644 target);
647 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
648 ui::AcceleratorTarget* target) {
649 accelerator_manager_->Unregister(accelerator, target);
652 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
653 accelerator_manager_->UnregisterAll(target);
656 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
657 if (ime_control_delegate_) {
658 return accelerator_manager_->Process(
659 ime_control_delegate_->RemapAccelerator(accelerator));
661 return accelerator_manager_->Process(accelerator);
664 bool AcceleratorController::IsRegistered(
665 const ui::Accelerator& accelerator) const {
666 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
669 bool AcceleratorController::IsPreferred(
670 const ui::Accelerator& accelerator) const {
671 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
672 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
674 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
675 accelerators_.find(remapped_accelerator);
676 if (iter == accelerators_.end())
677 return false; // not an accelerator.
679 return preferred_actions_.find(iter->second) != preferred_actions_.end();
682 bool AcceleratorController::IsReserved(
683 const ui::Accelerator& accelerator) const {
684 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
685 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
687 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
688 accelerators_.find(remapped_accelerator);
689 if (iter == accelerators_.end())
690 return false; // not an accelerator.
692 return reserved_actions_.find(iter->second) != reserved_actions_.end();
695 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
696 if (CanPerformAction(action, ui::Accelerator())) {
697 PerformAction(action, ui::Accelerator());
698 return true;
700 return false;
703 AcceleratorController::AcceleratorProcessingRestriction
704 AcceleratorController::GetCurrentAcceleratorRestriction() {
705 return GetAcceleratorProcessingRestriction(-1);
708 void AcceleratorController::SetBrightnessControlDelegate(
709 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
710 brightness_control_delegate_ = brightness_control_delegate.Pass();
713 void AcceleratorController::SetImeControlDelegate(
714 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
715 ime_control_delegate_ = ime_control_delegate.Pass();
718 void AcceleratorController::SetScreenshotDelegate(
719 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
720 screenshot_delegate_ = screenshot_delegate.Pass();
723 ////////////////////////////////////////////////////////////////////////////////
724 // AcceleratorController, ui::AcceleratorTarget implementation:
726 bool AcceleratorController::AcceleratorPressed(
727 const ui::Accelerator& accelerator) {
728 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
729 accelerators_.find(accelerator);
730 DCHECK(it != accelerators_.end());
731 AcceleratorAction action = it->second;
732 if (CanPerformAction(action, accelerator)) {
733 PerformAction(action, accelerator);
734 return ShouldActionConsumeKeyEvent(action);
736 return false;
739 bool AcceleratorController::CanHandleAccelerators() const {
740 return true;
743 ///////////////////////////////////////////////////////////////////////////////
744 // AcceleratorController, private:
746 void AcceleratorController::Init() {
747 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
748 actions_allowed_at_login_screen_.insert(
749 kActionsAllowedAtLoginOrLockScreen[i]);
750 actions_allowed_at_lock_screen_.insert(
751 kActionsAllowedAtLoginOrLockScreen[i]);
753 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
754 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
755 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
756 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
757 for (size_t i = 0; i < kPreferredActionsLength; ++i)
758 preferred_actions_.insert(kPreferredActions[i]);
759 for (size_t i = 0; i < kReservedActionsLength; ++i)
760 reserved_actions_.insert(kReservedActions[i]);
761 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
762 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
763 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
764 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
765 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
766 actions_needing_window_.insert(kActionsNeedingWindow[i]);
768 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
770 if (debug::DebugAcceleratorsEnabled()) {
771 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
772 // All debug accelerators are reserved.
773 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
774 reserved_actions_.insert(kDebugAcceleratorData[i].action);
777 #if defined(OS_CHROMEOS)
778 keyboard_brightness_control_delegate_.reset(
779 new KeyboardBrightnessController());
780 #endif
783 void AcceleratorController::RegisterAccelerators(
784 const AcceleratorData accelerators[],
785 size_t accelerators_length) {
786 for (size_t i = 0; i < accelerators_length; ++i) {
787 ui::Accelerator accelerator(accelerators[i].keycode,
788 accelerators[i].modifiers);
789 accelerator.set_type(accelerators[i].trigger_on_press ?
790 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
791 Register(accelerator, this);
792 accelerators_.insert(
793 std::make_pair(accelerator, accelerators[i].action));
797 bool AcceleratorController::CanPerformAction(
798 AcceleratorAction action,
799 const ui::Accelerator& accelerator) {
800 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
801 accelerator.IsRepeat()) {
802 return false;
805 AcceleratorProcessingRestriction restriction =
806 GetAcceleratorProcessingRestriction(action);
807 if (restriction != RESTRICTION_NONE)
808 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
810 const ui::Accelerator& previous_accelerator =
811 accelerator_history_->previous_accelerator();
813 // True should be returned if running |action| does something. Otherwise,
814 // false should be returned to give the web contents a chance at handling the
815 // accelerator.
816 switch (action) {
817 case DEBUG_PRINT_LAYER_HIERARCHY:
818 case DEBUG_PRINT_VIEW_HIERARCHY:
819 case DEBUG_PRINT_WINDOW_HIERARCHY:
820 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
821 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
822 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
823 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
824 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
825 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
826 return debug::DebugAcceleratorsEnabled();
827 case MAGNIFY_SCREEN_ZOOM_IN:
828 case MAGNIFY_SCREEN_ZOOM_OUT:
829 return CanHandleMagnifyScreen();
830 case NEW_INCOGNITO_WINDOW:
831 return CanHandleNewIncognitoWindow();
832 case NEXT_IME:
833 return CanHandleNextIme(ime_control_delegate_.get(),
834 previous_accelerator);
835 case PREVIOUS_IME:
836 return CanHandlePreviousIme(ime_control_delegate_.get());
837 case SCALE_UI_RESET:
838 case SCALE_UI_UP:
839 case SCALE_UI_DOWN:
840 return accelerators::IsInternalDisplayZoomEnabled();
841 case SHOW_MESSAGE_CENTER_BUBBLE:
842 return CanHandleShowMessageCenterBubble();
843 case SWITCH_IME:
844 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
845 case TOGGLE_APP_LIST:
846 return CanHandleToggleAppList(accelerator, previous_accelerator);
847 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
848 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
849 return CanHandleWindowSnapOrDock();
850 case WINDOW_POSITION_CENTER:
851 return CanHandlePositionCenter();
852 #if defined(OS_CHROMEOS)
853 case DEBUG_ADD_REMOVE_DISPLAY:
854 case DEBUG_TOGGLE_UNIFIED_DESKTOP:
855 return debug::DebugAcceleratorsEnabled();
856 case DISABLE_CAPS_LOCK:
857 return CanHandleDisableCapsLock(previous_accelerator);
858 case SILENCE_SPOKEN_FEEDBACK:
859 return CanHandleSilenceSpokenFeedback();
860 case SWITCH_TO_PREVIOUS_USER:
861 case SWITCH_TO_NEXT_USER:
862 return CanHandleCycleUser();
863 case TOGGLE_CAPS_LOCK:
864 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
865 case TOGGLE_TOUCH_VIEW_TESTING:
866 return CanHandleToggleTouchViewTesting();
867 case TOUCH_HUD_CLEAR:
868 case TOUCH_HUD_MODE_CHANGE:
869 return CanHandleTouchHud();
870 #endif
872 case CYCLE_BACKWARD_MRU:
873 case CYCLE_FORWARD_MRU:
874 case EXIT:
875 case FOCUS_NEXT_PANE:
876 case FOCUS_PREVIOUS_PANE:
877 case FOCUS_SHELF:
878 case LAUNCH_APP_0:
879 case LAUNCH_APP_1:
880 case LAUNCH_APP_2:
881 case LAUNCH_APP_3:
882 case LAUNCH_APP_4:
883 case LAUNCH_APP_5:
884 case LAUNCH_APP_6:
885 case LAUNCH_APP_7:
886 case LAUNCH_LAST_APP:
887 case MEDIA_NEXT_TRACK:
888 case MEDIA_PLAY_PAUSE:
889 case MEDIA_PREV_TRACK:
890 case NEW_TAB:
891 case NEW_WINDOW:
892 case OPEN_FEEDBACK_PAGE:
893 case PRINT_UI_HIERARCHIES:
894 case RESTORE_TAB:
895 case ROTATE_SCREEN:
896 case ROTATE_WINDOW:
897 case SHOW_KEYBOARD_OVERLAY:
898 case SHOW_SYSTEM_TRAY_BUBBLE:
899 case SHOW_TASK_MANAGER:
900 case TAKE_PARTIAL_SCREENSHOT:
901 case TAKE_SCREENSHOT:
902 case TOGGLE_FULLSCREEN:
903 case TOGGLE_MAXIMIZED:
904 case TOGGLE_OVERVIEW:
905 case WINDOW_MINIMIZE:
906 #if defined(OS_CHROMEOS)
907 case BRIGHTNESS_DOWN:
908 case BRIGHTNESS_UP:
909 case DISABLE_GPU_WATCHDOG:
910 case KEYBOARD_BRIGHTNESS_DOWN:
911 case KEYBOARD_BRIGHTNESS_UP:
912 case LOCK_PRESSED:
913 case LOCK_RELEASED:
914 case LOCK_SCREEN:
915 case OPEN_CROSH:
916 case OPEN_FILE_MANAGER:
917 case OPEN_GET_HELP:
918 case POWER_PRESSED:
919 case POWER_RELEASED:
920 case SWAP_PRIMARY_DISPLAY:
921 case TOGGLE_MIRROR_MODE:
922 case TOGGLE_SPOKEN_FEEDBACK:
923 case TOGGLE_WIFI:
924 case TOUCH_HUD_PROJECTION_TOGGLE:
925 case VOLUME_DOWN:
926 case VOLUME_MUTE:
927 case VOLUME_UP:
928 #else
929 case DUMMY_FOR_RESERVED:
930 #endif
931 return true;
933 return false;
936 void AcceleratorController::PerformAction(AcceleratorAction action,
937 const ui::Accelerator& accelerator) {
938 AcceleratorProcessingRestriction restriction =
939 GetAcceleratorProcessingRestriction(action);
940 if (restriction != RESTRICTION_NONE)
941 return;
943 // If your accelerator invokes more than one line of code, please either
944 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
945 // below) or pull it into a HandleFoo() function above.
946 switch (action) {
947 case CYCLE_BACKWARD_MRU:
948 HandleCycleBackwardMRU(accelerator);
949 break;
950 case CYCLE_FORWARD_MRU:
951 HandleCycleForwardMRU(accelerator);
952 break;
953 case DEBUG_PRINT_LAYER_HIERARCHY:
954 case DEBUG_PRINT_VIEW_HIERARCHY:
955 case DEBUG_PRINT_WINDOW_HIERARCHY:
956 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
957 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
958 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
959 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
960 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
961 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
962 debug::PerformDebugActionIfEnabled(action);
963 break;
964 case EXIT:
965 // UMA metrics are recorded in the handler.
966 exit_warning_handler_.HandleAccelerator();
967 break;
968 case FOCUS_NEXT_PANE:
969 HandleRotatePaneFocus(Shell::FORWARD);
970 break;
971 case FOCUS_PREVIOUS_PANE:
972 HandleRotatePaneFocus(Shell::BACKWARD);
973 break;
974 case FOCUS_SHELF:
975 HandleFocusShelf();
976 break;
977 case LAUNCH_APP_0:
978 HandleLaunchAppN(0);
979 break;
980 case LAUNCH_APP_1:
981 HandleLaunchAppN(1);
982 break;
983 case LAUNCH_APP_2:
984 HandleLaunchAppN(2);
985 break;
986 case LAUNCH_APP_3:
987 HandleLaunchAppN(3);
988 break;
989 case LAUNCH_APP_4:
990 HandleLaunchAppN(4);
991 break;
992 case LAUNCH_APP_5:
993 HandleLaunchAppN(5);
994 break;
995 case LAUNCH_APP_6:
996 HandleLaunchAppN(6);
997 break;
998 case LAUNCH_APP_7:
999 HandleLaunchAppN(7);
1000 break;
1001 case LAUNCH_LAST_APP:
1002 HandleLaunchLastApp();
1003 break;
1004 case MAGNIFY_SCREEN_ZOOM_IN:
1005 HandleMagnifyScreen(1);
1006 break;
1007 case MAGNIFY_SCREEN_ZOOM_OUT:
1008 HandleMagnifyScreen(-1);
1009 break;
1010 case MEDIA_NEXT_TRACK:
1011 HandleMediaNextTrack();
1012 break;
1013 case MEDIA_PLAY_PAUSE:
1014 HandleMediaPlayPause();
1015 break;
1016 case MEDIA_PREV_TRACK:
1017 HandleMediaPrevTrack();
1018 break;
1019 case NEW_INCOGNITO_WINDOW:
1020 HandleNewIncognitoWindow();
1021 break;
1022 case NEW_TAB:
1023 HandleNewTab(accelerator);
1024 break;
1025 case NEW_WINDOW:
1026 HandleNewWindow();
1027 break;
1028 case NEXT_IME:
1029 HandleNextIme(ime_control_delegate_.get());
1030 break;
1031 case OPEN_FEEDBACK_PAGE:
1032 HandleOpenFeedbackPage();
1033 break;
1034 case PREVIOUS_IME:
1035 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1036 break;
1037 case PRINT_UI_HIERARCHIES:
1038 debug::PrintUIHierarchies();
1039 break;
1040 case RESTORE_TAB:
1041 HandleRestoreTab();
1042 break;
1043 case ROTATE_SCREEN:
1044 HandleRotateScreen();
1045 break;
1046 case ROTATE_WINDOW:
1047 HandleRotateActiveWindow();
1048 break;
1049 case SCALE_UI_DOWN:
1050 accelerators::ZoomInternalDisplay(false /* down */);
1051 break;
1052 case SCALE_UI_RESET:
1053 accelerators::ResetInternalDisplayZoom();
1054 break;
1055 case SCALE_UI_UP:
1056 accelerators::ZoomInternalDisplay(true /* up */);
1057 break;
1058 case SHOW_KEYBOARD_OVERLAY:
1059 HandleShowKeyboardOverlay();
1060 break;
1061 case SHOW_MESSAGE_CENTER_BUBBLE:
1062 HandleShowMessageCenterBubble();
1063 break;
1064 case SHOW_SYSTEM_TRAY_BUBBLE:
1065 HandleShowSystemTrayBubble();
1066 break;
1067 case SHOW_TASK_MANAGER:
1068 HandleShowTaskManager();
1069 break;
1070 case SWITCH_IME:
1071 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1072 break;
1073 case TAKE_PARTIAL_SCREENSHOT:
1074 HandleTakePartialScreenshot(screenshot_delegate_.get());
1075 break;
1076 case TAKE_SCREENSHOT:
1077 HandleTakeScreenshot(screenshot_delegate_.get());
1078 break;
1079 case TOGGLE_APP_LIST:
1080 HandleToggleAppList(accelerator);
1081 break;
1082 case TOGGLE_FULLSCREEN:
1083 HandleToggleFullscreen(accelerator);
1084 break;
1085 case TOGGLE_MAXIMIZED:
1086 accelerators::ToggleMaximized();
1087 break;
1088 case TOGGLE_OVERVIEW:
1089 HandleToggleOverview();
1090 break;
1091 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1092 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1093 HandleWindowSnapOrDock(action);
1094 break;
1095 case WINDOW_MINIMIZE:
1096 HandleWindowMinimize();
1097 break;
1098 case WINDOW_POSITION_CENTER:
1099 HandlePositionCenter();
1100 break;
1101 #if defined(OS_CHROMEOS)
1102 case BRIGHTNESS_DOWN:
1103 HandleBrightnessDown(brightness_control_delegate_.get(), accelerator);
1104 break;
1105 case BRIGHTNESS_UP:
1106 HandleBrightnessUp(brightness_control_delegate_.get(), accelerator);
1107 break;
1108 case DEBUG_ADD_REMOVE_DISPLAY:
1109 debug::PerformDebugActionIfEnabled(action);
1110 break;
1111 case DEBUG_TOGGLE_UNIFIED_DESKTOP:
1112 debug::PerformDebugActionIfEnabled(action);
1113 break;
1114 case DISABLE_CAPS_LOCK:
1115 HandleDisableCapsLock();
1116 break;
1117 case DISABLE_GPU_WATCHDOG:
1118 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
1119 break;
1120 case KEYBOARD_BRIGHTNESS_DOWN:
1121 HandleKeyboardBrightnessDown(keyboard_brightness_control_delegate_.get(),
1122 accelerator);
1123 break;
1124 case KEYBOARD_BRIGHTNESS_UP:
1125 HandleKeyboardBrightnessUp(keyboard_brightness_control_delegate_.get(),
1126 accelerator);
1127 break;
1128 case LOCK_PRESSED:
1129 case LOCK_RELEASED:
1130 Shell::GetInstance()->power_button_controller()->
1131 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1132 break;
1133 case LOCK_SCREEN:
1134 HandleLock();
1135 break;
1136 case OPEN_CROSH:
1137 HandleCrosh();
1138 break;
1139 case OPEN_FILE_MANAGER:
1140 HandleFileManager();
1141 break;
1142 case OPEN_GET_HELP:
1143 HandleGetHelp();
1144 break;
1145 case POWER_PRESSED: // fallthrough
1146 case POWER_RELEASED:
1147 if (!base::SysInfo::IsRunningOnChromeOS()) {
1148 // There is no powerd, the Chrome OS power manager, in linux desktop,
1149 // so call the PowerButtonController here.
1150 Shell::GetInstance()->power_button_controller()->
1151 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1153 // We don't do anything with these at present on the device,
1154 // (power button events are reported to us from powerm via
1155 // D-BUS), but we consume them to prevent them from getting
1156 // passed to apps -- see http://crbug.com/146609.
1157 break;
1158 case SILENCE_SPOKEN_FEEDBACK:
1159 HandleSilenceSpokenFeedback();
1160 break;
1161 case SWAP_PRIMARY_DISPLAY:
1162 HandleSwapPrimaryDisplay();
1163 break;
1164 case SWITCH_TO_NEXT_USER:
1165 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
1166 break;
1167 case SWITCH_TO_PREVIOUS_USER:
1168 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
1169 break;
1170 case TOGGLE_CAPS_LOCK:
1171 HandleToggleCapsLock();
1172 break;
1173 case TOGGLE_MIRROR_MODE:
1174 HandleToggleMirrorMode();
1175 break;
1176 case TOGGLE_SPOKEN_FEEDBACK:
1177 HandleToggleSpokenFeedback();
1178 break;
1179 case TOGGLE_TOUCH_VIEW_TESTING:
1180 HandleToggleTouchViewTesting();
1181 break;
1182 case TOGGLE_WIFI:
1183 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
1184 break;
1185 case TOUCH_HUD_CLEAR:
1186 HandleTouchHudClear();
1187 break;
1188 case TOUCH_HUD_MODE_CHANGE:
1189 HandleTouchHudModeChange();
1190 break;
1191 case TOUCH_HUD_PROJECTION_TOGGLE:
1192 accelerators::ToggleTouchHudProjection();
1193 break;
1194 case VOLUME_DOWN:
1195 HandleVolumeDown(accelerator);
1196 break;
1197 case VOLUME_MUTE:
1198 HandleVolumeMute(accelerator);
1199 break;
1200 case VOLUME_UP:
1201 HandleVolumeUp(accelerator);
1202 break;
1203 #else
1204 case DUMMY_FOR_RESERVED:
1205 NOTREACHED();
1206 break;
1207 #endif
1211 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1212 AcceleratorAction action) {
1213 #if defined(OS_CHROMEOS)
1214 if (action == SILENCE_SPOKEN_FEEDBACK)
1215 return false;
1216 #endif
1218 // Adding new exceptions is *STRONGLY* discouraged.
1219 return true;
1222 AcceleratorController::AcceleratorProcessingRestriction
1223 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1224 ash::Shell* shell = ash::Shell::GetInstance();
1225 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1226 actions_allowed_at_login_screen_.find(action) ==
1227 actions_allowed_at_login_screen_.end()) {
1228 return RESTRICTION_PREVENT_PROCESSING;
1230 if (shell->session_state_delegate()->IsScreenLocked() &&
1231 actions_allowed_at_lock_screen_.find(action) ==
1232 actions_allowed_at_lock_screen_.end()) {
1233 return RESTRICTION_PREVENT_PROCESSING;
1235 if (shell->delegate()->IsRunningInForcedAppMode() &&
1236 actions_allowed_in_app_mode_.find(action) ==
1237 actions_allowed_in_app_mode_.end()) {
1238 return RESTRICTION_PREVENT_PROCESSING;
1240 if (shell->IsSystemModalWindowOpen() &&
1241 actions_allowed_at_modal_window_.find(action) ==
1242 actions_allowed_at_modal_window_.end()) {
1243 // Note we prevent the shortcut from propagating so it will not
1244 // be passed to the modal window. This is important for things like
1245 // Alt+Tab that would cause an undesired effect in the modal window by
1246 // cycling through its window elements.
1247 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1249 if (shell->mru_window_tracker()->BuildMruWindowList().empty() &&
1250 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1251 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1252 ui::A11Y_ALERT_WINDOW_NEEDED);
1253 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1255 return RESTRICTION_NONE;
1258 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1259 scoped_ptr<KeyboardBrightnessControlDelegate>
1260 keyboard_brightness_control_delegate) {
1261 keyboard_brightness_control_delegate_ =
1262 keyboard_brightness_control_delegate.Pass();
1265 } // namespace ash