Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller.cc
blob77c3ed2a560cf0d7f53f13162c93b1a60ab9e857
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/system_notifier.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/histogram_macros.h"
58 #include "base/metrics/user_metrics.h"
59 #include "ui/aura/env.h"
60 #include "ui/base/accelerators/accelerator.h"
61 #include "ui/base/accelerators/accelerator_manager.h"
62 #include "ui/base/l10n/l10n_util.h"
63 #include "ui/base/resource/resource_bundle.h"
64 #include "ui/compositor/layer.h"
65 #include "ui/compositor/layer_animation_sequence.h"
66 #include "ui/compositor/layer_animator.h"
67 #include "ui/events/event.h"
68 #include "ui/events/keycodes/keyboard_codes.h"
69 #include "ui/gfx/screen.h"
70 #include "ui/message_center/message_center.h"
71 #include "ui/message_center/notification.h"
72 #include "ui/message_center/notifier_settings.h"
73 #include "ui/views/controls/webview/webview.h"
75 #if defined(OS_CHROMEOS)
76 #include "ash/system/chromeos/keyboard_brightness_controller.h"
77 #include "base/sys_info.h"
78 #include "ui/base/ime/chromeos/ime_keyboard.h"
79 #include "ui/base/ime/chromeos/input_method_manager.h"
80 #endif // defined(OS_CHROMEOS)
82 namespace ash {
83 namespace {
85 using base::UserMetricsAction;
87 // The notification delegate that will be used to open the keyboard shortcut
88 // help page when the notification is clicked.
89 class DeprecatedAcceleratorNotificationDelegate
90 : public message_center::NotificationDelegate {
91 public:
92 DeprecatedAcceleratorNotificationDelegate() {}
94 // message_center::NotificationDelegate:
95 bool HasClickedListener() override { return true; }
97 void Click() override {
98 if (!Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked())
99 Shell::GetInstance()->delegate()->OpenKeyboardShortcutHelpPage();
102 private:
103 // Private destructor since NotificationDelegate is ref-counted.
104 ~DeprecatedAcceleratorNotificationDelegate() override {}
106 DISALLOW_COPY_AND_ASSIGN(DeprecatedAcceleratorNotificationDelegate);
109 ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode,
110 int modifiers,
111 bool trigger_on_press) {
112 ui::Accelerator accelerator(keycode, modifiers);
113 accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED
114 : ui::ET_KEY_RELEASED);
115 return accelerator;
118 void ShowDeprecatedAcceleratorNotification(const char* const notification_id,
119 int message_id) {
120 const base::string16 message = l10n_util::GetStringUTF16(message_id);
121 scoped_ptr<message_center::Notification> notification(
122 new message_center::Notification(
123 message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
124 base::string16(), message,
125 Shell::GetInstance()->delegate()->GetDeprecatedAcceleratorImage(),
126 base::string16(), GURL(),
127 message_center::NotifierId(
128 message_center::NotifierId::SYSTEM_COMPONENT,
129 system_notifier::kNotifierDeprecatedAccelerator),
130 message_center::RichNotificationData(),
131 new DeprecatedAcceleratorNotificationDelegate));
132 message_center::MessageCenter::Get()->AddNotification(notification.Pass());
135 void RecordUmaHistogram(const char* histogram_name,
136 DeprecatedAcceleratorUsage sample) {
137 auto histogram = base::LinearHistogram::FactoryGet(
138 histogram_name, 1, DEPRECATED_USAGE_COUNT, DEPRECATED_USAGE_COUNT + 1,
139 base::HistogramBase::kUmaTargetedHistogramFlag);
140 histogram->Add(sample);
143 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
144 if (accelerator.key_code() == ui::VKEY_TAB)
145 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
147 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
148 WindowCycleController::BACKWARD);
151 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
152 if (accelerator.key_code() == ui::VKEY_TAB)
153 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
155 Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
156 WindowCycleController::FORWARD);
159 void HandleRotatePaneFocus(Shell::Direction direction) {
160 Shell* shell = Shell::GetInstance();
161 switch (direction) {
162 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
163 case Shell::FORWARD: {
164 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
165 shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
166 break;
168 case Shell::BACKWARD: {
169 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
170 shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
171 break;
176 void HandleFocusShelf() {
177 Shell* shell = Shell::GetInstance();
178 base::RecordAction(base::UserMetricsAction("Accel_Focus_Shelf"));
179 shell->focus_cycler()->FocusWidget(
180 Shelf::ForPrimaryDisplay()->shelf_widget());
183 void HandleLaunchAppN(int n) {
184 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
185 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
188 void HandleLaunchLastApp() {
189 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
190 Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
193 bool CanHandleMagnifyScreen() {
194 Shell* shell = Shell::GetInstance();
195 return shell->magnification_controller()->IsEnabled() ||
196 shell->partial_magnification_controller()->is_enabled();
199 // Magnify the screen
200 void HandleMagnifyScreen(int delta_index) {
201 if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
202 // TODO(yoshiki): Move the following logic to MagnificationController.
203 float scale =
204 ash::Shell::GetInstance()->magnification_controller()->GetScale();
205 // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
206 int scale_index = std::floor(
207 std::log(scale) / std::log(ui::kMagnificationScaleFactor) + 0.5);
209 int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
211 ash::Shell::GetInstance()->magnification_controller()->SetScale(
212 std::pow(ui::kMagnificationScaleFactor, new_scale_index), true);
213 } else if (ash::Shell::GetInstance()->
214 partial_magnification_controller()->is_enabled()) {
215 float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
216 ash::Shell::GetInstance()->partial_magnification_controller()->
217 SetScale(scale);
221 void HandleMediaNextTrack() {
222 Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
225 void HandleMediaPlayPause() {
226 Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
229 void HandleMediaPrevTrack() {
230 Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
233 bool CanHandleNewIncognitoWindow() {
234 return Shell::GetInstance()->delegate()->IsIncognitoAllowed();
237 void HandleNewIncognitoWindow() {
238 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
239 Shell::GetInstance()->new_window_delegate()->NewWindow(
240 true /* is_incognito */);
243 void HandleNewTab(const ui::Accelerator& accelerator) {
244 if (accelerator.key_code() == ui::VKEY_T)
245 base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
246 Shell::GetInstance()->new_window_delegate()->NewTab();
249 void HandleNewWindow() {
250 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
251 Shell::GetInstance()->new_window_delegate()->NewWindow(
252 false /* is_incognito */);
255 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
256 const ui::Accelerator& previous_accelerator) {
257 // This check is necessary e.g. not to process the Shift+Alt+
258 // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
259 // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
260 // is released.
261 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
262 if (previous_accelerator.type() == ui::ET_KEY_RELEASED &&
263 // Workaround for crbug.com/139556. CJK IME users tend to press
264 // Enter (or Space) and Shift+Alt almost at the same time to commit
265 // an IME string and then switch from the IME to the English layout.
266 // This workaround allows the user to trigger NEXT_IME even if the
267 // user presses Shift+Alt before releasing Enter.
268 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
269 previous_key_code != ui::VKEY_RETURN &&
270 previous_key_code != ui::VKEY_SPACE) {
271 // We totally ignore this accelerator.
272 // TODO(mazda): Fix crbug.com/158217
273 return false;
275 return ime_control_delegate && ime_control_delegate->CanCycleIme();
278 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
279 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
280 ime_control_delegate->HandleNextIme();
283 void HandleOpenFeedbackPage() {
284 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
285 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
288 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
289 return ime_control_delegate && ime_control_delegate->CanCycleIme();
292 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
293 const ui::Accelerator& accelerator) {
294 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
295 if (accelerator.type() == ui::ET_KEY_PRESSED)
296 ime_control_delegate->HandlePreviousIme();
297 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
300 void HandleRestoreTab() {
301 base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
302 Shell::GetInstance()->new_window_delegate()->RestoreTab();
305 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
306 switch (current) {
307 case gfx::Display::ROTATE_0:
308 return gfx::Display::ROTATE_90;
309 case gfx::Display::ROTATE_90:
310 return gfx::Display::ROTATE_180;
311 case gfx::Display::ROTATE_180:
312 return gfx::Display::ROTATE_270;
313 case gfx::Display::ROTATE_270:
314 return gfx::Display::ROTATE_0;
316 NOTREACHED() << "Unknown rotation:" << current;
317 return gfx::Display::ROTATE_0;
320 // Rotates the screen.
321 void HandleRotateScreen() {
322 if (Shell::GetInstance()->display_manager()->IsInUnifiedMode())
323 return;
325 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
326 gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
327 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
328 const DisplayInfo& display_info =
329 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
330 ash::ScreenRotationAnimator(display.id())
331 .Rotate(GetNextRotation(display_info.GetActiveRotation()),
332 gfx::Display::ROTATION_SOURCE_USER);
335 // Rotate the active window.
336 void HandleRotateActiveWindow() {
337 base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
338 aura::Window* active_window = wm::GetActiveWindow();
339 if (active_window) {
340 // The rotation animation bases its target transform on the current
341 // rotation and position. Since there could be an animation in progress
342 // right now, queue this animation so when it starts it picks up a neutral
343 // rotation and position. Use replace so we only enqueue one at a time.
344 active_window->layer()->GetAnimator()->
345 set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
346 active_window->layer()->GetAnimator()->StartAnimation(
347 new ui::LayerAnimationSequence(
348 new ash::WindowRotation(360, active_window->layer())));
352 void HandleShowKeyboardOverlay() {
353 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
354 ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
357 bool CanHandleShowMessageCenterBubble() {
358 RootWindowController* controller =
359 RootWindowController::ForTargetRootWindow();
360 StatusAreaWidget* status_area_widget =
361 controller->shelf()->status_area_widget();
362 return status_area_widget &&
363 status_area_widget->web_notification_tray()->visible();
366 void HandleShowMessageCenterBubble() {
367 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
368 RootWindowController* controller =
369 RootWindowController::ForTargetRootWindow();
370 StatusAreaWidget* status_area_widget =
371 controller->shelf()->status_area_widget();
372 if (status_area_widget) {
373 WebNotificationTray* notification_tray =
374 status_area_widget->web_notification_tray();
375 if (notification_tray->visible())
376 notification_tray->ShowMessageCenterBubble();
380 void HandleShowSystemTrayBubble() {
381 base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
382 RootWindowController* controller =
383 RootWindowController::ForTargetRootWindow();
384 if (!controller->GetSystemTray()->HasSystemBubble())
385 controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
388 void HandleShowTaskManager() {
389 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
390 Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
393 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
394 const ui::Accelerator& accelerator) {
395 return ime_control_delegate &&
396 ime_control_delegate->CanSwitchIme(accelerator);
399 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
400 const ui::Accelerator& accelerator) {
401 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
402 ime_control_delegate->HandleSwitchIme(accelerator);
405 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
406 base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
407 DCHECK(screenshot_delegate);
408 Shell::GetInstance()
409 ->partial_screenshot_controller()
410 ->StartPartialScreenshotSession(screenshot_delegate);
413 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
414 base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
415 DCHECK(screenshot_delegate);
416 if (screenshot_delegate->CanTakeScreenshot())
417 screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
420 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
421 const ui::Accelerator& previous_accelerator) {
422 if (accelerator.key_code() == ui::VKEY_LWIN) {
423 // If something else was pressed between the Search key (LWIN)
424 // being pressed and released, then ignore the release of the
425 // Search key.
426 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
427 previous_accelerator.key_code() != ui::VKEY_LWIN) {
428 return false;
431 // When spoken feedback is enabled, we should neither toggle the list nor
432 // consume the key since Search+Shift is one of the shortcuts the a11y
433 // feature uses. crbug.com/132296
434 if (Shell::GetInstance()
435 ->accessibility_delegate()
436 ->IsSpokenFeedbackEnabled()) {
437 return false;
440 return true;
443 void HandleToggleAppList(const ui::Accelerator& accelerator) {
444 if (accelerator.key_code() == ui::VKEY_LWIN)
445 base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
446 ash::Shell::GetInstance()->ToggleAppList(NULL);
449 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
450 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
451 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
452 accelerators::ToggleFullscreen();
455 void HandleToggleOverview() {
456 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
457 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
460 bool CanHandleWindowSnapOrDock() {
461 wm::WindowState* window_state = wm::GetActiveWindowState();
462 // Disable window snapping shortcut key for full screen window due to
463 // http://crbug.com/135487.
464 return (window_state && window_state->IsUserPositionable() &&
465 !window_state->IsFullscreen());
468 void HandleWindowSnapOrDock(AcceleratorAction action) {
469 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
470 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
471 else
472 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
474 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT ?
475 wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT :
476 wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
477 wm::GetActiveWindowState()->OnWMEvent(&event);
480 void HandleWindowMinimize() {
481 base::RecordAction(
482 base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
483 accelerators::ToggleMinimized();
486 bool CanHandlePositionCenter() {
487 // Docked windows do not support centering.
488 wm::WindowState* window_state = wm::GetActiveWindowState();
489 return (window_state && !window_state->IsDocked());
492 void HandlePositionCenter() {
493 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
494 wm::CenterWindow(wm::GetActiveWindow());
497 #if defined(OS_CHROMEOS)
498 void HandleBrightnessDown(BrightnessControlDelegate* delegate,
499 const ui::Accelerator& accelerator) {
500 if (delegate)
501 delegate->HandleBrightnessDown(accelerator);
504 void HandleBrightnessUp(BrightnessControlDelegate* delegate,
505 const ui::Accelerator& accelerator) {
506 if (delegate)
507 delegate->HandleBrightnessUp(accelerator);
510 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
511 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
512 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
513 (previous_key_code != ui::VKEY_LSHIFT &&
514 previous_key_code != ui::VKEY_SHIFT &&
515 previous_key_code != ui::VKEY_RSHIFT)) {
516 // If something else was pressed between the Shift key being pressed
517 // and released, then ignore the release of the Shift key.
518 return false;
520 chromeos::input_method::InputMethodManager* ime =
521 chromeos::input_method::InputMethodManager::Get();
522 chromeos::input_method::ImeKeyboard* keyboard =
523 ime ? ime->GetImeKeyboard() : NULL;
524 return (keyboard && keyboard->CapsLockIsEnabled());
527 void HandleDisableCapsLock() {
528 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
529 chromeos::input_method::InputMethodManager* ime =
530 chromeos::input_method::InputMethodManager::Get();
531 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
534 void HandleKeyboardBrightnessDown(KeyboardBrightnessControlDelegate* delegate,
535 const ui::Accelerator& accelerator) {
536 if (delegate)
537 delegate->HandleKeyboardBrightnessDown(accelerator);
540 void HandleKeyboardBrightnessUp(KeyboardBrightnessControlDelegate* delegate,
541 const ui::Accelerator& accelerator) {
542 if (delegate)
543 delegate->HandleKeyboardBrightnessUp(accelerator);
546 bool CanHandleLock() {
547 return Shell::GetInstance()->session_state_delegate()->CanLockScreen();
550 void HandleLock() {
551 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
552 Shell::GetInstance()->session_state_delegate()->LockScreen();
555 void HandleCrosh() {
556 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
558 Shell::GetInstance()->new_window_delegate()->OpenCrosh();
561 void HandleFileManager() {
562 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
564 Shell::GetInstance()->new_window_delegate()->OpenFileManager();
567 void HandleGetHelp() {
568 Shell::GetInstance()->new_window_delegate()->OpenGetHelp();
571 bool CanHandleSilenceSpokenFeedback() {
572 AccessibilityDelegate* delegate =
573 Shell::GetInstance()->accessibility_delegate();
574 return delegate->IsSpokenFeedbackEnabled();
577 void HandleSilenceSpokenFeedback() {
578 base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
579 Shell::GetInstance()->accessibility_delegate()->SilenceSpokenFeedback();
582 void HandleSwapPrimaryDisplay() {
583 base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
584 Shell::GetInstance()->window_tree_host_manager()->SwapPrimaryDisplay();
587 bool CanHandleCycleUser() {
588 Shell* shell = Shell::GetInstance();
589 return shell->delegate()->IsMultiProfilesEnabled() &&
590 shell->session_state_delegate()->NumberOfLoggedInUsers() > 1;
593 void HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
594 MultiProfileUMA::RecordSwitchActiveUser(
595 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
596 switch (cycle_user) {
597 case SessionStateDelegate::CYCLE_TO_NEXT_USER:
598 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
599 break;
600 case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
601 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
602 break;
604 Shell::GetInstance()->session_state_delegate()->CycleActiveUser(cycle_user);
607 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
608 const ui::Accelerator& previous_accelerator) {
609 if (accelerator.key_code() == ui::VKEY_LWIN) {
610 // If something else was pressed between the Search key (LWIN)
611 // being pressed and released, then ignore the release of the
612 // Search key.
613 // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
614 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
615 previous_accelerator.key_code() != ui::VKEY_LWIN)
616 return false;
618 chromeos::input_method::InputMethodManager* ime =
619 chromeos::input_method::InputMethodManager::Get();
620 return ime && ime->GetImeKeyboard();
623 void HandleToggleCapsLock() {
624 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
625 chromeos::input_method::InputMethodManager* ime =
626 chromeos::input_method::InputMethodManager::Get();
627 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
628 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
631 void HandleToggleMirrorMode() {
632 base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
633 Shell::GetInstance()->window_tree_host_manager()->ToggleMirrorMode();
636 void HandleToggleSpokenFeedback() {
637 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
639 Shell::GetInstance()->accessibility_delegate()->
640 ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_SHOW);
643 bool CanHandleToggleTouchViewTesting() {
644 return base::CommandLine::ForCurrentProcess()->HasSwitch(
645 switches::kAshEnableTouchViewTesting);
648 void HandleToggleTouchViewTesting() {
649 // TODO(skuhne): This is only temporary! Remove this!
650 MaximizeModeController* controller = Shell::GetInstance()->
651 maximize_mode_controller();
652 controller->EnableMaximizeModeWindowManager(
653 !controller->IsMaximizeModeWindowManagerEnabled());
656 bool CanHandleTouchHud() {
657 return RootWindowController::ForTargetRootWindow()->touch_hud_debug();
660 void HandleTouchHudClear() {
661 RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear();
664 void HandleTouchHudModeChange() {
665 RootWindowController* controller =
666 RootWindowController::ForTargetRootWindow();
667 controller->touch_hud_debug()->ChangeToNextMode();
670 void HandleVolumeDown(const ui::Accelerator& accelerator) {
671 VolumeControlDelegate* volume_delegate =
672 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
673 if (volume_delegate)
674 volume_delegate->HandleVolumeDown(accelerator);
677 void HandleVolumeMute(const ui::Accelerator& accelerator) {
678 VolumeControlDelegate* volume_delegate =
679 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
680 if (volume_delegate)
681 volume_delegate->HandleVolumeMute(accelerator);
684 void HandleVolumeUp(const ui::Accelerator& accelerator) {
685 VolumeControlDelegate* volume_delegate =
686 Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate();
687 if (volume_delegate)
688 volume_delegate->HandleVolumeUp(accelerator);
691 #endif // defined(OS_CHROMEOS)
693 } // namespace
695 ////////////////////////////////////////////////////////////////////////////////
696 // AcceleratorController, public:
698 AcceleratorController::AcceleratorController()
699 : accelerator_manager_(new ui::AcceleratorManager),
700 accelerator_history_(new ui::AcceleratorHistory) {
701 Init();
704 AcceleratorController::~AcceleratorController() {
707 void AcceleratorController::Register(const ui::Accelerator& accelerator,
708 ui::AcceleratorTarget* target) {
709 accelerator_manager_->Register(accelerator,
710 ui::AcceleratorManager::kNormalPriority,
711 target);
714 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
715 ui::AcceleratorTarget* target) {
716 accelerator_manager_->Unregister(accelerator, target);
719 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
720 accelerator_manager_->UnregisterAll(target);
723 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
724 if (ime_control_delegate_) {
725 return accelerator_manager_->Process(
726 ime_control_delegate_->RemapAccelerator(accelerator));
728 return accelerator_manager_->Process(accelerator);
731 bool AcceleratorController::IsRegistered(
732 const ui::Accelerator& accelerator) const {
733 return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
736 bool AcceleratorController::IsPreferred(
737 const ui::Accelerator& accelerator) const {
738 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
739 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
741 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
742 accelerators_.find(remapped_accelerator);
743 if (iter == accelerators_.end())
744 return false; // not an accelerator.
746 return preferred_actions_.find(iter->second) != preferred_actions_.end();
749 bool AcceleratorController::IsReserved(
750 const ui::Accelerator& accelerator) const {
751 const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
752 ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
754 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
755 accelerators_.find(remapped_accelerator);
756 if (iter == accelerators_.end())
757 return false; // not an accelerator.
759 return reserved_actions_.find(iter->second) != reserved_actions_.end();
762 bool AcceleratorController::IsDeprecated(
763 const ui::Accelerator& accelerator) const {
764 return deprecated_accelerators_.count(accelerator) != 0;
767 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
768 if (CanPerformAction(action, ui::Accelerator())) {
769 PerformAction(action, ui::Accelerator());
770 return true;
772 return false;
775 AcceleratorController::AcceleratorProcessingRestriction
776 AcceleratorController::GetCurrentAcceleratorRestriction() {
777 return GetAcceleratorProcessingRestriction(-1);
780 void AcceleratorController::SetBrightnessControlDelegate(
781 scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
782 brightness_control_delegate_ = brightness_control_delegate.Pass();
785 void AcceleratorController::SetImeControlDelegate(
786 scoped_ptr<ImeControlDelegate> ime_control_delegate) {
787 ime_control_delegate_ = ime_control_delegate.Pass();
790 void AcceleratorController::SetScreenshotDelegate(
791 scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
792 screenshot_delegate_ = screenshot_delegate.Pass();
795 bool AcceleratorController::ShouldCloseMenuAndRepostAccelerator(
796 const ui::Accelerator& accelerator) const {
797 auto itr = accelerators_.find(accelerator);
798 if (itr == accelerators_.end())
799 return false; // Menu shouldn't be closed for an invalid accelerator.
801 AcceleratorAction action = itr->second;
802 return actions_keeping_menu_open_.count(action) == 0;
805 ////////////////////////////////////////////////////////////////////////////////
806 // AcceleratorController, ui::AcceleratorTarget implementation:
808 bool AcceleratorController::AcceleratorPressed(
809 const ui::Accelerator& accelerator) {
810 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
811 accelerators_.find(accelerator);
812 DCHECK(it != accelerators_.end());
813 AcceleratorAction action = it->second;
814 if (CanPerformAction(action, accelerator)) {
815 // Handling the deprecated accelerators (if any) only if action can be
816 // performed.
817 auto itr = actions_with_deprecations_.find(action);
818 if (itr != actions_with_deprecations_.end()) {
819 const DeprecatedAcceleratorData* data = itr->second;
820 if (deprecated_accelerators_.count(accelerator)) {
821 // This accelerator has been deprecated and should be treated according
822 // to its |DeprecatedAcceleratorData|.
824 // Record UMA stats.
825 RecordUmaHistogram(data->uma_histogram_name, DEPRECATED_USED);
827 // We always display the notification as long as this entry exists.
828 ShowDeprecatedAcceleratorNotification(data->uma_histogram_name,
829 data->notification_message_id);
831 if (!data->deprecated_enabled)
832 return false;
833 } else {
834 // This is a new accelerator replacing the old deprecated one.
835 // Record UMA stats and proceed normally.
836 RecordUmaHistogram(data->uma_histogram_name, NEW_USED);
840 PerformAction(action, accelerator);
841 return ShouldActionConsumeKeyEvent(action);
843 return false;
846 bool AcceleratorController::CanHandleAccelerators() const {
847 return true;
850 ///////////////////////////////////////////////////////////////////////////////
851 // AcceleratorController, private:
853 void AcceleratorController::Init() {
854 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
855 actions_allowed_at_login_screen_.insert(
856 kActionsAllowedAtLoginOrLockScreen[i]);
857 actions_allowed_at_lock_screen_.insert(
858 kActionsAllowedAtLoginOrLockScreen[i]);
860 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
861 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
862 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
863 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
864 for (size_t i = 0; i < kPreferredActionsLength; ++i)
865 preferred_actions_.insert(kPreferredActions[i]);
866 for (size_t i = 0; i < kReservedActionsLength; ++i)
867 reserved_actions_.insert(kReservedActions[i]);
868 for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
869 nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
870 for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
871 actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
872 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
873 actions_needing_window_.insert(kActionsNeedingWindow[i]);
874 for (size_t i = 0; i < kActionsKeepingMenuOpenLength; ++i)
875 actions_keeping_menu_open_.insert(kActionsKeepingMenuOpen[i]);
877 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
879 RegisterDeprecatedAccelerators();
881 if (debug::DebugAcceleratorsEnabled()) {
882 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
883 // All debug accelerators are reserved.
884 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
885 reserved_actions_.insert(kDebugAcceleratorData[i].action);
888 #if defined(OS_CHROMEOS)
889 keyboard_brightness_control_delegate_.reset(
890 new KeyboardBrightnessController());
891 #endif
894 void AcceleratorController::RegisterAccelerators(
895 const AcceleratorData accelerators[],
896 size_t accelerators_length) {
897 for (size_t i = 0; i < accelerators_length; ++i) {
898 ui::Accelerator accelerator =
899 CreateAccelerator(accelerators[i].keycode, accelerators[i].modifiers,
900 accelerators[i].trigger_on_press);
901 Register(accelerator, this);
902 accelerators_.insert(
903 std::make_pair(accelerator, accelerators[i].action));
907 void AcceleratorController::RegisterDeprecatedAccelerators() {
908 #if defined(OS_CHROMEOS)
909 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) {
910 const DeprecatedAcceleratorData* data = &kDeprecatedAccelerators[i];
911 const AcceleratorAction action = data->deprecated_accelerator.action;
912 const ui::Accelerator deprecated_accelerator =
913 CreateAccelerator(data->deprecated_accelerator.keycode,
914 data->deprecated_accelerator.modifiers,
915 data->deprecated_accelerator.trigger_on_press);
917 Register(deprecated_accelerator, this);
918 actions_with_deprecations_[action] = data;
919 accelerators_[deprecated_accelerator] = action;
920 deprecated_accelerators_.insert(deprecated_accelerator);
922 #endif // defined(OS_CHROMEOS)
925 bool AcceleratorController::CanPerformAction(
926 AcceleratorAction action,
927 const ui::Accelerator& accelerator) {
928 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
929 accelerator.IsRepeat()) {
930 return false;
933 AcceleratorProcessingRestriction restriction =
934 GetAcceleratorProcessingRestriction(action);
935 if (restriction != RESTRICTION_NONE)
936 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
938 const ui::Accelerator& previous_accelerator =
939 accelerator_history_->previous_accelerator();
941 // True should be returned if running |action| does something. Otherwise,
942 // false should be returned to give the web contents a chance at handling the
943 // accelerator.
944 switch (action) {
945 case DEBUG_PRINT_LAYER_HIERARCHY:
946 case DEBUG_PRINT_VIEW_HIERARCHY:
947 case DEBUG_PRINT_WINDOW_HIERARCHY:
948 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
949 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
950 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
951 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
952 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
953 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
954 return debug::DebugAcceleratorsEnabled();
955 case MAGNIFY_SCREEN_ZOOM_IN:
956 case MAGNIFY_SCREEN_ZOOM_OUT:
957 return CanHandleMagnifyScreen();
958 case NEW_INCOGNITO_WINDOW:
959 return CanHandleNewIncognitoWindow();
960 case NEXT_IME:
961 return CanHandleNextIme(ime_control_delegate_.get(),
962 previous_accelerator);
963 case PREVIOUS_IME:
964 return CanHandlePreviousIme(ime_control_delegate_.get());
965 case SCALE_UI_RESET:
966 case SCALE_UI_UP:
967 case SCALE_UI_DOWN:
968 return accelerators::IsInternalDisplayZoomEnabled();
969 case SHOW_MESSAGE_CENTER_BUBBLE:
970 return CanHandleShowMessageCenterBubble();
971 case SWITCH_IME:
972 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
973 case TOGGLE_APP_LIST:
974 return CanHandleToggleAppList(accelerator, previous_accelerator);
975 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
976 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
977 return CanHandleWindowSnapOrDock();
978 case WINDOW_POSITION_CENTER:
979 return CanHandlePositionCenter();
980 #if defined(OS_CHROMEOS)
981 case DEBUG_ADD_REMOVE_DISPLAY:
982 case DEBUG_TOGGLE_UNIFIED_DESKTOP:
983 return debug::DebugAcceleratorsEnabled();
984 case DISABLE_CAPS_LOCK:
985 return CanHandleDisableCapsLock(previous_accelerator);
986 case LOCK_SCREEN:
987 return CanHandleLock();
988 case SILENCE_SPOKEN_FEEDBACK:
989 return CanHandleSilenceSpokenFeedback();
990 case SWITCH_TO_PREVIOUS_USER:
991 case SWITCH_TO_NEXT_USER:
992 return CanHandleCycleUser();
993 case TOGGLE_CAPS_LOCK:
994 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
995 case TOGGLE_TOUCH_VIEW_TESTING:
996 return CanHandleToggleTouchViewTesting();
997 case TOUCH_HUD_CLEAR:
998 case TOUCH_HUD_MODE_CHANGE:
999 return CanHandleTouchHud();
1000 #endif
1002 case CYCLE_BACKWARD_MRU:
1003 case CYCLE_FORWARD_MRU:
1004 case EXIT:
1005 case FOCUS_NEXT_PANE:
1006 case FOCUS_PREVIOUS_PANE:
1007 case FOCUS_SHELF:
1008 case LAUNCH_APP_0:
1009 case LAUNCH_APP_1:
1010 case LAUNCH_APP_2:
1011 case LAUNCH_APP_3:
1012 case LAUNCH_APP_4:
1013 case LAUNCH_APP_5:
1014 case LAUNCH_APP_6:
1015 case LAUNCH_APP_7:
1016 case LAUNCH_LAST_APP:
1017 case MEDIA_NEXT_TRACK:
1018 case MEDIA_PLAY_PAUSE:
1019 case MEDIA_PREV_TRACK:
1020 case NEW_TAB:
1021 case NEW_WINDOW:
1022 case OPEN_FEEDBACK_PAGE:
1023 case PRINT_UI_HIERARCHIES:
1024 case RESTORE_TAB:
1025 case ROTATE_SCREEN:
1026 case ROTATE_WINDOW:
1027 case SHOW_KEYBOARD_OVERLAY:
1028 case SHOW_SYSTEM_TRAY_BUBBLE:
1029 case SHOW_TASK_MANAGER:
1030 case TAKE_PARTIAL_SCREENSHOT:
1031 case TAKE_SCREENSHOT:
1032 case TOGGLE_FULLSCREEN:
1033 case TOGGLE_MAXIMIZED:
1034 case TOGGLE_OVERVIEW:
1035 case WINDOW_MINIMIZE:
1036 #if defined(OS_CHROMEOS)
1037 case BRIGHTNESS_DOWN:
1038 case BRIGHTNESS_UP:
1039 case DISABLE_GPU_WATCHDOG:
1040 case KEYBOARD_BRIGHTNESS_DOWN:
1041 case KEYBOARD_BRIGHTNESS_UP:
1042 case LOCK_PRESSED:
1043 case LOCK_RELEASED:
1044 case OPEN_CROSH:
1045 case OPEN_FILE_MANAGER:
1046 case OPEN_GET_HELP:
1047 case POWER_PRESSED:
1048 case POWER_RELEASED:
1049 case SWAP_PRIMARY_DISPLAY:
1050 case TOGGLE_MIRROR_MODE:
1051 case TOGGLE_SPOKEN_FEEDBACK:
1052 case TOGGLE_WIFI:
1053 case TOUCH_HUD_PROJECTION_TOGGLE:
1054 case VOLUME_DOWN:
1055 case VOLUME_MUTE:
1056 case VOLUME_UP:
1057 #else
1058 case DUMMY_FOR_RESERVED:
1059 #endif
1060 return true;
1062 return false;
1065 void AcceleratorController::PerformAction(AcceleratorAction action,
1066 const ui::Accelerator& accelerator) {
1067 AcceleratorProcessingRestriction restriction =
1068 GetAcceleratorProcessingRestriction(action);
1069 if (restriction != RESTRICTION_NONE)
1070 return;
1072 // If your accelerator invokes more than one line of code, please either
1073 // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
1074 // below) or pull it into a HandleFoo() function above.
1075 switch (action) {
1076 case CYCLE_BACKWARD_MRU:
1077 HandleCycleBackwardMRU(accelerator);
1078 break;
1079 case CYCLE_FORWARD_MRU:
1080 HandleCycleForwardMRU(accelerator);
1081 break;
1082 case DEBUG_PRINT_LAYER_HIERARCHY:
1083 case DEBUG_PRINT_VIEW_HIERARCHY:
1084 case DEBUG_PRINT_WINDOW_HIERARCHY:
1085 case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
1086 case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
1087 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
1088 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
1089 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
1090 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
1091 debug::PerformDebugActionIfEnabled(action);
1092 break;
1093 case EXIT:
1094 // UMA metrics are recorded in the handler.
1095 exit_warning_handler_.HandleAccelerator();
1096 break;
1097 case FOCUS_NEXT_PANE:
1098 HandleRotatePaneFocus(Shell::FORWARD);
1099 break;
1100 case FOCUS_PREVIOUS_PANE:
1101 HandleRotatePaneFocus(Shell::BACKWARD);
1102 break;
1103 case FOCUS_SHELF:
1104 HandleFocusShelf();
1105 break;
1106 case LAUNCH_APP_0:
1107 HandleLaunchAppN(0);
1108 break;
1109 case LAUNCH_APP_1:
1110 HandleLaunchAppN(1);
1111 break;
1112 case LAUNCH_APP_2:
1113 HandleLaunchAppN(2);
1114 break;
1115 case LAUNCH_APP_3:
1116 HandleLaunchAppN(3);
1117 break;
1118 case LAUNCH_APP_4:
1119 HandleLaunchAppN(4);
1120 break;
1121 case LAUNCH_APP_5:
1122 HandleLaunchAppN(5);
1123 break;
1124 case LAUNCH_APP_6:
1125 HandleLaunchAppN(6);
1126 break;
1127 case LAUNCH_APP_7:
1128 HandleLaunchAppN(7);
1129 break;
1130 case LAUNCH_LAST_APP:
1131 HandleLaunchLastApp();
1132 break;
1133 case MAGNIFY_SCREEN_ZOOM_IN:
1134 HandleMagnifyScreen(1);
1135 break;
1136 case MAGNIFY_SCREEN_ZOOM_OUT:
1137 HandleMagnifyScreen(-1);
1138 break;
1139 case MEDIA_NEXT_TRACK:
1140 HandleMediaNextTrack();
1141 break;
1142 case MEDIA_PLAY_PAUSE:
1143 HandleMediaPlayPause();
1144 break;
1145 case MEDIA_PREV_TRACK:
1146 HandleMediaPrevTrack();
1147 break;
1148 case NEW_INCOGNITO_WINDOW:
1149 HandleNewIncognitoWindow();
1150 break;
1151 case NEW_TAB:
1152 HandleNewTab(accelerator);
1153 break;
1154 case NEW_WINDOW:
1155 HandleNewWindow();
1156 break;
1157 case NEXT_IME:
1158 HandleNextIme(ime_control_delegate_.get());
1159 break;
1160 case OPEN_FEEDBACK_PAGE:
1161 HandleOpenFeedbackPage();
1162 break;
1163 case PREVIOUS_IME:
1164 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
1165 break;
1166 case PRINT_UI_HIERARCHIES:
1167 debug::PrintUIHierarchies();
1168 break;
1169 case RESTORE_TAB:
1170 HandleRestoreTab();
1171 break;
1172 case ROTATE_SCREEN:
1173 HandleRotateScreen();
1174 break;
1175 case ROTATE_WINDOW:
1176 HandleRotateActiveWindow();
1177 break;
1178 case SCALE_UI_DOWN:
1179 accelerators::ZoomInternalDisplay(false /* down */);
1180 break;
1181 case SCALE_UI_RESET:
1182 accelerators::ResetInternalDisplayZoom();
1183 break;
1184 case SCALE_UI_UP:
1185 accelerators::ZoomInternalDisplay(true /* up */);
1186 break;
1187 case SHOW_KEYBOARD_OVERLAY:
1188 HandleShowKeyboardOverlay();
1189 break;
1190 case SHOW_MESSAGE_CENTER_BUBBLE:
1191 HandleShowMessageCenterBubble();
1192 break;
1193 case SHOW_SYSTEM_TRAY_BUBBLE:
1194 HandleShowSystemTrayBubble();
1195 break;
1196 case SHOW_TASK_MANAGER:
1197 HandleShowTaskManager();
1198 break;
1199 case SWITCH_IME:
1200 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1201 break;
1202 case TAKE_PARTIAL_SCREENSHOT:
1203 HandleTakePartialScreenshot(screenshot_delegate_.get());
1204 break;
1205 case TAKE_SCREENSHOT:
1206 HandleTakeScreenshot(screenshot_delegate_.get());
1207 break;
1208 case TOGGLE_APP_LIST:
1209 HandleToggleAppList(accelerator);
1210 break;
1211 case TOGGLE_FULLSCREEN:
1212 HandleToggleFullscreen(accelerator);
1213 break;
1214 case TOGGLE_MAXIMIZED:
1215 accelerators::ToggleMaximized();
1216 break;
1217 case TOGGLE_OVERVIEW:
1218 HandleToggleOverview();
1219 break;
1220 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1221 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1222 HandleWindowSnapOrDock(action);
1223 break;
1224 case WINDOW_MINIMIZE:
1225 HandleWindowMinimize();
1226 break;
1227 case WINDOW_POSITION_CENTER:
1228 HandlePositionCenter();
1229 break;
1230 #if defined(OS_CHROMEOS)
1231 case BRIGHTNESS_DOWN:
1232 HandleBrightnessDown(brightness_control_delegate_.get(), accelerator);
1233 break;
1234 case BRIGHTNESS_UP:
1235 HandleBrightnessUp(brightness_control_delegate_.get(), accelerator);
1236 break;
1237 case DEBUG_ADD_REMOVE_DISPLAY:
1238 debug::PerformDebugActionIfEnabled(action);
1239 break;
1240 case DEBUG_TOGGLE_UNIFIED_DESKTOP:
1241 debug::PerformDebugActionIfEnabled(action);
1242 break;
1243 case DISABLE_CAPS_LOCK:
1244 HandleDisableCapsLock();
1245 break;
1246 case DISABLE_GPU_WATCHDOG:
1247 Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
1248 break;
1249 case KEYBOARD_BRIGHTNESS_DOWN:
1250 HandleKeyboardBrightnessDown(keyboard_brightness_control_delegate_.get(),
1251 accelerator);
1252 break;
1253 case KEYBOARD_BRIGHTNESS_UP:
1254 HandleKeyboardBrightnessUp(keyboard_brightness_control_delegate_.get(),
1255 accelerator);
1256 break;
1257 case LOCK_PRESSED:
1258 case LOCK_RELEASED:
1259 Shell::GetInstance()->power_button_controller()->
1260 OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
1261 break;
1262 case LOCK_SCREEN:
1263 HandleLock();
1264 break;
1265 case OPEN_CROSH:
1266 HandleCrosh();
1267 break;
1268 case OPEN_FILE_MANAGER:
1269 HandleFileManager();
1270 break;
1271 case OPEN_GET_HELP:
1272 HandleGetHelp();
1273 break;
1274 case POWER_PRESSED: // fallthrough
1275 case POWER_RELEASED:
1276 if (!base::SysInfo::IsRunningOnChromeOS()) {
1277 // There is no powerd, the Chrome OS power manager, in linux desktop,
1278 // so call the PowerButtonController here.
1279 Shell::GetInstance()->power_button_controller()->
1280 OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
1282 // We don't do anything with these at present on the device,
1283 // (power button events are reported to us from powerm via
1284 // D-BUS), but we consume them to prevent them from getting
1285 // passed to apps -- see http://crbug.com/146609.
1286 break;
1287 case SILENCE_SPOKEN_FEEDBACK:
1288 HandleSilenceSpokenFeedback();
1289 break;
1290 case SWAP_PRIMARY_DISPLAY:
1291 HandleSwapPrimaryDisplay();
1292 break;
1293 case SWITCH_TO_NEXT_USER:
1294 HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
1295 break;
1296 case SWITCH_TO_PREVIOUS_USER:
1297 HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
1298 break;
1299 case TOGGLE_CAPS_LOCK:
1300 HandleToggleCapsLock();
1301 break;
1302 case TOGGLE_MIRROR_MODE:
1303 HandleToggleMirrorMode();
1304 break;
1305 case TOGGLE_SPOKEN_FEEDBACK:
1306 HandleToggleSpokenFeedback();
1307 break;
1308 case TOGGLE_TOUCH_VIEW_TESTING:
1309 HandleToggleTouchViewTesting();
1310 break;
1311 case TOGGLE_WIFI:
1312 Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
1313 break;
1314 case TOUCH_HUD_CLEAR:
1315 HandleTouchHudClear();
1316 break;
1317 case TOUCH_HUD_MODE_CHANGE:
1318 HandleTouchHudModeChange();
1319 break;
1320 case TOUCH_HUD_PROJECTION_TOGGLE:
1321 accelerators::ToggleTouchHudProjection();
1322 break;
1323 case VOLUME_DOWN:
1324 HandleVolumeDown(accelerator);
1325 break;
1326 case VOLUME_MUTE:
1327 HandleVolumeMute(accelerator);
1328 break;
1329 case VOLUME_UP:
1330 HandleVolumeUp(accelerator);
1331 break;
1332 #else
1333 case DUMMY_FOR_RESERVED:
1334 NOTREACHED();
1335 break;
1336 #endif
1340 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1341 AcceleratorAction action) {
1342 #if defined(OS_CHROMEOS)
1343 if (action == SILENCE_SPOKEN_FEEDBACK)
1344 return false;
1345 #endif
1347 // Adding new exceptions is *STRONGLY* discouraged.
1348 return true;
1351 AcceleratorController::AcceleratorProcessingRestriction
1352 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1353 ash::Shell* shell = ash::Shell::GetInstance();
1354 if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
1355 actions_allowed_at_login_screen_.find(action) ==
1356 actions_allowed_at_login_screen_.end()) {
1357 return RESTRICTION_PREVENT_PROCESSING;
1359 if (shell->session_state_delegate()->IsScreenLocked() &&
1360 actions_allowed_at_lock_screen_.find(action) ==
1361 actions_allowed_at_lock_screen_.end()) {
1362 return RESTRICTION_PREVENT_PROCESSING;
1364 if (shell->delegate()->IsRunningInForcedAppMode() &&
1365 actions_allowed_in_app_mode_.find(action) ==
1366 actions_allowed_in_app_mode_.end()) {
1367 return RESTRICTION_PREVENT_PROCESSING;
1369 if (shell->IsSystemModalWindowOpen() &&
1370 actions_allowed_at_modal_window_.find(action) ==
1371 actions_allowed_at_modal_window_.end()) {
1372 // Note we prevent the shortcut from propagating so it will not
1373 // be passed to the modal window. This is important for things like
1374 // Alt+Tab that would cause an undesired effect in the modal window by
1375 // cycling through its window elements.
1376 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1378 if (shell->mru_window_tracker()->BuildMruWindowList().empty() &&
1379 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1380 Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
1381 ui::A11Y_ALERT_WINDOW_NEEDED);
1382 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1384 return RESTRICTION_NONE;
1387 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1388 scoped_ptr<KeyboardBrightnessControlDelegate>
1389 keyboard_brightness_control_delegate) {
1390 keyboard_brightness_control_delegate_ =
1391 keyboard_brightness_control_delegate.Pass();
1394 } // namespace ash