Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blob0dd608521ee582d66f265c81bd9025c07e288610
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/display_controller.h"
16 #include "ash/display/display_manager.h"
17 #include "ash/display/display_util.h"
18 #include "ash/focus_cycler.h"
19 #include "ash/gpu_support.h"
20 #include "ash/ime_control_delegate.h"
21 #include "ash/magnifier/magnification_controller.h"
22 #include "ash/magnifier/partial_magnification_controller.h"
23 #include "ash/media_delegate.h"
24 #include "ash/multi_profile_uma.h"
25 #include "ash/new_window_delegate.h"
26 #include "ash/root_window_controller.h"
27 #include "ash/rotator/screen_rotation.h"
28 #include "ash/screenshot_delegate.h"
29 #include "ash/session/session_state_delegate.h"
30 #include "ash/shelf/shelf.h"
31 #include "ash/shelf/shelf_delegate.h"
32 #include "ash/shelf/shelf_model.h"
33 #include "ash/shelf/shelf_widget.h"
34 #include "ash/shell.h"
35 #include "ash/shell_delegate.h"
36 #include "ash/shell_window_ids.h"
37 #include "ash/system/brightness_control_delegate.h"
38 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
39 #include "ash/system/status_area_widget.h"
40 #include "ash/system/tray/system_tray.h"
41 #include "ash/system/tray/system_tray_delegate.h"
42 #include "ash/system/tray/system_tray_notifier.h"
43 #include "ash/system/web_notification/web_notification_tray.h"
44 #include "ash/touch/touch_hud_debug.h"
45 #include "ash/utility/partial_screenshot_controller.h"
46 #include "ash/volume_control_delegate.h"
47 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
48 #include "ash/wm/mru_window_tracker.h"
49 #include "ash/wm/overview/window_selector_controller.h"
50 #include "ash/wm/power_button_controller.h"
51 #include "ash/wm/window_cycle_controller.h"
52 #include "ash/wm/window_state.h"
53 #include "ash/wm/window_util.h"
54 #include "ash/wm/wm_event.h"
55 #include "base/bind.h"
56 #include "base/command_line.h"
57 #include "base/metrics/user_metrics.h"
58 #include "ui/aura/env.h"
59 #include "ui/base/accelerators/accelerator.h"
60 #include "ui/base/accelerators/accelerator_manager.h"
61 #include "ui/compositor/layer.h"
62 #include "ui/compositor/layer_animation_sequence.h"
63 #include "ui/compositor/layer_animator.h"
64 #include "ui/events/event.h"
65 #include "ui/events/keycodes/keyboard_codes.h"
66 #include "ui/gfx/screen.h"
67 #include "ui/views/controls/webview/webview.h"
69 #if defined(OS_CHROMEOS)
70 #include "ash/system/chromeos/keyboard_brightness_controller.h"
71 #include "base/sys_info.h"
72 #include "ui/base/ime/chromeos/ime_keyboard.h"
73 #include "ui/base/ime/chromeos/input_method_manager.h"
74 #endif // defined(OS_CHROMEOS)
76 namespace ash {
77 namespace {
79 using base::UserMetricsAction;
81 bool CanHandleAccessibleFocusCycle() {
82 if (!Shell::GetInstance()->accessibility_delegate()->
83 IsSpokenFeedbackEnabled()) {
84 return false;
86 aura::Window* active_window = ash::wm::GetActiveWindow();
87 if (!active_window)
88 return false;
89 views::Widget* widget =
90 views::Widget::GetWidgetForNativeWindow(active_window);
91 if (!widget)
92 return false;
93 views::FocusManager* focus_manager = widget->GetFocusManager();
94 if (!focus_manager)
95 return false;
96 views::View* view = focus_manager->GetFocusedView();
97 return view && strcmp(view->GetClassName(), views::WebView::kViewClassName);
100 void HandleAccessibleFocusCycle(bool reverse) {
101 if (reverse)
102 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
103 else
104 base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Next"));
106 aura::Window* active_window = ash::wm::GetActiveWindow();
107 views::Widget* widget =
108 views::Widget::GetWidgetForNativeWindow(active_window);
109 widget->GetFocusManager()->AdvanceFocus(reverse);
112 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
113 if (accelerator.key_code() == ui::VKEY_TAB)
114 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
116 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
117 WindowCycleController::BACKWARD);
120 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
121 if (accelerator.key_code() == ui::VKEY_TAB)
122 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
124 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
125 WindowCycleController::FORWARD);
128 void HandleRotatePaneFocus(Shell::Direction direction) {
129 Shell* shell = Shell::GetInstance();
130 switch (direction) {
131 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
132 case Shell::FORWARD: {
133 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
134 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
135 break;
137 case Shell::BACKWARD: {
138 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
139 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
140 break;
145 void HandleFocusShelf() {
146 Shell* shell = Shell::GetInstance();
147 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
148 shell->focus_cycler()->FocusWidget(
149 Shelf::ForPrimaryDisplay()->shelf_widget());
152 void HandleLaunchAppN(int n) {
153 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
154 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
157 void HandleLaunchLastApp() {
158 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
159 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
162 bool CanHandleMagnifyScreen() {
163 Shell* shell = Shell::GetInstance();
164 return shell->magnification_controller()->IsEnabled() ||
165 shell->partial_magnification_controller()->is_enabled();
168 // Magnify the screen
169 void HandleMagnifyScreen(int delta_index) {
170 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
171 // TODO(yoshiki): Move the following logic to MagnificationController.
172 float scale =
173 ash::Shell::GetInstance()->magnification_controller()->GetScale();
174 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
175 int scale_index = std::floor(
176 std::log(scale) / std::log(ui::kMagnificationScaleFactor) + 0.5);
178 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
180 ash::Shell::GetInstance()->magnification_controller()->SetScale(
181 std::pow(ui::kMagnificationScaleFactor, new_scale_index), true);
182 } else if (ash::Shell::GetInstance()->
183 partial_magnification_controller()->is_enabled()) {
184 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
185 ash::Shell::GetInstance()->partial_magnification_controller()->
186 SetScale(scale);
190 void HandleMediaNextTrack() {
191 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
194 void HandleMediaPlayPause() {
195 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
198 void HandleMediaPrevTrack() {
199 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
202 bool CanHandleNewIncognitoWindow() {
203 return Shell::GetInstance()->delegate()->IsIncognitoAllowed();
206 void HandleNewIncognitoWindow() {
207 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
208 Shell::GetInstance()->new_window_delegate()->NewWindow(
209 true /* is_incognito */);
212 void HandleNewTab(const ui::Accelerator& accelerator) {
213 if (accelerator.key_code() == ui::VKEY_T)
214 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
215 Shell::GetInstance()->new_window_delegate()->NewTab();
218 void HandleNewWindow() {
219 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
220 Shell::GetInstance()->new_window_delegate()->NewWindow(
221 false /* is_incognito */);
224 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
225 const ui::Accelerator& previous_accelerator) {
226 // This check is necessary e.g. not to process the Shift+Alt+
227 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
228 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
229 // is released.
230 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
231 if (previous_accelerator.type() == ui::ET_KEY_RELEASED &&
232 // Workaround for crbug.com/139556. CJK IME users tend to press
233 // Enter (or Space) and Shift+Alt almost at the same time to commit
234 // an IME string and then switch from the IME to the English layout.
235 // This workaround allows the user to trigger NEXT_IME even if the
236 // user presses Shift+Alt before releasing Enter.
237 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
238 previous_key_code != ui::VKEY_RETURN &&
239 previous_key_code != ui::VKEY_SPACE) {
240 // We totally ignore this accelerator.
241 // TODO(mazda): Fix crbug.com/158217
242 return false;
244 return ime_control_delegate && ime_control_delegate->CanCycleIme();
247 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
248 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
249 ime_control_delegate->HandleNextIme();
252 void HandleOpenFeedbackPage() {
253 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
254 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
257 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
258 return ime_control_delegate && ime_control_delegate->CanCycleIme();
261 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
262 const ui::Accelerator& accelerator) {
263 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
264 if (accelerator.type() == ui::ET_KEY_PRESSED)
265 ime_control_delegate->HandlePreviousIme();
266 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
269 void HandleRestoreTab() {
270 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
271 Shell::GetInstance()->new_window_delegate()->RestoreTab();
274 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
275 switch (current) {
276 case gfx::Display::ROTATE_0:
277 return gfx::Display::ROTATE_90;
278 case gfx::Display::ROTATE_90:
279 return gfx::Display::ROTATE_180;
280 case gfx::Display::ROTATE_180:
281 return gfx::Display::ROTATE_270;
282 case gfx::Display::ROTATE_270:
283 return gfx::Display::ROTATE_0;
285 NOTREACHED() << "Unknown rotation:" << current;
286 return gfx::Display::ROTATE_0;
289 // Rotates the screen.
290 void HandleRotateScreen() {
291 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
292 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
293 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
294 const DisplayInfo& display_info =
295 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
296 Shell::GetInstance()->display_manager()->SetDisplayRotation(
297 display.id(), GetNextRotation(display_info.rotation()));
300 // Rotate the active window.
301 void HandleRotateActiveWindow() {
302 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
303 aura::Window* active_window = wm::GetActiveWindow();
304 if (active_window) {
305 // The rotation animation bases its target transform on the current
306 // rotation and position. Since there could be an animation in progress
307 // right now, queue this animation so when it starts it picks up a neutral
308 // rotation and position. Use replace so we only enqueue one at a time.
309 active_window->layer()->GetAnimator()->
310 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
311 active_window->layer()->GetAnimator()->StartAnimation(
312 new ui::LayerAnimationSequence(
313 new ash::ScreenRotation(360, active_window->layer())));
317 bool CanHandleScaleReset() {
318 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
319 int64 display_id = display_manager->GetDisplayIdForUIScaling();
320 return (display_id != gfx::Display::kInvalidDisplayID &&
321 display_manager->GetDisplayInfo(display_id).configured_ui_scale() !=
322 1.0f);
325 void HandleScaleReset() {
326 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset"));
327 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
328 int64 display_id = display_manager->GetDisplayIdForUIScaling();
329 display_manager->SetDisplayUIScale(display_id, 1.0f);
332 bool CanHandleScaleUI() {
333 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
334 int64 display_id = display_manager->GetDisplayIdForUIScaling();
335 return display_id != gfx::Display::kInvalidDisplayID;
338 void HandleScaleUI(bool up) {
339 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
340 int64 display_id = display_manager->GetDisplayIdForUIScaling();
342 if (up) {
343 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up"));
344 } else {
345 base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down"));
348 const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
349 float next_scale = GetNextUIScale(display_info, up);
350 display_manager->SetDisplayUIScale(display_id, next_scale);
353 void HandleShowKeyboardOverlay() {
354 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
355 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
358 bool CanHandleShowMessageCenterBubble() {
359 RootWindowController* controller =
360 RootWindowController::ForTargetRootWindow();
361 StatusAreaWidget* status_area_widget =
362 controller->shelf()->status_area_widget();
363 return status_area_widget &&
364 status_area_widget->web_notification_tray()->visible();
367 void HandleShowMessageCenterBubble() {
368 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
369 RootWindowController* controller =
370 RootWindowController::ForTargetRootWindow();
371 StatusAreaWidget* status_area_widget =
372 controller->shelf()->status_area_widget();
373 if (status_area_widget) {
374 WebNotificationTray* notification_tray =
375 status_area_widget->web_notification_tray();
376 if (notification_tray->visible())
377 notification_tray->ShowMessageCenterBubble();
381 void HandleShowSystemTrayBubble() {
382 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
383 RootWindowController* controller =
384 RootWindowController::ForTargetRootWindow();
385 if (!controller->GetSystemTray()->HasSystemBubble())
386 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
389 void HandleShowTaskManager() {
390 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
391 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
394 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
395 const ui::Accelerator& accelerator) {
396 return ime_control_delegate &&
397 ime_control_delegate->CanSwitchIme(accelerator);
400 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
401 const ui::Accelerator& accelerator) {
402 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
403 ime_control_delegate->HandleSwitchIme(accelerator);
406 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
407 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
408 DCHECK(screenshot_delegate);
409 Shell::GetInstance()
410 ->partial_screenshot_controller()
411 ->StartPartialScreenshotSession(screenshot_delegate);
414 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
415 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
416 DCHECK(screenshot_delegate);
417 if (screenshot_delegate->CanTakeScreenshot())
418 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
421 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
422 const ui::Accelerator& previous_accelerator) {
423 if (accelerator.key_code() == ui::VKEY_LWIN) {
424 // If something else was pressed between the Search key (LWIN)
425 // being pressed and released, then ignore the release of the
426 // Search key.
427 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
428 previous_accelerator.key_code() != ui::VKEY_LWIN) {
429 return false;
432 // When spoken feedback is enabled, we should neither toggle the list nor
433 // consume the key since Search+Shift is one of the shortcuts the a11y
434 // feature uses. crbug.com/132296
435 if (Shell::GetInstance()
436 ->accessibility_delegate()
437 ->IsSpokenFeedbackEnabled()) {
438 return false;
441 return true;
444 void HandleToggleAppList(const ui::Accelerator& accelerator) {
445 if (accelerator.key_code() == ui::VKEY_LWIN)
446 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
447 ash::Shell::GetInstance()->ToggleAppList(NULL);
450 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
451 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
452 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
453 accelerators::ToggleFullscreen();
456 void HandleToggleOverview() {
457 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
458 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
461 bool CanHandleWindowSnapOrDock() {
462 wm::WindowState* window_state = wm::GetActiveWindowState();
463 // Disable window snapping shortcut key for full screen window due to
464 // http://crbug.com/135487.
465 return (window_state &&
466 (window_state->window()->type() == ui::wm::WINDOW_TYPE_NORMAL ||
467 window_state->window()->type() == ui::wm::WINDOW_TYPE_PANEL) &&
468 !window_state->IsFullscreen());
471 void HandleWindowSnapOrDock(AcceleratorAction action) {
472 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
473 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
474 else
475 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
477 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT ?
478 wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT :
479 wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
480 wm::GetActiveWindowState()->OnWMEvent(&event);
483 void HandleWindowMinimize() {
484 base::RecordAction(
485 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
486 accelerators::ToggleMinimized();
489 bool CanHandlePositionCenter() {
490 // Docked windows do not support centering.
491 wm::WindowState* window_state = wm::GetActiveWindowState();
492 return (window_state && !window_state->IsDocked());
495 void HandlePositionCenter() {
496 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
497 wm::CenterWindow(wm::GetActiveWindow());
500 #if defined(OS_CHROMEOS)
501 void HandleBrightnessDown(BrightnessControlDelegate* delegate,
502 const ui::Accelerator& accelerator) {
503 if (delegate)
504 delegate->HandleBrightnessDown(accelerator);
507 void HandleBrightnessUp(BrightnessControlDelegate* delegate,
508 const ui::Accelerator& accelerator) {
509 if (delegate)
510 delegate->HandleBrightnessUp(accelerator);
513 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
514 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
515 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
516 (previous_key_code != ui::VKEY_LSHIFT &&
517 previous_key_code != ui::VKEY_SHIFT &&
518 previous_key_code != ui::VKEY_RSHIFT)) {
519 // If something else was pressed between the Shift key being pressed
520 // and released, then ignore the release of the Shift key.
521 return false;
523 chromeos::input_method::InputMethodManager* ime =
524 chromeos::input_method::InputMethodManager::Get();
525 chromeos::input_method::ImeKeyboard* keyboard =
526 ime ? ime->GetImeKeyboard() : NULL;
527 return (keyboard && keyboard->CapsLockIsEnabled());
530 void HandleDisableCapsLock() {
531 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
532 chromeos::input_method::InputMethodManager* ime =
533 chromeos::input_method::InputMethodManager::Get();
534 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
537 void HandleKeyboardBrightnessDown(KeyboardBrightnessControlDelegate* delegate,
538 const ui::Accelerator& accelerator) {
539 if (delegate)
540 delegate->HandleKeyboardBrightnessDown(accelerator);
543 void HandleKeyboardBrightnessUp(KeyboardBrightnessControlDelegate* delegate,
544 const ui::Accelerator& accelerator) {
545 if (delegate)
546 delegate->HandleKeyboardBrightnessUp(accelerator);
549 void HandleLock() {
550 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
551 Shell::GetInstance()->session_state_delegate()->LockScreen();
554 void HandleCrosh() {
555 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
557 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
560 void HandleFileManager() {
561 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
563 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
566 void HandleGetHelp() {
567 Shell::GetInstance()->new_window_delegate()->OpenGetHelp();
570 bool CanHandleSilenceSpokenFeedback() {
571 AccessibilityDelegate* delegate =
572 Shell::GetInstance()->accessibility_delegate();
573 return delegate->IsSpokenFeedbackEnabled();
576 void HandleSilenceSpokenFeedback() {
577 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
578 Shell::GetInstance()->accessibility_delegate()->SilenceSpokenFeedback();
581 void HandleSwapPrimaryDisplay() {
582 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
583 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
586 bool CanHandleCycleUser() {
587 Shell* shell = Shell::GetInstance();
588 return shell->delegate()->IsMultiProfilesEnabled() &&
589 shell->session_state_delegate()->NumberOfLoggedInUsers() > 1;
592 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
593 MultiProfileUMA::RecordSwitchActiveUser(
594 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
595 switch (cycle_user) {
596 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
597 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
598 break;
599 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
600 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
601 break;
603 Shell::GetInstance()->session_state_delegate()->CycleActiveUser(cycle_user);
606 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
607 const ui::Accelerator& previous_accelerator) {
608 if (accelerator.key_code() == ui::VKEY_LWIN) {
609 // If something else was pressed between the Search key (LWIN)
610 // being pressed and released, then ignore the release of the
611 // Search key.
612 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
613 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
614 previous_accelerator.key_code() != ui::VKEY_LWIN)
615 return false;
617 chromeos::input_method::InputMethodManager* ime =
618 chromeos::input_method::InputMethodManager::Get();
619 return ime && ime->GetImeKeyboard();
622 void HandleToggleCapsLock() {
623 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
624 chromeos::input_method::InputMethodManager* ime =
625 chromeos::input_method::InputMethodManager::Get();
626 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
627 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
630 void HandleToggleMirrorMode() {
631 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
632 Shell::GetInstance()->display_controller()->ToggleMirrorMode();
635 void HandleToggleSpokenFeedback() {
636 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
638 Shell::GetInstance()->accessibility_delegate()->
639 ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_SHOW);
642 bool CanHandleToggleTouchViewTesting() {
643 return base::CommandLine::ForCurrentProcess()->HasSwitch(
644 switches::kAshEnableTouchViewTesting);
647 void HandleToggleTouchViewTesting() {
648 // TODO(skuhne): This is only temporary! Remove this!
649 MaximizeModeController* controller = Shell::GetInstance()->
650 maximize_mode_controller();
651 controller->EnableMaximizeModeWindowManager(
652 !controller->IsMaximizeModeWindowManagerEnabled());
655 bool CanHandleTouchHud() {
656 return RootWindowController::ForTargetRootWindow()->touch_hud_debug();
659 void HandleTouchHudClear() {
660 RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear();
663 void HandleTouchHudModeChange() {
664 RootWindowController* controller =
665 RootWindowController::ForTargetRootWindow();
666 controller->touch_hud_debug()->ChangeToNextMode();
669 void HandleVolumeDown(const ui::Accelerator& accelerator) {
670 VolumeControlDelegate* volume_delegate =
671 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
672 if (volume_delegate)
673 volume_delegate->HandleVolumeDown(accelerator);
676 void HandleVolumeMute(const ui::Accelerator& accelerator) {
677 VolumeControlDelegate* volume_delegate =
678 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
679 if (volume_delegate)
680 volume_delegate->HandleVolumeMute(accelerator);
683 void HandleVolumeUp(const ui::Accelerator& accelerator) {
684 VolumeControlDelegate* volume_delegate =
685 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
686 if (volume_delegate)
687 volume_delegate->HandleVolumeUp(accelerator);
690 #endif // defined(OS_CHROMEOS)
692 } // namespace
694 ////////////////////////////////////////////////////////////////////////////////
695 // AcceleratorController, public:
697 AcceleratorController::AcceleratorController()
698 : accelerator_manager_(new ui::AcceleratorManager),
699 accelerator_history_(new ui::AcceleratorHistory) {
700 Init();
703 AcceleratorController::~AcceleratorController() {
706 void AcceleratorController::Register(const ui::Accelerator& accelerator,
707 ui::AcceleratorTarget* target) {
708 accelerator_manager_->Register(accelerator,
709 ui::AcceleratorManager::kNormalPriority,
710 target);
713 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
714 ui::AcceleratorTarget* target) {
715 accelerator_manager_->Unregister(accelerator, target);
718 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
719 accelerator_manager_->UnregisterAll(target);
722 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
723 if (ime_control_delegate_) {
724 return accelerator_manager_->Process(
725 ime_control_delegate_->RemapAccelerator(accelerator));
727 return accelerator_manager_->Process(accelerator);
730 bool AcceleratorController::IsRegistered(
731 const ui::Accelerator& accelerator) const {
732 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
735 bool AcceleratorController::IsPreferred(
736 const ui::Accelerator& accelerator) const {
737 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
738 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
740 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
741 accelerators_.find(remapped_accelerator);
742 if (iter == accelerators_.end())
743 return false; // not an accelerator.
745 return preferred_actions_.find(iter->second) != preferred_actions_.end();
748 bool AcceleratorController::IsReserved(
749 const ui::Accelerator& accelerator) const {
750 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
751 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
753 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
754 accelerators_.find(remapped_accelerator);
755 if (iter == accelerators_.end())
756 return false; // not an accelerator.
758 return reserved_actions_.find(iter->second) != reserved_actions_.end();
761 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
762 if (CanPerformAction(action, ui::Accelerator())) {
763 PerformAction(action, ui::Accelerator());
764 return true;
766 return false;
769 AcceleratorController::AcceleratorProcessingRestriction
770 AcceleratorController::GetCurrentAcceleratorRestriction() {
771 return GetAcceleratorProcessingRestriction(-1);
774 void AcceleratorController::SetBrightnessControlDelegate(
775 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
776 brightness_control_delegate_ = brightness_control_delegate.Pass();
779 void AcceleratorController::SetImeControlDelegate(
780 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
781 ime_control_delegate_ = ime_control_delegate.Pass();
784 void AcceleratorController::SetScreenshotDelegate(
785 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
786 screenshot_delegate_ = screenshot_delegate.Pass();
789 ////////////////////////////////////////////////////////////////////////////////
790 // AcceleratorController, ui::AcceleratorTarget implementation:
792 bool AcceleratorController::AcceleratorPressed(
793 const ui::Accelerator& accelerator) {
794 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
795 accelerators_.find(accelerator);
796 DCHECK(it != accelerators_.end());
797 AcceleratorAction action = it->second;
798 if (CanPerformAction(action, accelerator)) {
799 PerformAction(action, accelerator);
800 return ShouldActionConsumeKeyEvent(action);
802 return false;
805 bool AcceleratorController::CanHandleAccelerators() const {
806 return true;
809 ///////////////////////////////////////////////////////////////////////////////
810 // AcceleratorController, private:
812 void AcceleratorController::Init() {
813 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
814 actions_allowed_at_login_screen_.insert(
815 kActionsAllowedAtLoginOrLockScreen[i]);
816 actions_allowed_at_lock_screen_.insert(
817 kActionsAllowedAtLoginOrLockScreen[i]);
819 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
820 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
821 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
822 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
823 for (size_t i = 0; i < kPreferredActionsLength; ++i)
824 preferred_actions_.insert(kPreferredActions[i]);
825 for (size_t i = 0; i < kReservedActionsLength; ++i)
826 reserved_actions_.insert(kReservedActions[i]);
827 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
828 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
829 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
830 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
831 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
832 actions_needing_window_.insert(kActionsNeedingWindow[i]);
834 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
836 if (debug::DebugAcceleratorsEnabled()) {
837 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
838 // All debug accelerators are reserved.
839 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
840 reserved_actions_.insert(kDebugAcceleratorData[i].action);
843 #if defined(OS_CHROMEOS)
844 keyboard_brightness_control_delegate_.reset(
845 new KeyboardBrightnessController());
846 #endif
849 void AcceleratorController::RegisterAccelerators(
850 const AcceleratorData accelerators[],
851 size_t accelerators_length) {
852 for (size_t i = 0; i < accelerators_length; ++i) {
853 ui::Accelerator accelerator(accelerators[i].keycode,
854 accelerators[i].modifiers);
855 accelerator.set_type(accelerators[i].trigger_on_press ?
856 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
857 Register(accelerator, this);
858 accelerators_.insert(
859 std::make_pair(accelerator, accelerators[i].action));
863 bool AcceleratorController::CanPerformAction(
864 AcceleratorAction action,
865 const ui::Accelerator& accelerator) {
866 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
867 accelerator.IsRepeat()) {
868 return false;
871 AcceleratorProcessingRestriction restriction =
872 GetAcceleratorProcessingRestriction(action);
873 if (restriction != RESTRICTION_NONE)
874 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
876 const ui::Accelerator& previous_accelerator =
877 accelerator_history_->previous_accelerator();
879 // True should be returned if running |action| does something. Otherwise,
880 // false should be returned to give the web contents a chance at handling the
881 // accelerator.
882 switch (action) {
883 case ACCESSIBLE_FOCUS_NEXT:
884 case ACCESSIBLE_FOCUS_PREVIOUS:
885 return CanHandleAccessibleFocusCycle();
886 case DEBUG_PRINT_LAYER_HIERARCHY:
887 case DEBUG_PRINT_VIEW_HIERARCHY:
888 case DEBUG_PRINT_WINDOW_HIERARCHY:
889 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
890 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
891 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
892 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
893 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
894 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
895 return debug::DebugAcceleratorsEnabled();
896 case MAGNIFY_SCREEN_ZOOM_IN:
897 case MAGNIFY_SCREEN_ZOOM_OUT:
898 return CanHandleMagnifyScreen();
899 case NEW_INCOGNITO_WINDOW:
900 return CanHandleNewIncognitoWindow();
901 case NEXT_IME:
902 return CanHandleNextIme(ime_control_delegate_.get(),
903 previous_accelerator);
904 case PREVIOUS_IME:
905 return CanHandlePreviousIme(ime_control_delegate_.get());
906 case SCALE_UI_RESET:
907 return CanHandleScaleReset();
908 case SCALE_UI_UP:
909 case SCALE_UI_DOWN:
910 return CanHandleScaleUI();
911 case SHOW_MESSAGE_CENTER_BUBBLE:
912 return CanHandleShowMessageCenterBubble();
913 case SWITCH_IME:
914 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
915 case TOGGLE_APP_LIST:
916 return CanHandleToggleAppList(accelerator, previous_accelerator);
917 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
918 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
919 return CanHandleWindowSnapOrDock();
920 case WINDOW_POSITION_CENTER:
921 return CanHandlePositionCenter();
922 #if defined(OS_CHROMEOS)
923 case DEBUG_ADD_REMOVE_DISPLAY:
924 return debug::DebugAcceleratorsEnabled();
925 case DISABLE_CAPS_LOCK:
926 return CanHandleDisableCapsLock(previous_accelerator);
927 case SILENCE_SPOKEN_FEEDBACK:
928 return CanHandleSilenceSpokenFeedback();
929 case SWITCH_TO_PREVIOUS_USER:
930 case SWITCH_TO_NEXT_USER:
931 return CanHandleCycleUser();
932 case TOGGLE_CAPS_LOCK:
933 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
934 case TOGGLE_TOUCH_VIEW_TESTING:
935 return CanHandleToggleTouchViewTesting();
936 case TOUCH_HUD_CLEAR:
937 case TOUCH_HUD_MODE_CHANGE:
938 return CanHandleTouchHud();
939 #endif
941 case CYCLE_BACKWARD_MRU:
942 case CYCLE_FORWARD_MRU:
943 case EXIT:
944 case FOCUS_NEXT_PANE:
945 case FOCUS_PREVIOUS_PANE:
946 case FOCUS_SHELF:
947 case LAUNCH_APP_0:
948 case LAUNCH_APP_1:
949 case LAUNCH_APP_2:
950 case LAUNCH_APP_3:
951 case LAUNCH_APP_4:
952 case LAUNCH_APP_5:
953 case LAUNCH_APP_6:
954 case LAUNCH_APP_7:
955 case LAUNCH_LAST_APP:
956 case MEDIA_NEXT_TRACK:
957 case MEDIA_PLAY_PAUSE:
958 case MEDIA_PREV_TRACK:
959 case NEW_TAB:
960 case NEW_WINDOW:
961 case OPEN_FEEDBACK_PAGE:
962 case PRINT_UI_HIERARCHIES:
963 case RESTORE_TAB:
964 case ROTATE_SCREEN:
965 case ROTATE_WINDOW:
966 case SHOW_KEYBOARD_OVERLAY:
967 case SHOW_SYSTEM_TRAY_BUBBLE:
968 case SHOW_TASK_MANAGER:
969 case TAKE_PARTIAL_SCREENSHOT:
970 case TAKE_SCREENSHOT:
971 case TOGGLE_FULLSCREEN:
972 case TOGGLE_MAXIMIZED:
973 case TOGGLE_OVERVIEW:
974 case WINDOW_MINIMIZE:
975 #if defined(OS_CHROMEOS)
976 case BRIGHTNESS_DOWN:
977 case BRIGHTNESS_UP:
978 case DISABLE_GPU_WATCHDOG:
979 case KEYBOARD_BRIGHTNESS_DOWN:
980 case KEYBOARD_BRIGHTNESS_UP:
981 case LOCK_PRESSED:
982 case LOCK_RELEASED:
983 case LOCK_SCREEN:
984 case OPEN_CROSH:
985 case OPEN_FILE_MANAGER:
986 case OPEN_GET_HELP:
987 case POWER_PRESSED:
988 case POWER_RELEASED:
989 case SWAP_PRIMARY_DISPLAY:
990 case TOGGLE_MIRROR_MODE:
991 case TOGGLE_SPOKEN_FEEDBACK:
992 case TOGGLE_WIFI:
993 case TOUCH_HUD_PROJECTION_TOGGLE:
994 case VOLUME_DOWN:
995 case VOLUME_MUTE:
996 case VOLUME_UP:
997 #else
998 case DUMMY_FOR_RESERVED:
999 #endif
1000 return true;
1002 return false;
1005 void AcceleratorController::PerformAction(AcceleratorAction action,
1006 const ui::Accelerator& accelerator) {
1007 AcceleratorProcessingRestriction restriction =
1008 GetAcceleratorProcessingRestriction(action);
1009 if (restriction != RESTRICTION_NONE)
1010 return;
1012 // If your accelerator invokes more than one line of code, please either
1013 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
1014 // below) or pull it into a HandleFoo() function above.
1015 switch (action) {
1016 case ACCESSIBLE_FOCUS_NEXT:
1017 HandleAccessibleFocusCycle(false);
1018 break;
1019 case ACCESSIBLE_FOCUS_PREVIOUS:
1020 HandleAccessibleFocusCycle(true);
1021 break;
1022 case CYCLE_BACKWARD_MRU:
1023 HandleCycleBackwardMRU(accelerator);
1024 break;
1025 case CYCLE_FORWARD_MRU:
1026 HandleCycleForwardMRU(accelerator);
1027 break;
1028 case DEBUG_PRINT_LAYER_HIERARCHY:
1029 case DEBUG_PRINT_VIEW_HIERARCHY:
1030 case DEBUG_PRINT_WINDOW_HIERARCHY:
1031 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
1032 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
1033 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
1034 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
1035 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
1036 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
1037 debug::PerformDebugActionIfEnabled(action);
1038 break;
1039 case EXIT:
1040 // UMA metrics are recorded in the handler.
1041 exit_warning_handler_.HandleAccelerator();
1042 break;
1043 case FOCUS_NEXT_PANE:
1044 HandleRotatePaneFocus(Shell::FORWARD);
1045 break;
1046 case FOCUS_PREVIOUS_PANE:
1047 HandleRotatePaneFocus(Shell::BACKWARD);
1048 break;
1049 case FOCUS_SHELF:
1050 HandleFocusShelf();
1051 break;
1052 case LAUNCH_APP_0:
1053 HandleLaunchAppN(0);
1054 break;
1055 case LAUNCH_APP_1:
1056 HandleLaunchAppN(1);
1057 break;
1058 case LAUNCH_APP_2:
1059 HandleLaunchAppN(2);
1060 break;
1061 case LAUNCH_APP_3:
1062 HandleLaunchAppN(3);
1063 break;
1064 case LAUNCH_APP_4:
1065 HandleLaunchAppN(4);
1066 break;
1067 case LAUNCH_APP_5:
1068 HandleLaunchAppN(5);
1069 break;
1070 case LAUNCH_APP_6:
1071 HandleLaunchAppN(6);
1072 break;
1073 case LAUNCH_APP_7:
1074 HandleLaunchAppN(7);
1075 break;
1076 case LAUNCH_LAST_APP:
1077 HandleLaunchLastApp();
1078 break;
1079 case MAGNIFY_SCREEN_ZOOM_IN:
1080 HandleMagnifyScreen(1);
1081 break;
1082 case MAGNIFY_SCREEN_ZOOM_OUT:
1083 HandleMagnifyScreen(-1);
1084 break;
1085 case MEDIA_NEXT_TRACK:
1086 HandleMediaNextTrack();
1087 break;
1088 case MEDIA_PLAY_PAUSE:
1089 HandleMediaPlayPause();
1090 break;
1091 case MEDIA_PREV_TRACK:
1092 HandleMediaPrevTrack();
1093 break;
1094 case NEW_INCOGNITO_WINDOW:
1095 HandleNewIncognitoWindow();
1096 break;
1097 case NEW_TAB:
1098 HandleNewTab(accelerator);
1099 break;
1100 case NEW_WINDOW:
1101 HandleNewWindow();
1102 break;
1103 case NEXT_IME:
1104 HandleNextIme(ime_control_delegate_.get());
1105 break;
1106 case OPEN_FEEDBACK_PAGE:
1107 HandleOpenFeedbackPage();
1108 break;
1109 case PREVIOUS_IME:
1110 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1111 break;
1112 case PRINT_UI_HIERARCHIES:
1113 debug::PrintUIHierarchies();
1114 break;
1115 case RESTORE_TAB:
1116 HandleRestoreTab();
1117 break;
1118 case ROTATE_SCREEN:
1119 HandleRotateScreen();
1120 break;
1121 case ROTATE_WINDOW:
1122 HandleRotateActiveWindow();
1123 break;
1124 case SCALE_UI_DOWN:
1125 HandleScaleUI(false /* down */);
1126 break;
1127 case SCALE_UI_RESET:
1128 HandleScaleReset();
1129 break;
1130 case SCALE_UI_UP:
1131 HandleScaleUI(true /* up */);
1132 break;
1133 case SHOW_KEYBOARD_OVERLAY:
1134 HandleShowKeyboardOverlay();
1135 break;
1136 case SHOW_MESSAGE_CENTER_BUBBLE:
1137 HandleShowMessageCenterBubble();
1138 break;
1139 case SHOW_SYSTEM_TRAY_BUBBLE:
1140 HandleShowSystemTrayBubble();
1141 break;
1142 case SHOW_TASK_MANAGER:
1143 HandleShowTaskManager();
1144 break;
1145 case SWITCH_IME:
1146 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1147 break;
1148 case TAKE_PARTIAL_SCREENSHOT:
1149 HandleTakePartialScreenshot(screenshot_delegate_.get());
1150 break;
1151 case TAKE_SCREENSHOT:
1152 HandleTakeScreenshot(screenshot_delegate_.get());
1153 break;
1154 case TOGGLE_APP_LIST:
1155 HandleToggleAppList(accelerator);
1156 break;
1157 case TOGGLE_FULLSCREEN:
1158 HandleToggleFullscreen(accelerator);
1159 break;
1160 case TOGGLE_MAXIMIZED:
1161 accelerators::ToggleMaximized();
1162 break;
1163 case TOGGLE_OVERVIEW:
1164 HandleToggleOverview();
1165 break;
1166 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1167 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1168 HandleWindowSnapOrDock(action);
1169 break;
1170 case WINDOW_MINIMIZE:
1171 HandleWindowMinimize();
1172 break;
1173 case WINDOW_POSITION_CENTER:
1174 HandlePositionCenter();
1175 break;
1176 #if defined(OS_CHROMEOS)
1177 case BRIGHTNESS_DOWN:
1178 HandleBrightnessDown(brightness_control_delegate_.get(), accelerator);
1179 break;
1180 case BRIGHTNESS_UP:
1181 HandleBrightnessUp(brightness_control_delegate_.get(), accelerator);
1182 break;
1183 case DEBUG_ADD_REMOVE_DISPLAY:
1184 debug::PerformDebugActionIfEnabled(action);
1185 break;
1186 case DISABLE_CAPS_LOCK:
1187 HandleDisableCapsLock();
1188 break;
1189 case DISABLE_GPU_WATCHDOG:
1190 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
1191 break;
1192 case KEYBOARD_BRIGHTNESS_DOWN:
1193 HandleKeyboardBrightnessDown(keyboard_brightness_control_delegate_.get(),
1194 accelerator);
1195 break;
1196 case KEYBOARD_BRIGHTNESS_UP:
1197 HandleKeyboardBrightnessUp(keyboard_brightness_control_delegate_.get(),
1198 accelerator);
1199 break;
1200 case LOCK_PRESSED:
1201 case LOCK_RELEASED:
1202 Shell::GetInstance()->power_button_controller()->
1203 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1204 break;
1205 case LOCK_SCREEN:
1206 HandleLock();
1207 break;
1208 case OPEN_CROSH:
1209 HandleCrosh();
1210 break;
1211 case OPEN_FILE_MANAGER:
1212 HandleFileManager();
1213 break;
1214 case OPEN_GET_HELP:
1215 HandleGetHelp();
1216 break;
1217 case POWER_PRESSED: // fallthrough
1218 case POWER_RELEASED:
1219 if (!base::SysInfo::IsRunningOnChromeOS()) {
1220 // There is no powerd, the Chrome OS power manager, in linux desktop,
1221 // so call the PowerButtonController here.
1222 Shell::GetInstance()->power_button_controller()->
1223 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1225 // We don't do anything with these at present on the device,
1226 // (power button events are reported to us from powerm via
1227 // D-BUS), but we consume them to prevent them from getting
1228 // passed to apps -- see http://crbug.com/146609.
1229 break;
1230 case SILENCE_SPOKEN_FEEDBACK:
1231 HandleSilenceSpokenFeedback();
1232 break;
1233 case SWAP_PRIMARY_DISPLAY:
1234 HandleSwapPrimaryDisplay();
1235 break;
1236 case SWITCH_TO_NEXT_USER:
1237 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
1238 break;
1239 case SWITCH_TO_PREVIOUS_USER:
1240 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
1241 break;
1242 case TOGGLE_CAPS_LOCK:
1243 HandleToggleCapsLock();
1244 break;
1245 case TOGGLE_MIRROR_MODE:
1246 HandleToggleMirrorMode();
1247 break;
1248 case TOGGLE_SPOKEN_FEEDBACK:
1249 HandleToggleSpokenFeedback();
1250 break;
1251 case TOGGLE_TOUCH_VIEW_TESTING:
1252 HandleToggleTouchViewTesting();
1253 break;
1254 case TOGGLE_WIFI:
1255 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
1256 break;
1257 case TOUCH_HUD_CLEAR:
1258 HandleTouchHudClear();
1259 break;
1260 case TOUCH_HUD_MODE_CHANGE:
1261 HandleTouchHudModeChange();
1262 break;
1263 case TOUCH_HUD_PROJECTION_TOGGLE:
1264 accelerators::ToggleTouchHudProjection();
1265 break;
1266 case VOLUME_DOWN:
1267 HandleVolumeDown(accelerator);
1268 break;
1269 case VOLUME_MUTE:
1270 HandleVolumeMute(accelerator);
1271 break;
1272 case VOLUME_UP:
1273 HandleVolumeUp(accelerator);
1274 break;
1275 #else
1276 case DUMMY_FOR_RESERVED:
1277 NOTREACHED();
1278 break;
1279 #endif
1283 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1284 AcceleratorAction action) {
1285 #if defined(OS_CHROMEOS)
1286 if (action == SILENCE_SPOKEN_FEEDBACK)
1287 return false;
1288 #endif
1290 // Adding new exceptions is *STRONGLY* discouraged.
1291 return true;
1294 AcceleratorController::AcceleratorProcessingRestriction
1295 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1296 ash::Shell* shell = ash::Shell::GetInstance();
1297 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1298 actions_allowed_at_login_screen_.find(action) ==
1299 actions_allowed_at_login_screen_.end()) {
1300 return RESTRICTION_PREVENT_PROCESSING;
1302 if (shell->session_state_delegate()->IsScreenLocked() &&
1303 actions_allowed_at_lock_screen_.find(action) ==
1304 actions_allowed_at_lock_screen_.end()) {
1305 return RESTRICTION_PREVENT_PROCESSING;
1307 if (shell->delegate()->IsRunningInForcedAppMode() &&
1308 actions_allowed_in_app_mode_.find(action) ==
1309 actions_allowed_in_app_mode_.end()) {
1310 return RESTRICTION_PREVENT_PROCESSING;
1312 if (shell->IsSystemModalWindowOpen() &&
1313 actions_allowed_at_modal_window_.find(action) ==
1314 actions_allowed_at_modal_window_.end()) {
1315 // Note we prevent the shortcut from propagating so it will not
1316 // be passed to the modal window. This is important for things like
1317 // Alt+Tab that would cause an undesired effect in the modal window by
1318 // cycling through its window elements.
1319 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1321 if (shell->mru_window_tracker()->BuildMruWindowList().empty() &&
1322 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1323 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1324 ui::A11Y_ALERT_WINDOW_NEEDED);
1325 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1327 return RESTRICTION_NONE;
1330 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1331 scoped_ptr<KeyboardBrightnessControlDelegate>
1332 keyboard_brightness_control_delegate) {
1333 keyboard_brightness_control_delegate_ =
1334 keyboard_brightness_control_delegate.Pass();
1337 } // namespace ash