Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: ash/common/accelerators/accelerator_controller.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/common/accelerators/accelerator_controller.h"
6
7 #include <utility>
8
9 #include "ash/common/accelerators/accelerator_commands.h"
10 #include "ash/common/accelerators/accelerator_controller_delegate.h"
11 #include "ash/common/accelerators/debug_commands.h"
12 #include "ash/common/accessibility_delegate.h"
13 #include "ash/common/accessibility_types.h"
14 #include "ash/common/focus_cycler.h"
15 #include "ash/common/ime_control_delegate.h"
16 #include "ash/common/media_controller.h"
17 #include "ash/common/multi_profile_uma.h"
18 #include "ash/common/new_window_controller.h"
19 #include "ash/common/palette_delegate.h"
20 #include "ash/common/session/session_state_delegate.h"
21 #include "ash/common/shelf/shelf_widget.h"
22 #include "ash/common/shelf/wm_shelf.h"
23 #include "ash/common/shell_delegate.h"
24 #include "ash/common/system/brightness_control_delegate.h"
25 #include "ash/common/system/chromeos/ime_menu/ime_menu_tray.h"
26 #include "ash/common/system/chromeos/palette/palette_tray.h"
27 #include "ash/common/system/chromeos/palette/palette_utils.h"
28 #include "ash/common/system/keyboard_brightness_control_delegate.h"
29 #include "ash/common/system/status_area_widget.h"
30 #include "ash/common/system/system_notifier.h"
31 #include "ash/common/system/tray/system_tray_delegate.h"
32 #include "ash/common/system/tray/system_tray_notifier.h"
33 #include "ash/common/system/web_notification/web_notification_tray.h"
34 #include "ash/common/wm/mru_window_tracker.h"
35 #include "ash/common/wm/overview/window_selector_controller.h"
36 #include "ash/common/wm/window_cycle_controller.h"
37 #include "ash/common/wm/window_positioning_utils.h"
38 #include "ash/common/wm/window_state.h"
39 #include "ash/common/wm/wm_event.h"
40 #include "ash/common/wm_shell.h"
41 #include "ash/common/wm_window.h"
42 #include "ash/resources/vector_icons/vector_icons.h"
43 #include "ash/root_window_controller.h"
44 #include "ash/strings/grit/ash_strings.h"
45 #include "base/metrics/histogram_macros.h"
46 #include "base/metrics/user_metrics.h"
47 #include "chromeos/dbus/dbus_thread_manager.h"
48 #include "chromeos/dbus/power_manager_client.h"
49 #include "ui/base/accelerators/accelerator.h"
50 #include "ui/base/accelerators/accelerator_manager.h"
51 #include "ui/base/ime/chromeos/ime_keyboard.h"
52 #include "ui/base/ime/chromeos/input_method_manager.h"
53 #include "ui/base/l10n/l10n_util.h"
54 #include "ui/gfx/paint_vector_icon.h"
55 #include "ui/keyboard/keyboard_controller.h"
56 #include "ui/message_center/message_center.h"
57
58 namespace ash {
59 namespace {
60
61 using base::UserMetricsAction;
62 using message_center::Notification;
63
64 // Identifier for the high contrast toggle accelerator notification.
65 const char kHighContrastToggleAccelNotificationId[] =
66 "chrome://settings/accessibility/highcontrast";
67
68 ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode,
69 int modifiers,
70 bool trigger_on_press) {
71 ui::Accelerator accelerator(keycode, modifiers);
72 accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED
73 : ui::ET_KEY_RELEASED);
74 return accelerator;
75 }
76
77 void RecordUmaHistogram(const char* histogram_name,
78 DeprecatedAcceleratorUsage sample) {
79 auto* histogram = base::LinearHistogram::FactoryGet(
80 histogram_name, 1, DEPRECATED_USAGE_COUNT, DEPRECATED_USAGE_COUNT + 1,
81 base::HistogramBase::kUmaTargetedHistogramFlag);
82 histogram->Add(sample);
83 }
84
85 void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
86 if (accelerator.key_code() == ui::VKEY_TAB)
87 base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
88
89 WmShell::Get()->window_cycle_controller()->HandleCycleWindow(
90 WindowCycleController::BACKWARD);
91 }
92
93 void HandleCycleForwardMRU(const ui::Accelerator& accelerator) {
94 if (accelerator.key_code() == ui::VKEY_TAB)
95 base::RecordAction(base::UserMetricsAction("Accel_NextWindow_Tab"));
96
97 WmShell::Get()->window_cycle_controller()->HandleCycleWindow(
98 WindowCycleController::FORWARD);
99 }
100
101 void HandleRotatePaneFocus(FocusCycler::Direction direction) {
102 switch (direction) {
103 // TODO(stevet): Not sure if this is the same as IDC_FOCUS_NEXT_PANE.
104 case FocusCycler::FORWARD: {
105 base::RecordAction(UserMetricsAction("Accel_Focus_Next_Pane"));
106 break;
107 }
108 case FocusCycler::BACKWARD: {
109 base::RecordAction(UserMetricsAction("Accel_Focus_Previous_Pane"));
110 break;
111 }
112 }
113 WmShell::Get()->focus_cycler()->RotateFocus(direction);
114 }
115
116 void HandleFocusShelf() {
117 base::RecordAction(UserMetricsAction("Accel_Focus_Shelf"));
118 // TODO(jamescook): Should this be GetRootWindowForNewWindows()?
119 WmShelf* shelf = WmShelf::ForWindow(WmShell::Get()->GetPrimaryRootWindow());
120 WmShell::Get()->focus_cycler()->FocusWidget(shelf->shelf_widget());
121 }
122
123 void HandleLaunchAppN(int n) {
124 base::RecordAction(UserMetricsAction("Accel_Launch_App"));
125 WmShelf::LaunchShelfItem(n);
126 }
127
128 void HandleLaunchLastApp() {
129 base::RecordAction(UserMetricsAction("Accel_Launch_Last_App"));
130 WmShelf::LaunchShelfItem(-1);
131 }
132
133 void HandleMediaNextTrack() {
134 WmShell::Get()->media_controller()->HandleMediaNextTrack();
135 }
136
137 void HandleMediaPlayPause() {
138 WmShell::Get()->media_controller()->HandleMediaPlayPause();
139 }
140
141 void HandleMediaPrevTrack() {
142 WmShell::Get()->media_controller()->HandleMediaPrevTrack();
143 }
144
145 bool CanHandleNewIncognitoWindow() {
146 return WmShell::Get()->delegate()->IsIncognitoAllowed();
147 }
148
149 void HandleNewIncognitoWindow() {
150 base::RecordAction(UserMetricsAction("Accel_New_Incognito_Window"));
151 WmShell::Get()->new_window_controller()->NewWindow(true /* is_incognito */);
152 }
153
154 void HandleNewTab(const ui::Accelerator& accelerator) {
155 if (accelerator.key_code() == ui::VKEY_T)
156 base::RecordAction(UserMetricsAction("Accel_NewTab_T"));
157 WmShell::Get()->new_window_controller()->NewTab();
158 }
159
160 void HandleNewWindow() {
161 base::RecordAction(UserMetricsAction("Accel_New_Window"));
162 WmShell::Get()->new_window_controller()->NewWindow(false /* is_incognito */);
163 }
164
165 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate) {
166 return ime_control_delegate && ime_control_delegate->CanCycleIme();
167 }
168
169 bool CanHandleCycleMru(const ui::Accelerator& accelerator) {
170 // Don't do anything when Alt+Tab is hit while a virtual keyboard is showing.
171 // Touchscreen users have better window switching options. It would be
172 // preferable if we could tell whether this event actually came from a virtual
173 // keyboard, but there's no easy way to do so, thus we block Alt+Tab when the
174 // virtual keyboard is showing, even if it came from a real keyboard. See
175 // http://crbug.com/638269
176 keyboard::KeyboardController* keyboard_controller =
177 keyboard::KeyboardController::GetInstance();
178 return !(keyboard_controller && keyboard_controller->keyboard_visible());
179 }
180
181 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
182 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
183 ime_control_delegate->HandleNextIme();
184 }
185
186 void HandleOpenFeedbackPage() {
187 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
188 WmShell::Get()->new_window_controller()->OpenFeedbackPage();
189 }
190
191 bool CanHandlePreviousIme(ImeControlDelegate* ime_control_delegate) {
192 return ime_control_delegate && ime_control_delegate->CanCycleIme();
193 }
194
195 void HandlePreviousIme(ImeControlDelegate* ime_control_delegate,
196 const ui::Accelerator& accelerator) {
197 base::RecordAction(UserMetricsAction("Accel_Previous_Ime"));
198 if (accelerator.type() == ui::ET_KEY_PRESSED)
199 ime_control_delegate->HandlePreviousIme();
200 // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything.
201 }
202
203 void HandleRestoreTab() {
204 base::RecordAction(UserMetricsAction("Accel_Restore_Tab"));
205 WmShell::Get()->new_window_controller()->RestoreTab();
206 }
207
208 void HandleShowKeyboardOverlay() {
209 base::RecordAction(UserMetricsAction("Accel_Show_Keyboard_Overlay"));
210 WmShell::Get()->new_window_controller()->ShowKeyboardOverlay();
211 }
212
213 bool CanHandleShowMessageCenterBubble() {
214 WmWindow* target_root = WmShell::Get()->GetRootWindowForNewWindows();
215 StatusAreaWidget* status_area_widget =
216 WmShelf::ForWindow(target_root)->shelf_widget()->status_area_widget();
217 return status_area_widget &&
218 status_area_widget->web_notification_tray()->visible();
219 }
220
221 void HandleShowMessageCenterBubble() {
222 base::RecordAction(UserMetricsAction("Accel_Show_Message_Center_Bubble"));
223 WmWindow* target_root = WmShell::Get()->GetRootWindowForNewWindows();
224 StatusAreaWidget* status_area_widget =
225 WmShelf::ForWindow(target_root)->shelf_widget()->status_area_widget();
226 if (status_area_widget) {
227 WebNotificationTray* notification_tray =
228 status_area_widget->web_notification_tray();
229 if (notification_tray->visible())
230 notification_tray->ShowMessageCenterBubble();
231 }
232 }
233
234 void HandleShowTaskManager() {
235 base::RecordAction(UserMetricsAction("Accel_Show_Task_Manager"));
236 WmShell::Get()->new_window_controller()->ShowTaskManager();
237 }
238
239 bool CanHandleSwitchIme(ImeControlDelegate* ime_control_delegate,
240 const ui::Accelerator& accelerator) {
241 return ime_control_delegate &&
242 ime_control_delegate->CanSwitchIme(accelerator);
243 }
244
245 void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
246 const ui::Accelerator& accelerator) {
247 base::RecordAction(UserMetricsAction("Accel_Switch_Ime"));
248 ime_control_delegate->HandleSwitchIme(accelerator);
249 }
250
251 bool CanHandleToggleAppList(const ui::Accelerator& accelerator,
252 const ui::Accelerator& previous_accelerator) {
253 if (accelerator.key_code() == ui::VKEY_LWIN) {
254 // If something else was pressed between the Search key (LWIN)
255 // being pressed and released, then ignore the release of the
256 // Search key.
257 if (previous_accelerator.type() != ui::ET_KEY_PRESSED ||
258 previous_accelerator.key_code() != ui::VKEY_LWIN) {
259 return false;
260 }
261
262 // When spoken feedback is enabled, we should neither toggle the list nor
263 // consume the key since Search+Shift is one of the shortcuts the a11y
264 // feature uses. crbug.com/132296
265 if (WmShell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled())
266 return false;
267 }
268 return true;
269 }
270
271 void HandleToggleAppList(const ui::Accelerator& accelerator) {
272 if (accelerator.key_code() == ui::VKEY_LWIN)
273 base::RecordAction(UserMetricsAction("Accel_Search_LWin"));
274 WmShell::Get()->ToggleAppList();
275 }
276
277 void HandleToggleFullscreen(const ui::Accelerator& accelerator) {
278 if (accelerator.key_code() == ui::VKEY_MEDIA_LAUNCH_APP2)
279 base::RecordAction(UserMetricsAction("Accel_Fullscreen_F4"));
280 accelerators::ToggleFullscreen();
281 }
282
283 void HandleToggleOverview() {
284 base::RecordAction(base::UserMetricsAction("Accel_Overview_F5"));
285 WmShell::Get()->window_selector_controller()->ToggleOverview();
286 }
287
288 bool CanHandleWindowSnapOrDock() {
289 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
290 if (!active_window)
291 return false;
292 wm::WindowState* window_state = active_window->GetWindowState();
293 // Disable window snapping shortcut key for full screen window due to
294 // http://crbug.com/135487.
295 return (window_state && window_state->IsUserPositionable() &&
296 !window_state->IsFullscreen());
297 }
298
299 void HandleWindowSnapOrDock(AcceleratorAction action) {
300 if (action == WINDOW_CYCLE_SNAP_DOCK_LEFT)
301 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Left"));
302 else
303 base::RecordAction(UserMetricsAction("Accel_Window_Snap_Right"));
304
305 const wm::WMEvent event(action == WINDOW_CYCLE_SNAP_DOCK_LEFT
306 ? wm::WM_EVENT_CYCLE_SNAP_DOCK_LEFT
307 : wm::WM_EVENT_CYCLE_SNAP_DOCK_RIGHT);
308 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
309 DCHECK(active_window);
310 active_window->GetWindowState()->OnWMEvent(&event);
311 }
312
313 void HandleWindowMinimize() {
314 base::RecordAction(base::UserMetricsAction("Accel_Toggle_Minimized_Minus"));
315 accelerators::ToggleMinimized();
316 }
317
318 bool CanHandlePositionCenter() {
319 // Docked windows do not support centering.
320 WmWindow* active_window = WmShell::Get()->GetActiveWindow();
321 return (active_window && !active_window->GetWindowState()->IsDocked());
322 }
323
324 void HandlePositionCenter() {
325 base::RecordAction(UserMetricsAction("Accel_Window_Position_Center"));
326 wm::CenterWindow(WmShell::Get()->GetActiveWindow());
327 }
328
329 void HandleShowImeMenuBubble() {
330 base::RecordAction(UserMetricsAction("Accel_Show_Ime_Menu_Bubble"));
331
332 StatusAreaWidget* status_area_widget =
333 WmShelf::ForWindow(WmShell::Get()->GetPrimaryRootWindow())
334 ->GetStatusAreaWidget();
335 if (status_area_widget) {
336 ImeMenuTray* ime_menu_tray = status_area_widget->ime_menu_tray();
337 if (ime_menu_tray && ime_menu_tray->visible() &&
338 !ime_menu_tray->IsImeMenuBubbleShown()) {
339 ime_menu_tray->ShowImeMenuBubble();
340 }
341 }
342 }
343
344 void HandleCrosh() {
345 base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
346
347 WmShell::Get()->new_window_controller()->OpenCrosh();
348 }
349
350 bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) {
351 ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
352 if (previous_accelerator.type() == ui::ET_KEY_RELEASED ||
353 (previous_key_code != ui::VKEY_LSHIFT &&
354 previous_key_code != ui::VKEY_SHIFT &&
355 previous_key_code != ui::VKEY_RSHIFT)) {
356 // If something else was pressed between the Shift key being pressed
357 // and released, then ignore the release of the Shift key.
358 return false;
359 }
360 chromeos::input_method::InputMethodManager* ime =
361 chromeos::input_method::InputMethodManager::Get();
362 chromeos::input_method::ImeKeyboard* keyboard =
363 ime ? ime->GetImeKeyboard() : NULL;
364 return (keyboard && keyboard->CapsLockIsEnabled());
365 }
366
367 void HandleDisableCapsLock() {
368 base::RecordAction(UserMetricsAction("Accel_Disable_Caps_Lock"));
369 chromeos::input_method::InputMethodManager* ime =
370 chromeos::input_method::InputMethodManager::Get();
371 ime->GetImeKeyboard()->SetCapsLockEnabled(false);
372 }
373
374 void HandleFileManager() {
375 base::RecordAction(UserMetricsAction("Accel_Open_File_Manager"));
376
377 WmShell::Get()->new_window_controller()->OpenFileManager();
378 }
379
380 void HandleGetHelp() {
381 WmShell::Get()->new_window_controller()->OpenGetHelp();
382 }
383
384 bool CanHandleLock() {
385 return WmShell::Get()->GetSessionStateDelegate()->CanLockScreen();
386 }
387
388 void HandleLock() {
389 base::RecordAction(UserMetricsAction("Accel_LockScreen_L"));
390 WmShell::Get()->GetSessionStateDelegate()->LockScreen();
391 }
392
393 void HandleShowStylusTools() {
394 base::RecordAction(UserMetricsAction("Accel_Show_Stylus_Tools"));
395
396 RootWindowController* root_window_controller =
397 WmShell::Get()->GetRootWindowForNewWindows()->GetRootWindowController();
398 PaletteTray* palette_tray =
399 root_window_controller->GetShelf()->GetStatusAreaWidget()->palette_tray();
400 palette_tray->ShowPalette();
401 }
402
403 bool CanHandleShowStylusTools() {
404 return WmShell::Get()->palette_delegate() &&
405 WmShell::Get()->palette_delegate()->ShouldShowPalette();
406 }
407
408 void HandleSuspend() {
409 base::RecordAction(UserMetricsAction("Accel_Suspend"));
410 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestSuspend();
411 }
412
413 bool CanHandleCycleUser() {
414 return WmShell::Get()->delegate()->IsMultiProfilesEnabled() &&
415 WmShell::Get()->GetSessionStateDelegate()->NumberOfLoggedInUsers() > 1;
416 }
417
418 void HandleCycleUser(CycleUserDirection direction) {
419 MultiProfileUMA::RecordSwitchActiveUser(
420 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_ACCELERATOR);
421 switch (direction) {
422 case CycleUserDirection::NEXT:
423 base::RecordAction(UserMetricsAction("Accel_Switch_To_Next_User"));
424 break;
425 case CycleUserDirection::PREVIOUS:
426 base::RecordAction(UserMetricsAction("Accel_Switch_To_Previous_User"));
427 break;
428 }
429 WmShell::Get()->GetSessionStateDelegate()->CycleActiveUser(direction);
430 }
431
432 bool CanHandleToggleCapsLock(const ui::Accelerator& accelerator,
433 const ui::Accelerator& previous_accelerator) {
434 chromeos::input_method::InputMethodManager* ime =
435 chromeos::input_method::InputMethodManager::Get();
436
437 // This shortcust is set to be trigger on release. Either the current
438 // accelerator is a Search release or Alt release.
439 if (accelerator.key_code() == ui::VKEY_LWIN &&
440 accelerator.type() == ui::ET_KEY_RELEASED) {
441 // The previous must be either an Alt press or Search press:
442 // 1. Press Alt, Press Search, Release Search, Release Alt.
443 // 2. Press Search, Press Alt, Release Search, Release Alt.
444 if (previous_accelerator.type() == ui::ET_KEY_PRESSED &&
445 (previous_accelerator.key_code() == ui::VKEY_LWIN ||
446 previous_accelerator.key_code() == ui::VKEY_MENU)) {
447 return ime && ime->GetImeKeyboard();
448 }
449 }
450
451 // Alt release.
452 if (accelerator.key_code() == ui::VKEY_MENU &&
453 accelerator.type() == ui::ET_KEY_RELEASED) {
454 // The previous must be either an Alt press or Search press:
455 // 3. Press Alt, Press Search, Release Alt, Release Search.
456 // 4. Press Search, Press Alt, Release Alt, Release Search.
457 if (previous_accelerator.type() == ui::ET_KEY_PRESSED &&
458 (previous_accelerator.key_code() == ui::VKEY_LWIN ||
459 previous_accelerator.key_code() == ui::VKEY_MENU)) {
460 return ime && ime->GetImeKeyboard();
461 }
462 }
463
464 return false;
465 }
466
467 void HandleToggleCapsLock() {
468 base::RecordAction(UserMetricsAction("Accel_Toggle_Caps_Lock"));
469 chromeos::input_method::InputMethodManager* ime =
470 chromeos::input_method::InputMethodManager::Get();
471 chromeos::input_method::ImeKeyboard* keyboard = ime->GetImeKeyboard();
472 keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
473 }
474
475 void HandleToggleHighContrast() {
476 base::RecordAction(UserMetricsAction("Accel_Toggle_High_Contrast"));
477
478 // Show a notification so the user knows that this accelerator toggled
479 // high contrast mode, and that they can press it again to toggle back.
480 // The message center automatically only shows this once per session.
481 std::unique_ptr<Notification> notification(new Notification(
482 message_center::NOTIFICATION_TYPE_SIMPLE,
483 kHighContrastToggleAccelNotificationId, base::string16() /* title */,
484 l10n_util::GetStringUTF16(IDS_HIGH_CONTRAST_ACCEL_MSG),
485 gfx::Image(CreateVectorIcon(kSystemMenuAccessibilityIcon, SK_ColorBLACK)),
486 base::string16() /* display source */, GURL(),
487 message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT,
488 system_notifier::kNotifierAccessibility),
489 message_center::RichNotificationData(), nullptr));
490 message_center::MessageCenter::Get()->AddNotification(
491 std::move(notification));
492
493 WmShell::Get()->accessibility_delegate()->ToggleHighContrast();
494 }
495
496 void HandleToggleSpokenFeedback() {
497 base::RecordAction(UserMetricsAction("Accel_Toggle_Spoken_Feedback"));
498
499 WmShell::Get()->accessibility_delegate()->ToggleSpokenFeedback(
500 A11Y_NOTIFICATION_SHOW);
501 }
502
503 void HandleVolumeDown(mojom::VolumeController* volume_controller,
504 const ui::Accelerator& accelerator) {
505 if (accelerator.key_code() == ui::VKEY_VOLUME_DOWN)
506 base::RecordAction(UserMetricsAction("Accel_VolumeDown_F9"));
507
508 if (volume_controller)
509 volume_controller->VolumeDown();
510 }
511
512 void HandleVolumeMute(mojom::VolumeController* volume_controller,
513 const ui::Accelerator& accelerator) {
514 if (accelerator.key_code() == ui::VKEY_VOLUME_MUTE)
515 base::RecordAction(UserMetricsAction("Accel_VolumeMute_F8"));
516
517 if (volume_controller)
518 volume_controller->VolumeMute();
519 }
520
521 void HandleVolumeUp(mojom::VolumeController* volume_controller,
522 const ui::Accelerator& accelerator) {
523 if (accelerator.key_code() == ui::VKEY_VOLUME_UP)
524 base::RecordAction(UserMetricsAction("Accel_VolumeUp_F10"));
525
526 if (volume_controller)
527 volume_controller->VolumeUp();
528 }
529
530 } // namespace
531
532 ////////////////////////////////////////////////////////////////////////////////
533 // AcceleratorController, public:
534
535 AcceleratorController::AcceleratorController(
536 AcceleratorControllerDelegate* delegate,
537 ui::AcceleratorManagerDelegate* manager_delegate)
538 : delegate_(delegate),
539 accelerator_manager_(new ui::AcceleratorManager(manager_delegate)),
540 accelerator_history_(new ui::AcceleratorHistory) {
541 Init();
542 }
543
544 AcceleratorController::~AcceleratorController() {}
545
546 void AcceleratorController::Register(
547 const std::vector<ui::Accelerator>& accelerators,
548 ui::AcceleratorTarget* target) {
549 accelerator_manager_->Register(
550 accelerators, ui::AcceleratorManager::kNormalPriority, target);
551 }
552
553 void AcceleratorController::Unregister(const ui::Accelerator& accelerator,
554 ui::AcceleratorTarget* target) {
555 accelerator_manager_->Unregister(accelerator, target);
556 }
557
558 void AcceleratorController::UnregisterAll(ui::AcceleratorTarget* target) {
559 accelerator_manager_->UnregisterAll(target);
560 }
561
562 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
563 return accelerator_manager_->Process(accelerator);
564 }
565
566 bool AcceleratorController::IsRegistered(
567 const ui::Accelerator& accelerator) const {
568 return accelerator_manager_->IsRegistered(accelerator);
569 }
570
571 bool AcceleratorController::IsPreferred(
572 const ui::Accelerator& accelerator) const {
573 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
574 accelerators_.find(accelerator);
575 if (iter == accelerators_.end())
576 return false; // not an accelerator.
577
578 return preferred_actions_.find(iter->second) != preferred_actions_.end();
579 }
580
581 bool AcceleratorController::IsReserved(
582 const ui::Accelerator& accelerator) const {
583 std::map<ui::Accelerator, AcceleratorAction>::const_iterator iter =
584 accelerators_.find(accelerator);
585 if (iter == accelerators_.end())
586 return false; // not an accelerator.
587
588 return reserved_actions_.find(iter->second) != reserved_actions_.end();
589 }
590
591 bool AcceleratorController::IsDeprecated(
592 const ui::Accelerator& accelerator) const {
593 return deprecated_accelerators_.count(accelerator) != 0;
594 }
595
596 bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) {
597 if (CanPerformAction(action, ui::Accelerator())) {
598 PerformAction(action, ui::Accelerator());
599 return true;
600 }
601 return false;
602 }
603
604 AcceleratorController::AcceleratorProcessingRestriction
605 AcceleratorController::GetCurrentAcceleratorRestriction() {
606 return GetAcceleratorProcessingRestriction(-1);
607 }
608
609 void AcceleratorController::SetImeControlDelegate(
610 std::unique_ptr<ImeControlDelegate> ime_control_delegate) {
611 ime_control_delegate_ = std::move(ime_control_delegate);
612 }
613
614 bool AcceleratorController::ShouldCloseMenuAndRepostAccelerator(
615 const ui::Accelerator& accelerator) const {
616 auto itr = accelerators_.find(accelerator);
617 if (itr == accelerators_.end())
618 return false; // Menu shouldn't be closed for an invalid accelerator.
619
620 AcceleratorAction action = itr->second;
621 return actions_keeping_menu_open_.count(action) == 0;
622 }
623
624 ////////////////////////////////////////////////////////////////////////////////
625 // AcceleratorController, ui::AcceleratorTarget implementation:
626
627 bool AcceleratorController::AcceleratorPressed(
628 const ui::Accelerator& accelerator) {
629 std::map<ui::Accelerator, AcceleratorAction>::const_iterator it =
630 accelerators_.find(accelerator);
631 DCHECK(it != accelerators_.end());
632 AcceleratorAction action = it->second;
633 if (!CanPerformAction(action, accelerator))
634 return false;
635
636 // Handling the deprecated accelerators (if any) only if action can be
637 // performed.
638 if (MaybeDeprecatedAcceleratorPressed(action, accelerator) ==
639 AcceleratorProcessingStatus::STOP) {
640 return false;
641 }
642
643 PerformAction(action, accelerator);
644 return ShouldActionConsumeKeyEvent(action);
645 }
646
647 bool AcceleratorController::CanHandleAccelerators() const {
648 return true;
649 }
650
651 void AcceleratorController::BindRequest(
652 mojom::AcceleratorControllerRequest request) {
653 bindings_.AddBinding(this, std::move(request));
654 }
655
656 void AcceleratorController::SetVolumeController(
657 mojom::VolumeControllerPtr controller) {
658 volume_controller_ = std::move(controller);
659 }
660
661 ///////////////////////////////////////////////////////////////////////////////
662 // AcceleratorController, private:
663
664 void AcceleratorController::Init() {
665 for (size_t i = 0; i < kActionsAllowedAtLoginOrLockScreenLength; ++i) {
666 actions_allowed_at_login_screen_.insert(
667 kActionsAllowedAtLoginOrLockScreen[i]);
668 actions_allowed_at_lock_screen_.insert(
669 kActionsAllowedAtLoginOrLockScreen[i]);
670 }
671 for (size_t i = 0; i < kActionsAllowedAtLockScreenLength; ++i)
672 actions_allowed_at_lock_screen_.insert(kActionsAllowedAtLockScreen[i]);
673 for (size_t i = 0; i < kActionsAllowedAtModalWindowLength; ++i)
674 actions_allowed_at_modal_window_.insert(kActionsAllowedAtModalWindow[i]);
675 for (size_t i = 0; i < kPreferredActionsLength; ++i)
676 preferred_actions_.insert(kPreferredActions[i]);
677 for (size_t i = 0; i < kReservedActionsLength; ++i)
678 reserved_actions_.insert(kReservedActions[i]);
679 for (size_t i = 0; i < kRepeatableActionsLength; ++i)
680 repeatable_actions_.insert(kRepeatableActions[i]);
681 for (size_t i = 0; i < kActionsAllowedInAppModeOrPinnedModeLength; ++i) {
682 actions_allowed_in_app_mode_.insert(
683 kActionsAllowedInAppModeOrPinnedMode[i]);
684 actions_allowed_in_pinned_mode_.insert(
685 kActionsAllowedInAppModeOrPinnedMode[i]);
686 }
687 for (size_t i = 0; i < kActionsAllowedInPinnedModeLength; ++i)
688 actions_allowed_in_pinned_mode_.insert(kActionsAllowedInPinnedMode[i]);
689 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i)
690 actions_needing_window_.insert(kActionsNeedingWindow[i]);
691 for (size_t i = 0; i < kActionsKeepingMenuOpenLength; ++i)
692 actions_keeping_menu_open_.insert(kActionsKeepingMenuOpen[i]);
693
694 RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
695
696 RegisterDeprecatedAccelerators();
697
698 if (debug::DebugAcceleratorsEnabled()) {
699 RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
700 // All debug accelerators are reserved.
701 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
702 reserved_actions_.insert(kDebugAcceleratorData[i].action);
703 }
704
705 if (debug::DeveloperAcceleratorsEnabled()) {
706 RegisterAccelerators(kDeveloperAcceleratorData,
707 kDeveloperAcceleratorDataLength);
708 // Developer accelerators are also reserved.
709 for (size_t i = 0; i < kDeveloperAcceleratorDataLength; ++i)
710 reserved_actions_.insert(kDeveloperAcceleratorData[i].action);
711 }
712 }
713
714 void AcceleratorController::RegisterAccelerators(
715 const AcceleratorData accelerators[],
716 size_t accelerators_length) {
717 std::vector<ui::Accelerator> ui_accelerators;
718 for (size_t i = 0; i < accelerators_length; ++i) {
719 ui::Accelerator accelerator =
720 CreateAccelerator(accelerators[i].keycode, accelerators[i].modifiers,
721 accelerators[i].trigger_on_press);
722 ui_accelerators.push_back(accelerator);
723 accelerators_.insert(std::make_pair(accelerator, accelerators[i].action));
724 }
725 Register(ui_accelerators, this);
726 }
727
728 void AcceleratorController::RegisterDeprecatedAccelerators() {
729 for (size_t i = 0; i < kDeprecatedAcceleratorsDataLength; ++i) {
730 const DeprecatedAcceleratorData* data = &kDeprecatedAcceleratorsData[i];
731 actions_with_deprecations_[data->action] = data;
732 }
733
734 std::vector<ui::Accelerator> ui_accelerators;
735 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) {
736 const AcceleratorData& accelerator_data = kDeprecatedAccelerators[i];
737 const ui::Accelerator deprecated_accelerator =
738 CreateAccelerator(accelerator_data.keycode, accelerator_data.modifiers,
739 accelerator_data.trigger_on_press);
740
741 ui_accelerators.push_back(deprecated_accelerator);
742 accelerators_[deprecated_accelerator] = accelerator_data.action;
743 deprecated_accelerators_.insert(deprecated_accelerator);
744 }
745 Register(ui_accelerators, this);
746 }
747
748 bool AcceleratorController::CanPerformAction(
749 AcceleratorAction action,
750 const ui::Accelerator& accelerator) {
751 if (accelerator.IsRepeat() && !repeatable_actions_.count(action))
752 return false;
753
754 AcceleratorProcessingRestriction restriction =
755 GetAcceleratorProcessingRestriction(action);
756 if (restriction != RESTRICTION_NONE)
757 return restriction == RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
758
759 const ui::Accelerator& previous_accelerator =
760 accelerator_history_->previous_accelerator();
761
762 // True should be returned if running |action| does something. Otherwise,
763 // false should be returned to give the web contents a chance at handling the
764 // accelerator.
765 switch (action) {
766 case CYCLE_BACKWARD_MRU:
767 case CYCLE_FORWARD_MRU:
768 return CanHandleCycleMru(accelerator);
769 case DEBUG_PRINT_LAYER_HIERARCHY:
770 case DEBUG_PRINT_VIEW_HIERARCHY:
771 case DEBUG_PRINT_WINDOW_HIERARCHY:
772 case DEBUG_SHOW_TOAST:
773 case DEBUG_TOGGLE_TOUCH_PAD:
774 case DEBUG_TOGGLE_TOUCH_SCREEN:
775 case DEBUG_TOGGLE_TOUCH_VIEW:
776 case DEBUG_TOGGLE_WALLPAPER_MODE:
777 case DEBUG_TRIGGER_CRASH:
778 return debug::DebugAcceleratorsEnabled();
779 case DISABLE_CAPS_LOCK:
780 return CanHandleDisableCapsLock(previous_accelerator);
781 case LOCK_SCREEN:
782 return CanHandleLock();
783 case NEW_INCOGNITO_WINDOW:
784 return CanHandleNewIncognitoWindow();
785 case NEXT_IME:
786 return CanHandleNextIme(ime_control_delegate_.get());
787 case PREVIOUS_IME:
788 return CanHandlePreviousIme(ime_control_delegate_.get());
789 case SHOW_MESSAGE_CENTER_BUBBLE:
790 return CanHandleShowMessageCenterBubble();
791 case SHOW_STYLUS_TOOLS:
792 return CanHandleShowStylusTools();
793 case SWITCH_IME:
794 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
795 case SWITCH_TO_PREVIOUS_USER:
796 case SWITCH_TO_NEXT_USER:
797 return CanHandleCycleUser();
798 case TOGGLE_APP_LIST:
799 return CanHandleToggleAppList(accelerator, previous_accelerator);
800 case TOGGLE_CAPS_LOCK:
801 return CanHandleToggleCapsLock(accelerator, previous_accelerator);
802 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
803 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
804 return CanHandleWindowSnapOrDock();
805 case WINDOW_POSITION_CENTER:
806 return CanHandlePositionCenter();
807
808 // The following are always enabled.
809 case BRIGHTNESS_DOWN:
810 case BRIGHTNESS_UP:
811 case EXIT:
812 case FOCUS_NEXT_PANE:
813 case FOCUS_PREVIOUS_PANE:
814 case FOCUS_SHELF:
815 case KEYBOARD_BRIGHTNESS_DOWN:
816 case KEYBOARD_BRIGHTNESS_UP:
817 case LAUNCH_APP_0:
818 case LAUNCH_APP_1:
819 case LAUNCH_APP_2:
820 case LAUNCH_APP_3:
821 case LAUNCH_APP_4:
822 case LAUNCH_APP_5:
823 case LAUNCH_APP_6:
824 case LAUNCH_APP_7:
825 case LAUNCH_LAST_APP:
826 case MEDIA_NEXT_TRACK:
827 case MEDIA_PLAY_PAUSE:
828 case MEDIA_PREV_TRACK:
829 case NEW_TAB:
830 case NEW_WINDOW:
831 case OPEN_CROSH:
832 case OPEN_FEEDBACK_PAGE:
833 case OPEN_FILE_MANAGER:
834 case OPEN_GET_HELP:
835 case PRINT_UI_HIERARCHIES:
836 case RESTORE_TAB:
837 case SHOW_IME_MENU_BUBBLE:
838 case SHOW_KEYBOARD_OVERLAY:
839 case SHOW_TASK_MANAGER:
840 case SUSPEND:
841 case TOGGLE_FULLSCREEN:
842 case TOGGLE_HIGH_CONTRAST:
843 case TOGGLE_MAXIMIZED:
844 case TOGGLE_OVERVIEW:
845 case TOGGLE_SPOKEN_FEEDBACK:
846 case TOGGLE_WIFI:
847 case VOLUME_DOWN:
848 case VOLUME_MUTE:
849 case VOLUME_UP:
850 case WINDOW_MINIMIZE:
851 return true;
852
853 default:
854 // Default switch is temporary until mash transition complete. Needed as
855 // some actions don't yet work with mash.
856 break;
857 }
858 return delegate_ && delegate_->HandlesAction(action) &&
859 delegate_->CanPerformAction(action, accelerator, previous_accelerator);
860 }
861
862 void AcceleratorController::PerformAction(AcceleratorAction action,
863 const ui::Accelerator& accelerator) {
864 AcceleratorProcessingRestriction restriction =
865 GetAcceleratorProcessingRestriction(action);
866 if (restriction != RESTRICTION_NONE)
867 return;
868
869 // If your accelerator invokes more than one line of code, please either
870 // implement it in your module's controller code or pull it into a HandleFoo()
871 // function above.
872 switch (action) {
873 case BRIGHTNESS_DOWN: {
874 BrightnessControlDelegate* delegate =
875 WmShell::Get()->brightness_control_delegate();
876 if (delegate)
877 delegate->HandleBrightnessDown(accelerator);
878 break;
879 }
880 case BRIGHTNESS_UP: {
881 BrightnessControlDelegate* delegate =
882 WmShell::Get()->brightness_control_delegate();
883 if (delegate)
884 delegate->HandleBrightnessUp(accelerator);
885 break;
886 }
887 case CYCLE_BACKWARD_MRU:
888 HandleCycleBackwardMRU(accelerator);
889 break;
890 case CYCLE_FORWARD_MRU:
891 HandleCycleForwardMRU(accelerator);
892 break;
893 case DEBUG_PRINT_LAYER_HIERARCHY:
894 case DEBUG_PRINT_VIEW_HIERARCHY:
895 case DEBUG_PRINT_WINDOW_HIERARCHY:
896 case DEBUG_SHOW_TOAST:
897 case DEBUG_TOGGLE_TOUCH_PAD:
898 case DEBUG_TOGGLE_TOUCH_SCREEN:
899 case DEBUG_TOGGLE_TOUCH_VIEW:
900 case DEBUG_TOGGLE_WALLPAPER_MODE:
901 case DEBUG_TRIGGER_CRASH:
902 debug::PerformDebugActionIfEnabled(action);
903 break;
904 case DISABLE_CAPS_LOCK:
905 HandleDisableCapsLock();
906 break;
907 case EXIT:
908 // UMA metrics are recorded in the handler.
909 exit_warning_handler_.HandleAccelerator();
910 break;
911 case FOCUS_NEXT_PANE:
912 HandleRotatePaneFocus(FocusCycler::FORWARD);
913 break;
914 case FOCUS_PREVIOUS_PANE:
915 HandleRotatePaneFocus(FocusCycler::BACKWARD);
916 break;
917 case FOCUS_SHELF:
918 HandleFocusShelf();
919 break;
920 case KEYBOARD_BRIGHTNESS_DOWN: {
921 KeyboardBrightnessControlDelegate* delegate =
922 WmShell::Get()->keyboard_brightness_control_delegate();
923 if (delegate)
924 delegate->HandleKeyboardBrightnessDown(accelerator);
925 break;
926 }
927 case KEYBOARD_BRIGHTNESS_UP: {
928 KeyboardBrightnessControlDelegate* delegate =
929 WmShell::Get()->keyboard_brightness_control_delegate();
930 if (delegate)
931 delegate->HandleKeyboardBrightnessUp(accelerator);
932 break;
933 }
934 case LAUNCH_APP_0:
935 HandleLaunchAppN(0);
936 break;
937 case LAUNCH_APP_1:
938 HandleLaunchAppN(1);
939 break;
940 case LAUNCH_APP_2:
941 HandleLaunchAppN(2);
942 break;
943 case LAUNCH_APP_3:
944 HandleLaunchAppN(3);
945 break;
946 case LAUNCH_APP_4:
947 HandleLaunchAppN(4);
948 break;
949 case LAUNCH_APP_5:
950 HandleLaunchAppN(5);
951 break;
952 case LAUNCH_APP_6:
953 HandleLaunchAppN(6);
954 break;
955 case LAUNCH_APP_7:
956 HandleLaunchAppN(7);
957 break;
958 case LAUNCH_LAST_APP:
959 HandleLaunchLastApp();
960 break;
961 case LOCK_SCREEN:
962 HandleLock();
963 break;
964 case MEDIA_NEXT_TRACK:
965 HandleMediaNextTrack();
966 break;
967 case MEDIA_PLAY_PAUSE:
968 HandleMediaPlayPause();
969 break;
970 case MEDIA_PREV_TRACK:
971 HandleMediaPrevTrack();
972 break;
973 case NEW_INCOGNITO_WINDOW:
974 HandleNewIncognitoWindow();
975 break;
976 case NEW_TAB:
977 HandleNewTab(accelerator);
978 break;
979 case NEW_WINDOW:
980 HandleNewWindow();
981 break;
982 case NEXT_IME:
983 HandleNextIme(ime_control_delegate_.get());
984 break;
985 case OPEN_CROSH:
986 HandleCrosh();
987 break;
988 case OPEN_FEEDBACK_PAGE:
989 HandleOpenFeedbackPage();
990 break;
991 case OPEN_FILE_MANAGER:
992 HandleFileManager();
993 break;
994 case OPEN_GET_HELP:
995 HandleGetHelp();
996 break;
997 case PREVIOUS_IME:
998 HandlePreviousIme(ime_control_delegate_.get(), accelerator);
999 break;
1000 case PRINT_UI_HIERARCHIES:
1001 debug::PrintUIHierarchies();
1002 break;
1003 case RESTORE_TAB:
1004 HandleRestoreTab();
1005 break;
1006 case SHOW_IME_MENU_BUBBLE:
1007 HandleShowImeMenuBubble();
1008 break;
1009 case SHOW_KEYBOARD_OVERLAY:
1010 HandleShowKeyboardOverlay();
1011 break;
1012 case SHOW_MESSAGE_CENTER_BUBBLE:
1013 HandleShowMessageCenterBubble();
1014 break;
1015 case SHOW_STYLUS_TOOLS:
1016 HandleShowStylusTools();
1017 break;
1018 case SHOW_TASK_MANAGER:
1019 HandleShowTaskManager();
1020 break;
1021 case SUSPEND:
1022 HandleSuspend();
1023 break;
1024 case SWITCH_IME:
1025 HandleSwitchIme(ime_control_delegate_.get(), accelerator);
1026 break;
1027 case SWITCH_TO_NEXT_USER:
1028 HandleCycleUser(CycleUserDirection::NEXT);
1029 break;
1030 case SWITCH_TO_PREVIOUS_USER:
1031 HandleCycleUser(CycleUserDirection::PREVIOUS);
1032 break;
1033 case TOGGLE_APP_LIST:
1034 HandleToggleAppList(accelerator);
1035 break;
1036 case TOGGLE_CAPS_LOCK:
1037 HandleToggleCapsLock();
1038 break;
1039 case TOGGLE_FULLSCREEN:
1040 HandleToggleFullscreen(accelerator);
1041 break;
1042 case TOGGLE_HIGH_CONTRAST:
1043 HandleToggleHighContrast();
1044 break;
1045 case TOGGLE_MAXIMIZED:
1046 accelerators::ToggleMaximized();
1047 break;
1048 case TOGGLE_OVERVIEW:
1049 HandleToggleOverview();
1050 break;
1051 case TOGGLE_SPOKEN_FEEDBACK:
1052 HandleToggleSpokenFeedback();
1053 break;
1054 case TOGGLE_WIFI:
1055 WmShell::Get()->system_tray_notifier()->NotifyRequestToggleWifi();
1056 break;
1057 case VOLUME_DOWN:
1058 HandleVolumeDown(volume_controller_.get(), accelerator);
1059 break;
1060 case VOLUME_MUTE:
1061 HandleVolumeMute(volume_controller_.get(), accelerator);
1062 break;
1063 case VOLUME_UP:
1064 HandleVolumeUp(volume_controller_.get(), accelerator);
1065 break;
1066 case WINDOW_CYCLE_SNAP_DOCK_LEFT:
1067 case WINDOW_CYCLE_SNAP_DOCK_RIGHT:
1068 HandleWindowSnapOrDock(action);
1069 break;
1070 case WINDOW_MINIMIZE:
1071 HandleWindowMinimize();
1072 break;
1073 case WINDOW_POSITION_CENTER:
1074 HandlePositionCenter();
1075 break;
1076 default:
1077 // Temporary until mash transition complete. Needed as some actions
1078 // don't yet work with mash.
1079 DCHECK(delegate_ && delegate_->HandlesAction(action));
1080 delegate_->PerformAction(action, accelerator);
1081 break;
1082 }
1083 }
1084
1085 bool AcceleratorController::ShouldActionConsumeKeyEvent(
1086 AcceleratorAction action) {
1087 // Adding new exceptions is *STRONGLY* discouraged.
1088 return true;
1089 }
1090
1091 AcceleratorController::AcceleratorProcessingRestriction
1092 AcceleratorController::GetAcceleratorProcessingRestriction(int action) {
1093 WmShell* wm_shell = WmShell::Get();
1094 if (wm_shell->IsPinned() &&
1095 actions_allowed_in_pinned_mode_.find(action) ==
1096 actions_allowed_in_pinned_mode_.end()) {
1097 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1098 }
1099 // TODO(xiyuan): Replace with SessionController. http://crbug.com/648964
1100 if (!wm_shell->GetSessionStateDelegate()->IsActiveUserSessionStarted() &&
1101 actions_allowed_at_login_screen_.find(action) ==
1102 actions_allowed_at_login_screen_.end()) {
1103 return RESTRICTION_PREVENT_PROCESSING;
1104 }
1105 if (wm_shell->GetSessionStateDelegate()->IsScreenLocked() &&
1106 actions_allowed_at_lock_screen_.find(action) ==
1107 actions_allowed_at_lock_screen_.end()) {
1108 return RESTRICTION_PREVENT_PROCESSING;
1109 }
1110 if (wm_shell->delegate()->IsRunningInForcedAppMode() &&
1111 actions_allowed_in_app_mode_.find(action) ==
1112 actions_allowed_in_app_mode_.end()) {
1113 return RESTRICTION_PREVENT_PROCESSING;
1114 }
1115 if (WmShell::Get()->IsSystemModalWindowOpen() &&
1116 actions_allowed_at_modal_window_.find(action) ==
1117 actions_allowed_at_modal_window_.end()) {
1118 // Note we prevent the shortcut from propagating so it will not
1119 // be passed to the modal window. This is important for things like
1120 // Alt+Tab that would cause an undesired effect in the modal window by
1121 // cycling through its window elements.
1122 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1123 }
1124 if (wm_shell->mru_window_tracker()->BuildMruWindowList().empty() &&
1125 actions_needing_window_.find(action) != actions_needing_window_.end()) {
1126 wm_shell->accessibility_delegate()->TriggerAccessibilityAlert(
1127 A11Y_ALERT_WINDOW_NEEDED);
1128 return RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
1129 }
1130 return RESTRICTION_NONE;
1131 }
1132
1133 AcceleratorController::AcceleratorProcessingStatus
1134 AcceleratorController::MaybeDeprecatedAcceleratorPressed(
1135 AcceleratorAction action,
1136 const ui::Accelerator& accelerator) const {
1137 auto itr = actions_with_deprecations_.find(action);
1138 if (itr == actions_with_deprecations_.end()) {
1139 // The action is not associated with any deprecated accelerators, and hence
1140 // should be performed normally.
1141 return AcceleratorProcessingStatus::PROCEED;
1142 }
1143
1144 // This action is associated with new and deprecated accelerators, find which
1145 // one is |accelerator|.
1146 const DeprecatedAcceleratorData* data = itr->second;
1147 if (!deprecated_accelerators_.count(accelerator)) {
1148 // This is a new accelerator replacing the old deprecated one.
1149 // Record UMA stats and proceed normally to perform it.
1150 RecordUmaHistogram(data->uma_histogram_name, NEW_USED);
1151 return AcceleratorProcessingStatus::PROCEED;
1152 }
1153
1154 // This accelerator has been deprecated and should be treated according
1155 // to its |DeprecatedAcceleratorData|.
1156
1157 // Record UMA stats.
1158 RecordUmaHistogram(data->uma_histogram_name, DEPRECATED_USED);
1159
1160 if (delegate_) {
1161 // We always display the notification as long as this |data| entry exists.
1162 delegate_->ShowDeprecatedAcceleratorNotification(
1163 data->uma_histogram_name, data->notification_message_id,
1164 data->old_shortcut_id, data->new_shortcut_id);
1165 }
1166
1167 if (!data->deprecated_enabled)
1168 return AcceleratorProcessingStatus::STOP;
1169
1170 return AcceleratorProcessingStatus::PROCEED;
1171 }
1172
1173 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/accelerators/accelerator_controller.h ('k') | ash/common/accelerators/accelerator_controller_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698