Home | History | Annotate | Download | only in accelerators
      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.
      4 
      5 #include "ash/accelerators/accelerator_controller.h"
      6 
      7 #include <algorithm>
      8 #include <cmath>
      9 #include <string>
     10 
     11 #include "ash/accelerators/accelerator_commands.h"
     12 #include "ash/accelerators/accelerator_table.h"
     13 #include "ash/accelerators/debug_commands.h"
     14 #include "ash/ash_switches.h"
     15 #include "ash/debug.h"
     16 #include "ash/display/display_controller.h"
     17 #include "ash/display/display_manager.h"
     18 #include "ash/focus_cycler.h"
     19 #include "ash/gpu_support.h"
     20 #include "ash/host/ash_window_tree_host.h"
     21 #include "ash/ime_control_delegate.h"
     22 #include "ash/magnifier/magnification_controller.h"
     23 #include "ash/magnifier/partial_magnification_controller.h"
     24 #include "ash/media_delegate.h"
     25 #include "ash/multi_profile_uma.h"
     26 #include "ash/new_window_delegate.h"
     27 #include "ash/root_window_controller.h"
     28 #include "ash/rotator/screen_rotation.h"
     29 #include "ash/screenshot_delegate.h"
     30 #include "ash/session/session_state_delegate.h"
     31 #include "ash/shelf/shelf.h"
     32 #include "ash/shelf/shelf_delegate.h"
     33 #include "ash/shelf/shelf_model.h"
     34 #include "ash/shelf/shelf_widget.h"
     35 #include "ash/shell.h"
     36 #include "ash/shell_delegate.h"
     37 #include "ash/shell_window_ids.h"
     38 #include "ash/system/brightness_control_delegate.h"
     39 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
     40 #include "ash/system/status_area_widget.h"
     41 #include "ash/system/tray/system_tray.h"
     42 #include "ash/system/tray/system_tray_delegate.h"
     43 #include "ash/system/tray/system_tray_notifier.h"
     44 #include "ash/system/web_notification/web_notification_tray.h"
     45 #include "ash/touch/touch_hud_debug.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/partial_screenshot_view.h"
     51 #include "ash/wm/power_button_controller.h"
     52 #include "ash/wm/window_cycle_controller.h"
     53 #include "ash/wm/window_state.h"
     54 #include "ash/wm/window_util.h"
     55 #include "ash/wm/wm_event.h"
     56 #include "base/bind.h"
     57 #include "base/command_line.h"
     58 #include "base/metrics/user_metrics.h"
     59 #include "ui/aura/env.h"
     60 #include "ui/aura/window_event_dispatcher.h"
     61 #include "ui/base/accelerators/accelerator.h"
     62 #include "ui/base/accelerators/accelerator_manager.h"
     63 #include "ui/compositor/debug_utils.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/views/controls/webview/webview.h"
     71 #include "ui/views/debug_utils.h"
     72 #include "ui/views/widget/widget.h"
     73 
     74 #if defined(OS_CHROMEOS)
     75 #include "ash/system/chromeos/keyboard_brightness_controller.h"
     76 #include "base/sys_info.h"
     77 #include "chromeos/ime/ime_keyboard.h"
     78 #include "chromeos/ime/input_method_manager.h"
     79 #endif  // defined(OS_CHROMEOS)
     80 
     81 namespace ash {
     82 namespace {
     83 
     84 using base::UserMetricsAction;
     85 
     86 bool DebugShortcutsEnabled() {
     87 #if defined(NDEBUG)
     88   return CommandLine::ForCurrentProcess()->HasSwitch(
     89           switches::kAshDebugShortcuts);
     90 #else
     91   return true;
     92 #endif
     93 }
     94 
     95 bool HandleAccessibleFocusCycle(bool reverse) {
     96   if (reverse) {
     97     base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
     98   } else {
     99     base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Next"));
    100   }
    101 
    102   if (!Shell::GetInstance()->accessibility_delegate()->
    103       IsSpokenFeedbackEnabled()) {
    104     return false;
    105   }
    106   aura::Window* active_window = ash::wm::GetActiveWindow();
    107   if (!active_window)
    108     return false;
    109   views::Widget* widget =
    110       views::Widget::GetWidgetForNativeWindow(active_window);
    111   if (!widget)
    112     return false;
    113   views::FocusManager* focus_manager = widget->GetFocusManager();
    114   if (!focus_manager)
    115     return false;
    116   views::View* view = focus_manager->GetFocusedView();
    117   if (!view)
    118     return false;
    119   if (!strcmp(view->GetClassName(), views::WebView::kViewClassName))
    120     return false;
    121 
    122   focus_manager->AdvanceFocus(reverse);
    123   return true;
    124 }
    125 
    126 bool HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
    127   if (accelerator.key_code() == ui::VKEY_TAB)
    128     base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
    129 
    130   Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
    131       WindowCycleController::BACKWARD);
    132   return true;
    133 }
    134 
    135 bool HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
    136   if (accelerator.key_code() == ui::VKEY_TAB)
    137     base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
    138 
    139   Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
    140       WindowCycleController::FORWARD);
    141   return true;
    142 }
    143 
    144 bool ToggleOverview(const ui::Accelerator& accelerator) {
    145   base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
    146   Shell::GetInstance()->window_selector_controller()->ToggleOverview();
    147   return true;
    148 }
    149 
    150 bool HandleFocusLauncher() {
    151   Shell* shell = Shell::GetInstance();
    152   base::RecordAction(base::UserMetricsAction("Accel_Focus_Launcher"));
    153   return shell->focus_cycler()->FocusWidget(
    154       Shelf::ForPrimaryDisplay()->shelf_widget());
    155 }
    156 
    157 bool HandleLaunchAppN(int n) {
    158   base::RecordAction(UserMetricsAction("Accel_Launch_App"));
    159   Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(n);
    160   return true;
    161 }
    162 
    163 bool HandleLaunchLastApp() {
    164   base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
    165   Shelf::ForPrimaryDisplay()->LaunchAppIndexAt(-1);
    166   return true;
    167 }
    168 
    169 // Magnify the screen
    170 bool HandleMagnifyScreen(int delta_index) {
    171   if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
    172     // TODO(yoshiki): Move the following logic to MagnificationController.
    173     float scale =
    174         ash::Shell::GetInstance()->magnification_controller()->GetScale();
    175     // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
    176     int scale_index =
    177         std::floor(std::log(scale) / std::log(kMagnificationScaleFactor) + 0.5);
    178 
    179     int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
    180 
    181     ash::Shell::GetInstance()->magnification_controller()->
    182         SetScale(std::pow(kMagnificationScaleFactor, new_scale_index), true);
    183   } else if (ash::Shell::GetInstance()->
    184              partial_magnification_controller()->is_enabled()) {
    185     float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
    186     ash::Shell::GetInstance()->partial_magnification_controller()->
    187         SetScale(scale);
    188   }
    189 
    190   return true;
    191 }
    192 
    193 bool HandleMediaNextTrack() {
    194   Shell::GetInstance()->media_delegate()->HandleMediaNextTrack();
    195   return true;
    196 }
    197 
    198 bool HandleMediaPlayPause() {
    199   Shell::GetInstance()->media_delegate()->HandleMediaPlayPause();
    200   return true;
    201 }
    202 
    203 bool HandleMediaPrevTrack() {
    204   Shell::GetInstance()->media_delegate()->HandleMediaPrevTrack();
    205   return true;
    206 }
    207 
    208 bool HandleNewIncognitoWindow() {
    209   base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
    210   bool incognito_allowed =
    211     Shell::GetInstance()->delegate()->IsIncognitoAllowed();
    212   if (incognito_allowed)
    213     Shell::GetInstance()->new_window_delegate()->NewWindow(
    214         true /* is_incognito */);
    215   return incognito_allowed;
    216 }
    217 
    218 bool HandleNewTab(ui::KeyboardCode key_code) {
    219   if (key_code == ui::VKEY_T)
    220     base::RecordAction(base::UserMetricsAction("Accel_NewTab_T"));
    221   Shell::GetInstance()->new_window_delegate()->NewTab();
    222   return true;
    223 }
    224 
    225 bool HandleNewWindow() {
    226   base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
    227   Shell::GetInstance()->new_window_delegate()->NewWindow(
    228       false /* is_incognito */);
    229   return true;
    230 }
    231 
    232 bool HandleNextIme(ImeControlDelegate* ime_control_delegate,
    233                    ui::EventType previous_event_type,
    234                    ui::KeyboardCode previous_key_code) {
    235   // This check is necessary e.g. not to process the Shift+Alt+
    236   // ET_KEY_RELEASED accelerator for Chrome OS (see ash/accelerators/
    237   // accelerator_controller.cc) when Shift+Alt+Tab is pressed and then Tab
    238   // is released.
    239   if (previous_event_type == ui::ET_KEY_RELEASED &&
    240       // Workaround for crbug.com/139556. CJK IME users tend to press
    241       // Enter (or Space) and Shift+Alt almost at the same time to commit
    242       // an IME string and then switch from the IME to the English layout.
    243       // This workaround allows the user to trigger NEXT_IME even if the
    244       // user presses Shift+Alt before releasing Enter.
    245       // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
    246       previous_key_code != ui::VKEY_RETURN &&
    247       previous_key_code != ui::VKEY_SPACE) {
    248     // We totally ignore this accelerator.
    249     // TODO(mazda): Fix crbug.com/158217
    250     return false;
    251   }
    252   base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
    253   if (ime_control_delegate)
    254     return ime_control_delegate->HandleNextIme();
    255   return false;
    256 }
    257 
    258 bool HandleOpenFeedbackPage() {
    259   base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
    260   ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
    261   return true;
    262 }
    263 
    264 bool HandlePositionCenter() {
    265   base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
    266   aura::Window* window = wm::GetActiveWindow();
    267   // Docked windows do not support centering and ignore accelerator.
    268   if (window && !wm::GetWindowState(window)->IsDocked()) {
    269     wm::CenterWindow(window);
    270     return true;
    271   }
    272   return false;
    273 }
    274 
    275 bool HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
    276                        const ui::Accelerator& accelerator) {
    277   base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
    278   if (ime_control_delegate)
    279     return ime_control_delegate->HandlePreviousIme(accelerator);
    280   return false;
    281 }
    282 
    283 bool HandleRestoreTab() {
    284   base::RecordAction(base::UserMetricsAction("Accel_Restore_Tab"));
    285   Shell::GetInstance()->new_window_delegate()->RestoreTab();
    286   return true;
    287 }
    288 
    289 bool HandleRotatePaneFocus(Shell::Direction direction) {
    290   Shell* shell = Shell::GetInstance();
    291   switch (direction) {
    292     // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
    293     case Shell::FORWARD: {
    294       base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
    295       shell->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
    296       break;
    297     }
    298     case Shell::BACKWARD: {
    299       base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
    300       shell->focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
    301       break;
    302     }
    303   }
    304   return true;
    305 }
    306 
    307 // Rotate the active window.
    308 bool HandleRotateActiveWindow() {
    309   base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
    310   aura::Window* active_window = wm::GetActiveWindow();
    311   if (active_window) {
    312     // The rotation animation bases its target transform on the current
    313     // rotation and position. Since there could be an animation in progress
    314     // right now, queue this animation so when it starts it picks up a neutral
    315     // rotation and position. Use replace so we only enqueue one at a time.
    316     active_window->layer()->GetAnimator()->
    317         set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
    318     active_window->layer()->GetAnimator()->StartAnimation(
    319         new ui::LayerAnimationSequence(
    320             new ash::ScreenRotation(360, active_window->layer())));
    321   }
    322   return true;
    323 }
    324 
    325 gfx::Display::Rotation GetNextRotation(gfx::Display::Rotation current) {
    326   switch (current) {
    327     case gfx::Display::ROTATE_0:
    328       return gfx::Display::ROTATE_90;
    329     case gfx::Display::ROTATE_90:
    330       return gfx::Display::ROTATE_180;
    331     case gfx::Display::ROTATE_180:
    332       return gfx::Display::ROTATE_270;
    333     case gfx::Display::ROTATE_270:
    334       return gfx::Display::ROTATE_0;
    335   }
    336   NOTREACHED() << "Unknown rotation:" << current;
    337   return gfx::Display::ROTATE_0;
    338 }
    339 
    340 // Rotates the screen.
    341 bool HandleRotateScreen() {
    342   base::RecordAction(UserMetricsAction("Accel_Rotate_Window"));
    343   gfx::Point point = Shell::GetScreen()->GetCursorScreenPoint();
    344   gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(point);
    345   const DisplayInfo& display_info =
    346       Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
    347   Shell::GetInstance()->display_manager()->SetDisplayRotation(
    348       display.id(), GetNextRotation(display_info.rotation()));
    349   return true;
    350 }
    351 
    352 bool HandleScaleReset() {
    353   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
    354   int64 display_id = display_manager->GetDisplayIdForUIScaling();
    355   if (display_id == gfx::Display::kInvalidDisplayID)
    356     return false;
    357 
    358   base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Reset"));
    359 
    360   display_manager->SetDisplayUIScale(display_id, 1.0f);
    361   return true;
    362 }
    363 
    364 bool HandleScaleUI(bool up) {
    365   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
    366   int64 display_id = display_manager->GetDisplayIdForUIScaling();
    367   if (display_id == gfx::Display::kInvalidDisplayID)
    368     return false;
    369 
    370   if (up) {
    371     base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Up"));
    372   } else {
    373     base::RecordAction(UserMetricsAction("Accel_Scale_Ui_Down"));
    374   }
    375 
    376   const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
    377   float next_scale = DisplayManager::GetNextUIScale(display_info, up);
    378   display_manager->SetDisplayUIScale(display_id, next_scale);
    379   return true;
    380 }
    381 
    382 #if defined(OS_CHROMEOS)
    383 bool HandleSwapPrimaryDisplay() {
    384   base::RecordAction(UserMetricsAction("Accel_Swap_Primary_Display"));
    385   Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
    386   return true;
    387 }
    388 #endif
    389 
    390 bool HandleShowKeyboardOverlay() {
    391   base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
    392   ash::Shell::GetInstance()->new_window_delegate()->ShowKeyboardOverlay();
    393 
    394   return true;
    395 }
    396 
    397 void HandleShowMessageCenterBubble() {
    398   base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
    399   RootWindowController* controller =
    400       RootWindowController::ForTargetRootWindow();
    401   StatusAreaWidget* status_area_widget =
    402       controller->shelf()->status_area_widget();
    403   if (status_area_widget) {
    404     WebNotificationTray* notification_tray =
    405       status_area_widget->web_notification_tray();
    406     if (notification_tray->visible())
    407       notification_tray->ShowMessageCenterBubble();
    408   }
    409 }
    410 
    411 bool HandleShowSystemTrayBubble() {
    412   base::RecordAction(UserMetricsAction("Accel_Show_System_Tray_Bubble"));
    413   RootWindowController* controller =
    414       RootWindowController::ForTargetRootWindow();
    415   if (!controller->GetSystemTray()->HasSystemBubble()) {
    416     controller->GetSystemTray()->ShowDefaultView(BUBBLE_CREATE_NEW);
    417     return true;
    418   }
    419   return false;
    420 }
    421 
    422 bool HandleShowTaskManager() {
    423   base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
    424   Shell::GetInstance()->new_window_delegate()->ShowTaskManager();
    425   return true;
    426 }
    427 
    428 #if defined(OS_CHROMEOS)
    429 void HandleSilenceSpokenFeedback() {
    430   base::RecordAction(UserMetricsAction("Accel_Silence_Spoken_Feedback"));
    431 
    432   AccessibilityDelegate* delegate =
    433       Shell::GetInstance()->accessibility_delegate();
    434   if (!delegate->IsSpokenFeedbackEnabled())
    435     return;
    436   delegate->SilenceSpokenFeedback();
    437 }
    438 #endif
    439 
    440 bool HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
    441                      const ui::Accelerator& accelerator) {
    442   base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
    443   if (ime_control_delegate)
    444     return ime_control_delegate->HandleSwitchIme(accelerator);
    445   return false;
    446 }
    447 
    448 bool HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
    449   base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
    450   if (screenshot_delegate) {
    451     ash::PartialScreenshotView::StartPartialScreenshot(
    452         screenshot_delegate);
    453   }
    454   // Return true to prevent propagation of the key event because
    455   // this key combination is reserved for partial screenshot.
    456   return true;
    457 }
    458 
    459 bool HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
    460   base::RecordAction(UserMetricsAction("Accel_Take_Screenshot"));
    461   if (screenshot_delegate &&
    462       screenshot_delegate->CanTakeScreenshot()) {
    463     screenshot_delegate->HandleTakeScreenshotForAllRootWindows();
    464   }
    465   // Return true to prevent propagation of the key event.
    466   return true;
    467 }
    468 
    469 bool HandleToggleAppList(ui::KeyboardCode key_code,
    470                          ui::EventType previous_event_type,
    471                          ui::KeyboardCode previous_key_code,
    472                          const ui::Accelerator& accelerator) {
    473   // If something else was pressed between the Search key (LWIN)
    474   // being pressed and released, then ignore the release of the
    475   // Search key.
    476   if (key_code == ui::VKEY_LWIN &&
    477       (previous_event_type == ui::ET_KEY_RELEASED ||
    478        previous_key_code != ui::VKEY_LWIN))
    479     return false;
    480   if (key_code == ui::VKEY_LWIN)
    481     base::RecordAction(base::UserMetricsAction("Accel_Search_LWin"));
    482   // When spoken feedback is enabled, we should neither toggle the list nor
    483   // consume the key since Search+Shift is one of the shortcuts the a11y
    484   // feature uses. crbug.com/132296
    485   DCHECK_EQ(ui::VKEY_LWIN, accelerator.key_code());
    486   if (Shell::GetInstance()->accessibility_delegate()->
    487       IsSpokenFeedbackEnabled())
    488     return false;
    489   ash::Shell::GetInstance()->ToggleAppList(NULL);
    490   return true;
    491 }
    492 
    493 bool HandleToggleFullscreen(ui::KeyboardCode key_code) {
    494   if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) {
    495     base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
    496   }
    497   accelerators::ToggleFullscreen();
    498   return true;
    499 }
    500 
    501 bool HandleToggleRootWindowFullScreen() {
    502   Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen();
    503   return true;
    504 }
    505 
    506 bool HandleWindowSnap(int action) {
    507   wm::WindowState* window_state = wm::GetActiveWindowState();
    508   // Disable window snapping shortcut key for full screen window due to
    509   // http://crbug.com/135487.
    510   if (!window_state ||
    511       window_state->window()->type() != ui::wm::WINDOW_TYPE_NORMAL ||
    512       window_state->IsFullscreen() ||
    513       !window_state->CanSnap()) {
    514     return false;
    515   }
    516 
    517   if (action == WINDOW_SNAP_LEFT) {
    518     base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
    519   } else {
    520     base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
    521   }
    522   const wm::WMEvent event(action == WINDOW_SNAP_LEFT ?
    523                           wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
    524   window_state->OnWMEvent(&event);
    525   return true;
    526 }
    527 
    528 bool HandleWindowMinimize() {
    529   base::RecordAction(
    530       base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
    531   return accelerators::ToggleMinimized();
    532 }
    533 
    534 #if defined(OS_CHROMEOS)
    535 bool HandleAddRemoveDisplay() {
    536   base::RecordAction(UserMetricsAction("Accel_Add_Remove_Display"));
    537   Shell::GetInstance()->display_manager()->AddRemoveDisplay();
    538   return true;
    539 }
    540 
    541 bool HandleCrosh() {
    542   base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
    543 
    544   Shell::GetInstance()->new_window_delegate()->OpenCrosh();
    545   return true;
    546 }
    547 
    548 bool HandleFileManager() {
    549   base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
    550 
    551   Shell::GetInstance()->new_window_delegate()->OpenFileManager();
    552   return true;
    553 }
    554 
    555 bool HandleLock(ui::KeyboardCode key_code) {
    556   base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
    557   Shell::GetInstance()->session_state_delegate()->LockScreen();
    558   return true;
    559 }
    560 
    561 bool HandleCycleUser(SessionStateDelegate::CycleUser cycle_user) {
    562   if (!Shell::GetInstance()->delegate()->IsMultiProfilesEnabled())
    563     return false;
    564   ash::SessionStateDelegate* delegate =
    565       ash::Shell::GetInstance()->session_state_delegate();
    566   if (delegate->NumberOfLoggedInUsers() <= 1)
    567     return false;
    568   MultiProfileUMA::RecordSwitchActiveUser(
    569       MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
    570   switch (cycle_user) {
    571     case SessionStateDelegate::CYCLE_TO_NEXT_USER:
    572       base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
    573       break;
    574     case SessionStateDelegate::CYCLE_TO_PREVIOUS_USER:
    575       base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
    576       break;
    577   }
    578   delegate->CycleActiveUser(cycle_user);
    579   return true;
    580 }
    581 
    582 bool HandleToggleMirrorMode() {
    583   base::RecordAction(UserMetricsAction("Accel_Toggle_Mirror_Mode"));
    584   Shell::GetInstance()->display_controller()->ToggleMirrorMode();
    585   return true;
    586 }
    587 
    588 bool HandleToggleSpokenFeedback() {
    589   base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
    590 
    591   Shell::GetInstance()->accessibility_delegate()->
    592       ToggleSpokenFeedback(A11Y_NOTIFICATION_SHOW);
    593   return true;
    594 }
    595 
    596 bool HandleToggleTouchViewTesting() {
    597   // TODO(skuhne): This is only temporary! Remove this!
    598   if (CommandLine::ForCurrentProcess()->HasSwitch(
    599           switches::kAshEnableTouchViewTesting)) {
    600     MaximizeModeController* controller = Shell::GetInstance()->
    601         maximize_mode_controller();
    602     controller->EnableMaximizeModeWindowManager(
    603         !controller->IsMaximizeModeWindowManagerEnabled());
    604     return true;
    605   }
    606   return false;
    607 }
    608 
    609 bool HandleTouchHudClear() {
    610   RootWindowController* controller =
    611       RootWindowController::ForTargetRootWindow();
    612   if (controller->touch_hud_debug()) {
    613     controller->touch_hud_debug()->Clear();
    614     return true;
    615   }
    616   return false;
    617 }
    618 
    619 bool HandleTouchHudModeChange() {
    620   RootWindowController* controller =
    621       RootWindowController::ForTargetRootWindow();
    622   if (controller->touch_hud_debug()) {
    623     controller->touch_hud_debug()->ChangeToNextMode();
    624     return true;
    625   }
    626   return false;
    627 }
    628 
    629 bool HandleTouchHudProjectToggle() {
    630   base::RecordAction(UserMetricsAction("Accel_Touch_Hud_Clear"));
    631   bool enabled = Shell::GetInstance()->is_touch_hud_projection_enabled();
    632   Shell::GetInstance()->SetTouchHudProjectionEnabled(!enabled);
    633   return true;
    634 }
    635 
    636 bool HandleDisableCapsLock(ui::KeyboardCode key_code,
    637                            ui::EventType previous_event_type,
    638                            ui::KeyboardCode previous_key_code) {
    639   if (previous_event_type == ui::ET_KEY_RELEASED ||
    640       (previous_key_code != ui::VKEY_LSHIFT &&
    641        previous_key_code != ui::VKEY_SHIFT &&
    642        previous_key_code != ui::VKEY_RSHIFT)) {
    643     // If something else was pressed between the Shift key being pressed
    644     // and released, then ignore the release of the Shift key.
    645     return false;
    646   }
    647   base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
    648   chromeos::input_method::InputMethodManager* ime =
    649       chromeos::input_method::InputMethodManager::Get();
    650   chromeos::input_method::ImeKeyboard* keyboard =
    651       ime ? ime->GetImeKeyboard() : NULL;
    652   if (keyboard && keyboard->CapsLockIsEnabled()) {
    653     keyboard->SetCapsLockEnabled(false);
    654     return true;
    655   }
    656   return false;
    657 }
    658 
    659 bool HandleToggleCapsLock(ui::KeyboardCode key_code,
    660                           ui::EventType previous_event_type,
    661                           ui::KeyboardCode previous_key_code) {
    662   if (key_code == ui::VKEY_LWIN) {
    663     // If something else was pressed between the Search key (LWIN)
    664     // being pressed and released, then ignore the release of the
    665     // Search key.
    666     // TODO(danakj): Releasing Alt first breaks this: crbug.com/166495
    667     if (previous_event_type == ui::ET_KEY_RELEASED ||
    668         previous_key_code != ui::VKEY_LWIN)
    669       return false;
    670   }
    671   base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
    672   chromeos::input_method::InputMethodManager* ime =
    673       chromeos::input_method::InputMethodManager::Get();
    674   chromeos::input_method::ImeKeyboard* keyboard =
    675       ime ? ime->GetImeKeyboard() : NULL;
    676   if (keyboard)
    677     keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
    678   return true;
    679 }
    680 
    681 #endif  // defined(OS_CHROMEOS)
    682 
    683 // Debug print methods.
    684 
    685 bool HandlePrintLayerHierarchy() {
    686   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    687   for (size_t i = 0; i < root_windows.size(); ++i) {
    688     ui::PrintLayerHierarchy(
    689         root_windows[i]->layer(),
    690         root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
    691   }
    692   return true;
    693 }
    694 
    695 bool HandlePrintViewHierarchy() {
    696   aura::Window* active_window = ash::wm::GetActiveWindow();
    697   if (!active_window)
    698     return true;
    699   views::Widget* browser_widget =
    700       views::Widget::GetWidgetForNativeWindow(active_window);
    701   if (!browser_widget)
    702     return true;
    703   views::PrintViewHierarchy(browser_widget->GetRootView());
    704   return true;
    705 }
    706 
    707 void PrintWindowHierarchy(aura::Window* window,
    708                           int indent,
    709                           std::ostringstream* out) {
    710   std::string indent_str(indent, ' ');
    711   std::string name(window->name());
    712   if (name.empty())
    713     name = "\"\"";
    714   *out << indent_str << name << " (" << window << ")"
    715        << " type=" << window->type()
    716        << (wm::IsActiveWindow(window) ? " [active] " : " ")
    717        << (window->IsVisible() ? " visible " : " ")
    718        << window->bounds().ToString()
    719        << '\n';
    720 
    721   for (size_t i = 0; i < window->children().size(); ++i)
    722     PrintWindowHierarchy(window->children()[i], indent + 3, out);
    723 }
    724 
    725 bool HandlePrintWindowHierarchy() {
    726   Shell::RootWindowControllerList controllers =
    727       Shell::GetAllRootWindowControllers();
    728   for (size_t i = 0; i < controllers.size(); ++i) {
    729     std::ostringstream out;
    730     out << "RootWindow " << i << ":\n";
    731     PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out);
    732     // Error so logs can be collected from end-users.
    733     LOG(ERROR) << out.str();
    734   }
    735   return true;
    736 }
    737 
    738 bool HandlePrintUIHierarchies() {
    739   // This is a separate command so the user only has to hit one key to generate
    740   // all the logs. Developers use the individual dumps repeatedly, so keep
    741   // those as separate commands to avoid spamming their logs.
    742   HandlePrintLayerHierarchy();
    743   HandlePrintWindowHierarchy();
    744   HandlePrintViewHierarchy();
    745   return true;
    746 }
    747 
    748 class AutoSet {
    749  public:
    750   AutoSet(ui::Accelerator* scoped, ui::Accelerator new_value)
    751       : scoped_(scoped), new_value_(new_value) {}
    752   ~AutoSet() { *scoped_ = new_value_; }
    753 
    754  private:
    755   ui::Accelerator* scoped_;
    756   const ui::Accelerator new_value_;
    757 
    758   DISALLOW_COPY_AND_ASSIGN(AutoSet);
    759 };
    760 
    761 }  // namespace
    762 
    763 ////////////////////////////////////////////////////////////////////////////////
    764 // AcceleratorController, public:
    765 
    766 AcceleratorController::AcceleratorController()
    767     : accelerator_manager_(new ui::AcceleratorManager) {
    768   Init();
    769 }
    770 
    771 AcceleratorController::~AcceleratorController() {
    772 }
    773 
    774 void AcceleratorController::Init() {
    775   previous_accelerator_.set_type(ui::ET_UNKNOWN);
    776   for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
    777     actions_allowed_at_login_screen_.insert(
    778         kActionsAllowedAtLoginOrLockScreen[i]);
    779     actions_allowed_at_lock_screen_.insert(
    780         kActionsAllowedAtLoginOrLockScreen[i]);
    781   }
    782   for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
    783     actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
    784   for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
    785     actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
    786   for (size_t i = 0; i < kReservedActionsLength; ++i)
    787     reserved_actions_.insert(kReservedActions[i]);
    788   for (size_t i = 0; i < kNonrepeatableActionsLength; ++i)
    789     nonrepeatable_actions_.insert(kNonrepeatableActions[i]);
    790   for (size_t i = 0; i < kActionsAllowedInAppModeLength; ++i)
    791     actions_allowed_in_app_mode_.insert(kActionsAllowedInAppMode[i]);
    792   for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
    793     actions_needing_window_.insert(kActionsNeedingWindow[i]);
    794 
    795   RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
    796 
    797 #if !defined(NDEBUG)
    798   RegisterAccelerators(kDesktopAcceleratorData, kDesktopAcceleratorDataLength);
    799 #endif
    800 
    801   if (DebugShortcutsEnabled()) {
    802     RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
    803     for (size_t i = 0; i < kReservedDebugActionsLength; ++i)
    804       reserved_actions_.insert(kReservedDebugActions[i]);
    805   }
    806 
    807 #if defined(OS_CHROMEOS)
    808   keyboard_brightness_control_delegate_.reset(
    809       new KeyboardBrightnessController());
    810 #endif
    811 }
    812 
    813 void AcceleratorController::Register(const ui::Accelerator& accelerator,
    814                                      ui::AcceleratorTarget* target) {
    815   accelerator_manager_->Register(accelerator,
    816                                  ui::AcceleratorManager::kNormalPriority,
    817                                  target);
    818 }
    819 
    820 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
    821                                        ui::AcceleratorTarget* target) {
    822   accelerator_manager_->Unregister(accelerator, target);
    823 }
    824 
    825 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
    826   accelerator_manager_->UnregisterAll(target);
    827 }
    828 
    829 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
    830   AutoSet auto_set(&previous_accelerator_, accelerator);
    831 
    832   if (ime_control_delegate_) {
    833     return accelerator_manager_->Process(
    834         ime_control_delegate_->RemapAccelerator(accelerator));
    835   }
    836   return accelerator_manager_->Process(accelerator);
    837 }
    838 
    839 bool AcceleratorController::IsRegistered(
    840     const ui::Accelerator& accelerator) const {
    841   return accelerator_manager_->GetCurrentTarget(accelerator) != NULL;
    842 }
    843 
    844 bool AcceleratorController::IsReservedAccelerator(
    845     const ui::Accelerator& accelerator) const {
    846   const ui::Accelerator remapped_accelerator = ime_control_delegate_.get() ?
    847       ime_control_delegate_->RemapAccelerator(accelerator) : accelerator;
    848 
    849   std::map<ui::Accelerator, int>::const_iterator iter =
    850       accelerators_.find(remapped_accelerator);
    851   if (iter == accelerators_.end())
    852     return false;  // not an accelerator.
    853 
    854   return reserved_actions_.find(iter->second) != reserved_actions_.end();
    855 }
    856 
    857 bool AcceleratorController::PerformAction(int action,
    858                                           const ui::Accelerator& accelerator) {
    859   ash::Shell* shell = ash::Shell::GetInstance();
    860   if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
    861       actions_allowed_at_login_screen_.find(action) ==
    862       actions_allowed_at_login_screen_.end()) {
    863     return false;
    864   }
    865   if (shell->session_state_delegate()->IsScreenLocked() &&
    866       actions_allowed_at_lock_screen_.find(action) ==
    867       actions_allowed_at_lock_screen_.end()) {
    868     return false;
    869   }
    870   if (shell->IsSystemModalWindowOpen() &&
    871       actions_allowed_at_modal_window_.find(action) ==
    872       actions_allowed_at_modal_window_.end()) {
    873     // Note: we return true. This indicates the shortcut is handled
    874     // and will not be passed to the modal window. This is important
    875     // for things like Alt+Tab that would cause an undesired effect
    876     // in the modal window by cycling through its window elements.
    877     return true;
    878   }
    879   if (shell->delegate()->IsRunningInForcedAppMode() &&
    880       actions_allowed_in_app_mode_.find(action) ==
    881       actions_allowed_in_app_mode_.end()) {
    882     return false;
    883   }
    884   if (MruWindowTracker::BuildWindowList(false).empty() &&
    885       actions_needing_window_.find(action) != actions_needing_window_.end()) {
    886     Shell::GetInstance()->accessibility_delegate()->TriggerAccessibilityAlert(
    887         A11Y_ALERT_WINDOW_NEEDED);
    888     return true;
    889   }
    890 
    891   const ui::KeyboardCode key_code = accelerator.key_code();
    892   // PerformAction() is performed from gesture controllers and passes
    893   // empty Accelerator() instance as the second argument. Such events
    894   // should never be suspended.
    895   const bool gesture_event = key_code == ui::VKEY_UNKNOWN;
    896   // Ignore accelerators invoked as repeated (while holding a key for a long
    897   // time, if their handling is nonrepeatable.
    898   if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
    899       accelerator.IsRepeat() && !gesture_event) {
    900     return true;
    901   }
    902   // Type of the previous accelerator. Used by NEXT_IME and DISABLE_CAPS_LOCK.
    903   const ui::EventType previous_event_type = previous_accelerator_.type();
    904   const ui::KeyboardCode previous_key_code = previous_accelerator_.key_code();
    905 
    906   // You *MUST* return true when some action is performed. Otherwise, this
    907   // function might be called *twice*, via BrowserView::PreHandleKeyboardEvent
    908   // and BrowserView::HandleKeyboardEvent, for a single accelerator press.
    909   //
    910   // If your accelerator invokes more than one line of code, please either
    911   // implement it in your module's controller code (like TOGGLE_MIRROR_MODE
    912   // below) or pull it into a HandleFoo() function above.
    913   switch (action) {
    914     case ACCESSIBLE_FOCUS_NEXT:
    915       return HandleAccessibleFocusCycle(false);
    916     case ACCESSIBLE_FOCUS_PREVIOUS:
    917       return HandleAccessibleFocusCycle(true);
    918     case CYCLE_BACKWARD_MRU:
    919       return HandleCycleBackwardMRU(accelerator);
    920     case CYCLE_FORWARD_MRU:
    921       return HandleCycleForwardMRU(accelerator);
    922     case TOGGLE_OVERVIEW:
    923       return ToggleOverview(accelerator);
    924 #if defined(OS_CHROMEOS)
    925     case ADD_REMOVE_DISPLAY:
    926       return HandleAddRemoveDisplay();
    927     case TOGGLE_MIRROR_MODE:
    928       return HandleToggleMirrorMode();
    929     case LOCK_SCREEN:
    930       return HandleLock(key_code);
    931     case OPEN_FILE_MANAGER:
    932       return HandleFileManager();
    933     case OPEN_CROSH:
    934       return HandleCrosh();
    935     case SILENCE_SPOKEN_FEEDBACK:
    936       HandleSilenceSpokenFeedback();
    937       break;
    938     case SWAP_PRIMARY_DISPLAY:
    939       return HandleSwapPrimaryDisplay();
    940     case SWITCH_TO_NEXT_USER:
    941       return HandleCycleUser(SessionStateDelegate::CYCLE_TO_NEXT_USER);
    942     case SWITCH_TO_PREVIOUS_USER:
    943       return HandleCycleUser(SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
    944     case TOGGLE_SPOKEN_FEEDBACK:
    945       return HandleToggleSpokenFeedback();
    946     case TOGGLE_TOUCH_VIEW_TESTING:
    947       return HandleToggleTouchViewTesting();
    948     case TOGGLE_WIFI:
    949       Shell::GetInstance()->system_tray_notifier()->NotifyRequestToggleWifi();
    950       return true;
    951     case TOUCH_HUD_CLEAR:
    952       return HandleTouchHudClear();
    953     case TOUCH_HUD_MODE_CHANGE:
    954       return HandleTouchHudModeChange();
    955     case TOUCH_HUD_PROJECTION_TOGGLE:
    956       return HandleTouchHudProjectToggle();
    957     case DISABLE_GPU_WATCHDOG:
    958       Shell::GetInstance()->gpu_support()->DisableGpuWatchdog();
    959       return true;
    960     case DISABLE_CAPS_LOCK:
    961       return HandleDisableCapsLock(
    962           key_code, previous_event_type, previous_key_code);
    963     case TOGGLE_CAPS_LOCK:
    964       return HandleToggleCapsLock(
    965           key_code, previous_event_type, previous_key_code);
    966 #endif  // OS_CHROMEOS
    967     case OPEN_FEEDBACK_PAGE:
    968       return HandleOpenFeedbackPage();
    969     case EXIT:
    970       // UMA metrics are recorded in the handler.
    971       exit_warning_handler_.HandleAccelerator();
    972       return true;
    973     case NEW_INCOGNITO_WINDOW:
    974       return HandleNewIncognitoWindow();
    975     case NEW_TAB:
    976       return HandleNewTab(key_code);
    977     case NEW_WINDOW:
    978       return HandleNewWindow();
    979     case RESTORE_TAB:
    980       return HandleRestoreTab();
    981     case TAKE_SCREENSHOT:
    982       return HandleTakeScreenshot(screenshot_delegate_.get());
    983     case TAKE_PARTIAL_SCREENSHOT:
    984       return HandleTakePartialScreenshot(screenshot_delegate_.get());
    985     case TOGGLE_APP_LIST:
    986       return HandleToggleAppList(
    987           key_code, previous_event_type, previous_key_code, accelerator);
    988     case BRIGHTNESS_DOWN:
    989       if (brightness_control_delegate_)
    990         return brightness_control_delegate_->HandleBrightnessDown(accelerator);
    991       break;
    992     case BRIGHTNESS_UP:
    993       if (brightness_control_delegate_)
    994         return brightness_control_delegate_->HandleBrightnessUp(accelerator);
    995       break;
    996     case KEYBOARD_BRIGHTNESS_DOWN:
    997       if (keyboard_brightness_control_delegate_)
    998         return keyboard_brightness_control_delegate_->
    999             HandleKeyboardBrightnessDown(accelerator);
   1000       break;
   1001     case KEYBOARD_BRIGHTNESS_UP:
   1002       if (keyboard_brightness_control_delegate_)
   1003         return keyboard_brightness_control_delegate_->
   1004             HandleKeyboardBrightnessUp(accelerator);
   1005       break;
   1006     case VOLUME_MUTE: {
   1007       ash::VolumeControlDelegate* volume_delegate =
   1008           shell->system_tray_delegate()->GetVolumeControlDelegate();
   1009       return volume_delegate && volume_delegate->HandleVolumeMute(accelerator);
   1010     }
   1011     case VOLUME_DOWN: {
   1012       ash::VolumeControlDelegate* volume_delegate =
   1013           shell->system_tray_delegate()->GetVolumeControlDelegate();
   1014       return volume_delegate && volume_delegate->HandleVolumeDown(accelerator);
   1015     }
   1016     case VOLUME_UP: {
   1017       ash::VolumeControlDelegate* volume_delegate =
   1018           shell->system_tray_delegate()->GetVolumeControlDelegate();
   1019       return volume_delegate && volume_delegate->HandleVolumeUp(accelerator);
   1020     }
   1021     case FOCUS_LAUNCHER:
   1022       return HandleFocusLauncher();
   1023     case FOCUS_NEXT_PANE:
   1024       return HandleRotatePaneFocus(Shell::FORWARD);
   1025     case FOCUS_PREVIOUS_PANE:
   1026       return HandleRotatePaneFocus(Shell::BACKWARD);
   1027     case SHOW_KEYBOARD_OVERLAY:
   1028       return HandleShowKeyboardOverlay();
   1029     case SHOW_SYSTEM_TRAY_BUBBLE:
   1030       return HandleShowSystemTrayBubble();
   1031     case SHOW_MESSAGE_CENTER_BUBBLE:
   1032       HandleShowMessageCenterBubble();
   1033       break;
   1034     case SHOW_TASK_MANAGER:
   1035       return HandleShowTaskManager();
   1036     case NEXT_IME:
   1037       return HandleNextIme(
   1038           ime_control_delegate_.get(), previous_event_type, previous_key_code);
   1039     case PREVIOUS_IME:
   1040       return HandlePreviousIme(ime_control_delegate_.get(), accelerator);
   1041     case PRINT_UI_HIERARCHIES:
   1042       return HandlePrintUIHierarchies();
   1043     case SWITCH_IME:
   1044       return HandleSwitchIme(ime_control_delegate_.get(), accelerator);
   1045     case LAUNCH_APP_0:
   1046       return HandleLaunchAppN(0);
   1047     case LAUNCH_APP_1:
   1048       return HandleLaunchAppN(1);
   1049     case LAUNCH_APP_2:
   1050       return HandleLaunchAppN(2);
   1051     case LAUNCH_APP_3:
   1052       return HandleLaunchAppN(3);
   1053     case LAUNCH_APP_4:
   1054       return HandleLaunchAppN(4);
   1055     case LAUNCH_APP_5:
   1056       return HandleLaunchAppN(5);
   1057     case LAUNCH_APP_6:
   1058       return HandleLaunchAppN(6);
   1059     case LAUNCH_APP_7:
   1060       return HandleLaunchAppN(7);
   1061     case LAUNCH_LAST_APP:
   1062       return HandleLaunchLastApp();
   1063     case WINDOW_SNAP_LEFT:
   1064     case WINDOW_SNAP_RIGHT:
   1065       return HandleWindowSnap(action);
   1066     case WINDOW_MINIMIZE:
   1067       return HandleWindowMinimize();
   1068     case TOGGLE_FULLSCREEN:
   1069       return HandleToggleFullscreen(key_code);
   1070     case TOGGLE_MAXIMIZED:
   1071       accelerators::ToggleMaximized();
   1072       return true;
   1073     case WINDOW_POSITION_CENTER:
   1074      return HandlePositionCenter();
   1075     case SCALE_UI_UP:
   1076       return HandleScaleUI(true /* up */);
   1077     case SCALE_UI_DOWN:
   1078       return HandleScaleUI(false /* down */);
   1079     case SCALE_UI_RESET:
   1080       return HandleScaleReset();
   1081     case ROTATE_WINDOW:
   1082       return HandleRotateActiveWindow();
   1083     case ROTATE_SCREEN:
   1084       return HandleRotateScreen();
   1085     case TOGGLE_DESKTOP_BACKGROUND_MODE:
   1086       return debug::CycleDesktopBackgroundMode();
   1087     case TOGGLE_ROOT_WINDOW_FULL_SCREEN:
   1088       return HandleToggleRootWindowFullScreen();
   1089     case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
   1090       Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor();
   1091       return true;
   1092     case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
   1093       ash::debug::ToggleShowDebugBorders();
   1094       return true;
   1095     case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
   1096       ash::debug::ToggleShowFpsCounter();
   1097       return true;
   1098     case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
   1099       ash::debug::ToggleShowPaintRects();
   1100       return true;
   1101     case MAGNIFY_SCREEN_ZOOM_IN:
   1102       return HandleMagnifyScreen(1);
   1103     case MAGNIFY_SCREEN_ZOOM_OUT:
   1104       return HandleMagnifyScreen(-1);
   1105     case MEDIA_NEXT_TRACK:
   1106       return HandleMediaNextTrack();
   1107     case MEDIA_PLAY_PAUSE:
   1108        return HandleMediaPlayPause();
   1109     case MEDIA_PREV_TRACK:
   1110        return HandleMediaPrevTrack();
   1111     case POWER_PRESSED:  // fallthrough
   1112     case POWER_RELEASED:
   1113 #if defined(OS_CHROMEOS)
   1114       if (!base::SysInfo::IsRunningOnChromeOS()) {
   1115         // There is no powerd in linux desktop, so call the
   1116         // PowerButtonController here.
   1117         Shell::GetInstance()->power_button_controller()->
   1118             OnPowerButtonEvent(action == POWER_PRESSED, base::TimeTicks());
   1119       }
   1120 #endif
   1121       // We don't do anything with these at present on the device,
   1122       // (power button events are reported to us from powerm via
   1123       // D-BUS), but we consume them to prevent them from getting
   1124       // passed to apps -- see http://crbug.com/146609.
   1125       return true;
   1126     case LOCK_PRESSED:
   1127     case LOCK_RELEASED:
   1128       Shell::GetInstance()->power_button_controller()->
   1129           OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
   1130       return true;
   1131     case PRINT_LAYER_HIERARCHY:
   1132       return HandlePrintLayerHierarchy();
   1133     case PRINT_VIEW_HIERARCHY:
   1134       return HandlePrintViewHierarchy();
   1135     case PRINT_WINDOW_HIERARCHY:
   1136       return HandlePrintWindowHierarchy();
   1137     default:
   1138       NOTREACHED() << "Unhandled action " << action;
   1139   }
   1140   return false;
   1141 }
   1142 
   1143 void AcceleratorController::SetBrightnessControlDelegate(
   1144     scoped_ptr<BrightnessControlDelegate> brightness_control_delegate) {
   1145   brightness_control_delegate_ = brightness_control_delegate.Pass();
   1146 }
   1147 
   1148 void AcceleratorController::SetImeControlDelegate(
   1149     scoped_ptr<ImeControlDelegate> ime_control_delegate) {
   1150   ime_control_delegate_ = ime_control_delegate.Pass();
   1151 }
   1152 
   1153 void AcceleratorController::SetScreenshotDelegate(
   1154     scoped_ptr<ScreenshotDelegate> screenshot_delegate) {
   1155   screenshot_delegate_ = screenshot_delegate.Pass();
   1156 }
   1157 
   1158 ////////////////////////////////////////////////////////////////////////////////
   1159 // AcceleratorController, ui::AcceleratorTarget implementation:
   1160 
   1161 bool AcceleratorController::AcceleratorPressed(
   1162     const ui::Accelerator& accelerator) {
   1163   std::map<ui::Accelerator, int>::const_iterator it =
   1164       accelerators_.find(accelerator);
   1165   DCHECK(it != accelerators_.end());
   1166   return PerformAction(static_cast<AcceleratorAction>(it->second), accelerator);
   1167 }
   1168 
   1169 void AcceleratorController::RegisterAccelerators(
   1170     const AcceleratorData accelerators[],
   1171     size_t accelerators_length) {
   1172   for (size_t i = 0; i < accelerators_length; ++i) {
   1173     ui::Accelerator accelerator(accelerators[i].keycode,
   1174                                 accelerators[i].modifiers);
   1175     accelerator.set_type(accelerators[i].trigger_on_press ?
   1176                          ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
   1177     Register(accelerator, this);
   1178     accelerators_.insert(
   1179         std::make_pair(accelerator, accelerators[i].action));
   1180   }
   1181 }
   1182 
   1183 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
   1184     scoped_ptr<KeyboardBrightnessControlDelegate>
   1185     keyboard_brightness_control_delegate) {
   1186   keyboard_brightness_control_delegate_ =
   1187       keyboard_brightness_control_delegate.Pass();
   1188 }
   1189 
   1190 bool AcceleratorController::CanHandleAccelerators() const {
   1191   return true;
   1192 }
   1193 
   1194 }  // namespace ash
   1195