OLD | NEW |
| (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 "ash/common/accelerators/accelerator_table.h" | |
8 #include "ash/common/accessibility_delegate.h" | |
9 #include "ash/common/accessibility_types.h" | |
10 #include "ash/common/ash_switches.h" | |
11 #include "ash/common/ime_control_delegate.h" | |
12 #include "ash/common/session/session_state_delegate.h" | |
13 #include "ash/common/system/brightness_control_delegate.h" | |
14 #include "ash/common/system/keyboard_brightness_control_delegate.h" | |
15 #include "ash/common/system/tray/system_tray_delegate.h" | |
16 #include "ash/common/test/ash_test.h" | |
17 #include "ash/common/wm/panels/panel_layout_manager.h" | |
18 #include "ash/common/wm/window_positioning_utils.h" | |
19 #include "ash/common/wm/window_state.h" | |
20 #include "ash/common/wm/wm_event.h" | |
21 #include "ash/common/wm_lookup.h" | |
22 #include "ash/common/wm_shell.h" | |
23 #include "ash/common/wm_window.h" | |
24 #include "ash/mus/accelerators/accelerator_controller_registrar_test_api.h" | |
25 #include "ash/mus/bridge/wm_shell_mus_test_api.h" | |
26 #include "ash/mus/property_util.h" | |
27 #include "ash/mus/test/wm_test_base.h" | |
28 #include "ash/public/cpp/shell_window_ids.h" | |
29 #include "ash/root_window_controller.h" | |
30 #include "base/command_line.h" | |
31 #include "base/test/user_action_tester.cc" | |
32 #include "services/ui/public/interfaces/window_manager.mojom.h" | |
33 #include "ui/aura/client/aura_constants.h" | |
34 #include "ui/aura/window.h" | |
35 #include "ui/events/event.h" | |
36 #include "ui/events/event_processor.h" | |
37 #include "ui/events/test/event_generator.h" | |
38 #include "ui/message_center/message_center.h" | |
39 #include "ui/views/widget/widget.h" | |
40 | |
41 #if defined(USE_X11) | |
42 #include <X11/Xlib.h> | |
43 #include "ui/events/test/events_test_utils_x11.h" | |
44 #endif | |
45 | |
46 namespace ash { | |
47 | |
48 namespace { | |
49 | |
50 class TestTarget : public ui::AcceleratorTarget { | |
51 public: | |
52 TestTarget() : accelerator_pressed_count_(0), accelerator_repeat_count_(0) {} | |
53 ~TestTarget() override {} | |
54 | |
55 int accelerator_pressed_count() const { return accelerator_pressed_count_; } | |
56 | |
57 int accelerator_repeat_count() const { return accelerator_repeat_count_; } | |
58 | |
59 void reset() { | |
60 accelerator_pressed_count_ = 0; | |
61 accelerator_repeat_count_ = 0; | |
62 } | |
63 | |
64 // Overridden from ui::AcceleratorTarget: | |
65 bool AcceleratorPressed(const ui::Accelerator& accelerator) override; | |
66 bool CanHandleAccelerators() const override; | |
67 | |
68 private: | |
69 int accelerator_pressed_count_; | |
70 int accelerator_repeat_count_; | |
71 | |
72 DISALLOW_COPY_AND_ASSIGN(TestTarget); | |
73 }; | |
74 | |
75 class ReleaseAccelerator : public ui::Accelerator { | |
76 public: | |
77 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers) | |
78 : ui::Accelerator(keycode, modifiers) { | |
79 set_type(ui::ET_KEY_RELEASED); | |
80 } | |
81 }; | |
82 | |
83 class DummyBrightnessControlDelegate : public BrightnessControlDelegate { | |
84 public: | |
85 DummyBrightnessControlDelegate() | |
86 : handle_brightness_down_count_(0), handle_brightness_up_count_(0) {} | |
87 ~DummyBrightnessControlDelegate() override {} | |
88 | |
89 void HandleBrightnessDown(const ui::Accelerator& accelerator) override { | |
90 ++handle_brightness_down_count_; | |
91 last_accelerator_ = accelerator; | |
92 } | |
93 void HandleBrightnessUp(const ui::Accelerator& accelerator) override { | |
94 ++handle_brightness_up_count_; | |
95 last_accelerator_ = accelerator; | |
96 } | |
97 void SetBrightnessPercent(double percent, bool gradual) override {} | |
98 void GetBrightnessPercent( | |
99 const base::Callback<void(double)>& callback) override { | |
100 callback.Run(100.0); | |
101 } | |
102 | |
103 int handle_brightness_down_count() const { | |
104 return handle_brightness_down_count_; | |
105 } | |
106 int handle_brightness_up_count() const { return handle_brightness_up_count_; } | |
107 const ui::Accelerator& last_accelerator() const { return last_accelerator_; } | |
108 | |
109 private: | |
110 int handle_brightness_down_count_; | |
111 int handle_brightness_up_count_; | |
112 ui::Accelerator last_accelerator_; | |
113 | |
114 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate); | |
115 }; | |
116 | |
117 class DummyImeControlDelegate : public ImeControlDelegate { | |
118 public: | |
119 DummyImeControlDelegate() | |
120 : handle_next_ime_count_(0), | |
121 handle_previous_ime_count_(0), | |
122 handle_switch_ime_count_(0) {} | |
123 ~DummyImeControlDelegate() override {} | |
124 | |
125 bool CanCycleIme() override { return true; } | |
126 void HandleNextIme() override { ++handle_next_ime_count_; } | |
127 void HandlePreviousIme() override { ++handle_previous_ime_count_; } | |
128 bool CanSwitchIme(const ui::Accelerator& accelerator) override { | |
129 return true; | |
130 } | |
131 void HandleSwitchIme(const ui::Accelerator& accelerator) override { | |
132 ++handle_switch_ime_count_; | |
133 } | |
134 | |
135 int handle_next_ime_count() const { return handle_next_ime_count_; } | |
136 int handle_previous_ime_count() const { return handle_previous_ime_count_; } | |
137 int handle_switch_ime_count() const { return handle_switch_ime_count_; } | |
138 | |
139 private: | |
140 int handle_next_ime_count_; | |
141 int handle_previous_ime_count_; | |
142 int handle_switch_ime_count_; | |
143 | |
144 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate); | |
145 }; | |
146 | |
147 class DummyKeyboardBrightnessControlDelegate | |
148 : public KeyboardBrightnessControlDelegate { | |
149 public: | |
150 DummyKeyboardBrightnessControlDelegate() | |
151 : handle_keyboard_brightness_down_count_(0), | |
152 handle_keyboard_brightness_up_count_(0) {} | |
153 ~DummyKeyboardBrightnessControlDelegate() override {} | |
154 | |
155 void HandleKeyboardBrightnessDown( | |
156 const ui::Accelerator& accelerator) override { | |
157 ++handle_keyboard_brightness_down_count_; | |
158 last_accelerator_ = accelerator; | |
159 } | |
160 | |
161 void HandleKeyboardBrightnessUp(const ui::Accelerator& accelerator) override { | |
162 ++handle_keyboard_brightness_up_count_; | |
163 last_accelerator_ = accelerator; | |
164 } | |
165 | |
166 int handle_keyboard_brightness_down_count() const { | |
167 return handle_keyboard_brightness_down_count_; | |
168 } | |
169 | |
170 int handle_keyboard_brightness_up_count() const { | |
171 return handle_keyboard_brightness_up_count_; | |
172 } | |
173 | |
174 const ui::Accelerator& last_accelerator() const { return last_accelerator_; } | |
175 | |
176 private: | |
177 int handle_keyboard_brightness_down_count_; | |
178 int handle_keyboard_brightness_up_count_; | |
179 ui::Accelerator last_accelerator_; | |
180 | |
181 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate); | |
182 }; | |
183 | |
184 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) { | |
185 if (accelerator.IsRepeat()) | |
186 ++accelerator_repeat_count_; | |
187 else | |
188 ++accelerator_pressed_count_; | |
189 return true; | |
190 } | |
191 | |
192 bool TestTarget::CanHandleAccelerators() const { | |
193 return true; | |
194 } | |
195 | |
196 void ProcessAccelerator(ui::KeyboardCode key_code, int flags) { | |
197 const ui::Accelerator accelerator(key_code, flags); | |
198 if (!WmShell::Get()->accelerator_controller()->IsRegistered(accelerator)) | |
199 return; | |
200 | |
201 mus::AcceleratorControllerRegistrarTestApi().ProcessAccelerator(accelerator); | |
202 } | |
203 | |
204 } // namespace | |
205 | |
206 class AcceleratorControllerTest : public mus::WmTestBase { | |
207 public: | |
208 AcceleratorControllerTest() {} | |
209 ~AcceleratorControllerTest() override {} | |
210 | |
211 protected: | |
212 static AcceleratorController* GetController(); | |
213 | |
214 static bool ProcessInController(const ui::Accelerator& accelerator) { | |
215 if (accelerator.type() == ui::ET_KEY_RELEASED) { | |
216 // If the |accelerator| should trigger on release, then we store the | |
217 // pressed version of it first in history then the released one to | |
218 // simulate what happens in reality. | |
219 ui::Accelerator pressed_accelerator = accelerator; | |
220 pressed_accelerator.set_type(ui::ET_KEY_PRESSED); | |
221 GetController()->accelerator_history()->StoreCurrentAccelerator( | |
222 pressed_accelerator); | |
223 } | |
224 GetController()->accelerator_history()->StoreCurrentAccelerator( | |
225 accelerator); | |
226 return GetController()->Process(accelerator); | |
227 } | |
228 | |
229 static const ui::Accelerator& GetPreviousAccelerator() { | |
230 return GetController()->accelerator_history()->previous_accelerator(); | |
231 } | |
232 | |
233 static const ui::Accelerator& GetCurrentAccelerator() { | |
234 return GetController()->accelerator_history()->current_accelerator(); | |
235 } | |
236 | |
237 // Several functions to access ExitWarningHandler (as friend). | |
238 static void StubForTest(ExitWarningHandler* ewh) { | |
239 ewh->stub_timer_for_test_ = true; | |
240 } | |
241 static void Reset(ExitWarningHandler* ewh) { | |
242 ewh->state_ = ExitWarningHandler::IDLE; | |
243 } | |
244 static void SimulateTimerExpired(ExitWarningHandler* ewh) { | |
245 ewh->TimerAction(); | |
246 } | |
247 static bool is_ui_shown(ExitWarningHandler* ewh) { return !!ewh->widget_; } | |
248 static bool is_idle(ExitWarningHandler* ewh) { | |
249 return ewh->state_ == ExitWarningHandler::IDLE; | |
250 } | |
251 static bool is_exiting(ExitWarningHandler* ewh) { | |
252 return ewh->state_ == ExitWarningHandler::EXITING; | |
253 } | |
254 // TODO: needs support for TestShelfDelegate: http://crbug.com/632208. | |
255 /* | |
256 ui::Window* CreatePanel() { | |
257 ui::Window* window = CreateTestWindow( | |
258 gfx::Rect(5, 5, 20, 20), | |
259 ui::wm::WINDOW_TYPE_PANEL); | |
260 test::TestShelfDelegate* shelf_delegate = | |
261 test::TestShelfDelegate::instance(); | |
262 shelf_delegate->AddShelfItem(window); | |
263 PanelLayoutManager* manager = | |
264 PanelLayoutManager::Get(WmWindow::Get(window)); | |
265 manager->Relayout(); | |
266 return window; | |
267 } | |
268 */ | |
269 | |
270 void SetBrightnessControlDelegate( | |
271 std::unique_ptr<BrightnessControlDelegate> delegate) { | |
272 WmShell::Get()->brightness_control_delegate_ = std::move(delegate); | |
273 } | |
274 | |
275 void SetKeyboardBrightnessControlDelegate( | |
276 std::unique_ptr<KeyboardBrightnessControlDelegate> delegate) { | |
277 WmShell::Get()->keyboard_brightness_control_delegate_ = std::move(delegate); | |
278 } | |
279 | |
280 private: | |
281 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest); | |
282 }; | |
283 | |
284 AcceleratorController* AcceleratorControllerTest::GetController() { | |
285 return WmShell::Get()->accelerator_controller(); | |
286 } | |
287 | |
288 #if !defined(OS_WIN) | |
289 // Double press of exit shortcut => exiting | |
290 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { | |
291 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); | |
292 ui::Accelerator release(press); | |
293 release.set_type(ui::ET_KEY_RELEASED); | |
294 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); | |
295 ASSERT_TRUE(ewh); | |
296 StubForTest(ewh); | |
297 EXPECT_TRUE(is_idle(ewh)); | |
298 EXPECT_FALSE(is_ui_shown(ewh)); | |
299 EXPECT_TRUE(ProcessInController(press)); | |
300 EXPECT_FALSE(ProcessInController(release)); | |
301 EXPECT_FALSE(is_idle(ewh)); | |
302 EXPECT_TRUE(is_ui_shown(ewh)); | |
303 EXPECT_TRUE(ProcessInController(press)); // second press before timer. | |
304 EXPECT_FALSE(ProcessInController(release)); | |
305 SimulateTimerExpired(ewh); | |
306 EXPECT_TRUE(is_exiting(ewh)); | |
307 EXPECT_FALSE(is_ui_shown(ewh)); | |
308 Reset(ewh); | |
309 } | |
310 | |
311 // Single press of exit shortcut before timer => idle | |
312 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) { | |
313 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); | |
314 ui::Accelerator release(press); | |
315 release.set_type(ui::ET_KEY_RELEASED); | |
316 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); | |
317 ASSERT_TRUE(ewh); | |
318 StubForTest(ewh); | |
319 EXPECT_TRUE(is_idle(ewh)); | |
320 EXPECT_FALSE(is_ui_shown(ewh)); | |
321 EXPECT_TRUE(ProcessInController(press)); | |
322 EXPECT_FALSE(ProcessInController(release)); | |
323 EXPECT_FALSE(is_idle(ewh)); | |
324 EXPECT_TRUE(is_ui_shown(ewh)); | |
325 SimulateTimerExpired(ewh); | |
326 EXPECT_TRUE(is_idle(ewh)); | |
327 EXPECT_FALSE(is_ui_shown(ewh)); | |
328 Reset(ewh); | |
329 } | |
330 | |
331 // Shutdown ash with exit warning bubble open should not crash. | |
332 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) { | |
333 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); | |
334 ASSERT_TRUE(ewh); | |
335 StubForTest(ewh); | |
336 | |
337 // Trigger once to show the bubble. | |
338 ewh->HandleAccelerator(); | |
339 EXPECT_FALSE(is_idle(ewh)); | |
340 EXPECT_TRUE(is_ui_shown(ewh)); | |
341 | |
342 // Exit ash and there should be no crash | |
343 } | |
344 #endif // !defined(OS_WIN) | |
345 | |
346 TEST_F(AcceleratorControllerTest, Register) { | |
347 TestTarget target; | |
348 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
349 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE); | |
350 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE); | |
351 const ui::Accelerator accelerator_d(ui::VKEY_D, ui::EF_NONE); | |
352 | |
353 GetController()->Register( | |
354 {accelerator_a, accelerator_b, accelerator_c, accelerator_d}, &target); | |
355 | |
356 // The registered accelerators are processed. | |
357 EXPECT_TRUE(ProcessInController(accelerator_a)); | |
358 EXPECT_TRUE(ProcessInController(accelerator_b)); | |
359 EXPECT_TRUE(ProcessInController(accelerator_c)); | |
360 EXPECT_TRUE(ProcessInController(accelerator_d)); | |
361 EXPECT_EQ(4, target.accelerator_pressed_count()); | |
362 } | |
363 | |
364 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) { | |
365 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
366 TestTarget target1; | |
367 GetController()->Register({accelerator_a}, &target1); | |
368 | |
369 TestTarget target2; | |
370 GetController()->Register({accelerator_a}, &target2); | |
371 | |
372 // If multiple targets are registered with the same accelerator, the target | |
373 // registered later processes the accelerator. | |
374 EXPECT_TRUE(ProcessInController(accelerator_a)); | |
375 EXPECT_EQ(0, target1.accelerator_pressed_count()); | |
376 EXPECT_EQ(1, target2.accelerator_pressed_count()); | |
377 } | |
378 | |
379 TEST_F(AcceleratorControllerTest, Unregister) { | |
380 TestTarget target; | |
381 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
382 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE); | |
383 GetController()->Register({accelerator_a, accelerator_b}, &target); | |
384 | |
385 // Unregistering a different accelerator does not affect the other | |
386 // accelerator. | |
387 GetController()->Unregister(accelerator_b, &target); | |
388 EXPECT_TRUE(ProcessInController(accelerator_a)); | |
389 EXPECT_EQ(1, target.accelerator_pressed_count()); | |
390 | |
391 // The unregistered accelerator is no longer processed. | |
392 target.reset(); | |
393 GetController()->Unregister(accelerator_a, &target); | |
394 EXPECT_FALSE(ProcessInController(accelerator_a)); | |
395 EXPECT_EQ(0, target.accelerator_pressed_count()); | |
396 } | |
397 | |
398 TEST_F(AcceleratorControllerTest, UnregisterAll) { | |
399 TestTarget target1; | |
400 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
401 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE); | |
402 GetController()->Register({accelerator_a, accelerator_b}, &target1); | |
403 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE); | |
404 TestTarget target2; | |
405 GetController()->Register({accelerator_c}, &target2); | |
406 GetController()->UnregisterAll(&target1); | |
407 | |
408 // All the accelerators registered for |target1| are no longer processed. | |
409 EXPECT_FALSE(ProcessInController(accelerator_a)); | |
410 EXPECT_FALSE(ProcessInController(accelerator_b)); | |
411 EXPECT_EQ(0, target1.accelerator_pressed_count()); | |
412 | |
413 // UnregisterAll with a different target does not affect the other target. | |
414 EXPECT_TRUE(ProcessInController(accelerator_c)); | |
415 EXPECT_EQ(1, target2.accelerator_pressed_count()); | |
416 } | |
417 | |
418 TEST_F(AcceleratorControllerTest, Process) { | |
419 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
420 TestTarget target1; | |
421 GetController()->Register({accelerator_a}, &target1); | |
422 | |
423 // The registered accelerator is processed. | |
424 EXPECT_TRUE(ProcessInController(accelerator_a)); | |
425 EXPECT_EQ(1, target1.accelerator_pressed_count()); | |
426 | |
427 // The non-registered accelerator is not processed. | |
428 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE); | |
429 EXPECT_FALSE(ProcessInController(accelerator_b)); | |
430 } | |
431 | |
432 TEST_F(AcceleratorControllerTest, IsRegistered) { | |
433 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE); | |
434 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN); | |
435 TestTarget target; | |
436 GetController()->Register({accelerator_a}, &target); | |
437 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a)); | |
438 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a)); | |
439 GetController()->UnregisterAll(&target); | |
440 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a)); | |
441 } | |
442 | |
443 TEST_F(AcceleratorControllerTest, WindowSnap) { | |
444 aura::Window* aura_window = CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
445 WmWindow* window = WmWindow::Get(aura_window); | |
446 wm::WindowState* window_state = window->GetWindowState(); | |
447 | |
448 window_state->Activate(); | |
449 | |
450 { | |
451 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
452 gfx::Rect expected_bounds = | |
453 wm::GetDefaultLeftSnappedWindowBoundsInParent(window); | |
454 EXPECT_EQ(expected_bounds.ToString(), window->GetBounds().ToString()); | |
455 } | |
456 { | |
457 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
458 gfx::Rect expected_bounds = | |
459 wm::GetDefaultRightSnappedWindowBoundsInParent(window); | |
460 EXPECT_EQ(expected_bounds.ToString(), window->GetBounds().ToString()); | |
461 } | |
462 { | |
463 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent(); | |
464 | |
465 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED); | |
466 EXPECT_TRUE(window_state->IsMaximized()); | |
467 EXPECT_NE(normal_bounds.ToString(), window->GetBounds().ToString()); | |
468 | |
469 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED); | |
470 EXPECT_FALSE(window_state->IsMaximized()); | |
471 // Window gets restored to its restore bounds since side-maximized state | |
472 // is treated as a "maximized" state. | |
473 EXPECT_EQ(normal_bounds.ToString(), window->GetBounds().ToString()); | |
474 | |
475 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED); | |
476 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
477 EXPECT_FALSE(window_state->IsMaximized()); | |
478 | |
479 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED); | |
480 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
481 EXPECT_FALSE(window_state->IsMaximized()); | |
482 | |
483 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED); | |
484 EXPECT_TRUE(window_state->IsMaximized()); | |
485 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE); | |
486 EXPECT_FALSE(window_state->IsMaximized()); | |
487 EXPECT_TRUE(window_state->IsMinimized()); | |
488 window_state->Restore(); | |
489 window_state->Activate(); | |
490 } | |
491 { | |
492 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE); | |
493 EXPECT_TRUE(window_state->IsMinimized()); | |
494 } | |
495 } | |
496 | |
497 // Tests that when window docking is disabled, only snapping windows works. | |
498 TEST_F(AcceleratorControllerTest, WindowSnapWithoutDocking) { | |
499 ASSERT_FALSE(ash::switches::DockedWindowsEnabled()); | |
500 WmWindow* window = WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
501 wm::WindowState* window_state = window->GetWindowState(); | |
502 window_state->Activate(); | |
503 | |
504 // Snap right. | |
505 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
506 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent(); | |
507 gfx::Rect expected_bounds = | |
508 wm::GetDefaultRightSnappedWindowBoundsInParent(window); | |
509 EXPECT_EQ(expected_bounds.ToString(), window->GetBounds().ToString()); | |
510 EXPECT_TRUE(window_state->IsSnapped()); | |
511 // Snap right again ->> becomes normal. | |
512 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
513 EXPECT_TRUE(window_state->IsNormalStateType()); | |
514 EXPECT_FALSE(window_state->IsDocked()); | |
515 EXPECT_EQ(normal_bounds.ToString(), window->GetBounds().ToString()); | |
516 // Snap right. | |
517 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
518 EXPECT_TRUE(window_state->IsSnapped()); | |
519 EXPECT_FALSE(window_state->IsDocked()); | |
520 // Snap left. | |
521 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
522 EXPECT_TRUE(window_state->IsSnapped()); | |
523 EXPECT_FALSE(window_state->IsDocked()); | |
524 expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(window); | |
525 EXPECT_EQ(expected_bounds.ToString(), window->GetBounds().ToString()); | |
526 // Snap left again ->> becomes normal. | |
527 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
528 EXPECT_TRUE(window_state->IsNormalStateType()); | |
529 EXPECT_FALSE(window_state->IsDocked()); | |
530 EXPECT_EQ(normal_bounds.ToString(), window->GetBounds().ToString()); | |
531 } | |
532 | |
533 // Test class used for testing docked windows. | |
534 class EnabledDockedWindowsAcceleratorControllerTest | |
535 : public AcceleratorControllerTest { | |
536 public: | |
537 EnabledDockedWindowsAcceleratorControllerTest() = default; | |
538 ~EnabledDockedWindowsAcceleratorControllerTest() override = default; | |
539 | |
540 void SetUp() override { | |
541 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
542 ash::switches::kAshEnableDockedWindows); | |
543 AcceleratorControllerTest::SetUp(); | |
544 } | |
545 | |
546 private: | |
547 DISALLOW_COPY_AND_ASSIGN(EnabledDockedWindowsAcceleratorControllerTest); | |
548 }; | |
549 | |
550 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, | |
551 WindowSnapLeftDockLeftRestore) { | |
552 CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
553 WmWindow* window1 = WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
554 wm::WindowState* window1_state = window1->GetWindowState(); | |
555 window1_state->Activate(); | |
556 | |
557 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
558 gfx::Rect normal_bounds = window1_state->GetRestoreBoundsInParent(); | |
559 gfx::Rect expected_bounds = | |
560 wm::GetDefaultLeftSnappedWindowBoundsInParent(window1); | |
561 EXPECT_EQ(expected_bounds.ToString(), window1->GetBounds().ToString()); | |
562 EXPECT_TRUE(window1_state->IsSnapped()); | |
563 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
564 EXPECT_FALSE(window1_state->IsNormalOrSnapped()); | |
565 EXPECT_TRUE(window1_state->IsDocked()); | |
566 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
567 EXPECT_FALSE(window1_state->IsDocked()); | |
568 EXPECT_EQ(normal_bounds.ToString(), window1->GetBounds().ToString()); | |
569 } | |
570 | |
571 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, | |
572 WindowSnapRightDockRightRestore) { | |
573 CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
574 WmWindow* window1 = WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
575 | |
576 wm::WindowState* window1_state = window1->GetWindowState(); | |
577 window1_state->Activate(); | |
578 | |
579 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
580 gfx::Rect normal_bounds = window1_state->GetRestoreBoundsInParent(); | |
581 gfx::Rect expected_bounds = | |
582 wm::GetDefaultRightSnappedWindowBoundsInParent(window1); | |
583 EXPECT_EQ(expected_bounds.ToString(), window1->GetBounds().ToString()); | |
584 EXPECT_TRUE(window1_state->IsSnapped()); | |
585 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
586 EXPECT_FALSE(window1_state->IsNormalOrSnapped()); | |
587 EXPECT_TRUE(window1_state->IsDocked()); | |
588 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
589 EXPECT_FALSE(window1_state->IsDocked()); | |
590 EXPECT_EQ(normal_bounds.ToString(), window1->GetBounds().ToString()); | |
591 } | |
592 | |
593 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, | |
594 WindowSnapLeftDockLeftSnapRight) { | |
595 CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
596 WmWindow* window1 = WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
597 | |
598 wm::WindowState* window1_state = window1->GetWindowState(); | |
599 window1_state->Activate(); | |
600 | |
601 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
602 gfx::Rect expected_bounds = | |
603 wm::GetDefaultLeftSnappedWindowBoundsInParent(window1); | |
604 gfx::Rect expected_bounds2 = | |
605 wm::GetDefaultRightSnappedWindowBoundsInParent(window1); | |
606 EXPECT_EQ(expected_bounds.ToString(), window1->GetBounds().ToString()); | |
607 EXPECT_TRUE(window1_state->IsSnapped()); | |
608 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
609 EXPECT_FALSE(window1_state->IsNormalOrSnapped()); | |
610 EXPECT_TRUE(window1_state->IsDocked()); | |
611 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
612 EXPECT_FALSE(window1_state->IsDocked()); | |
613 EXPECT_TRUE(window1_state->IsSnapped()); | |
614 EXPECT_EQ(expected_bounds2.ToString(), window1->GetBounds().ToString()); | |
615 } | |
616 | |
617 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, | |
618 WindowDockLeftMinimizeWindowWithRestore) { | |
619 WindowOwner window_owner( | |
620 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20)))); | |
621 WindowOwner window1_owner( | |
622 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20)))); | |
623 WmWindow* window1 = window1_owner.window(); | |
624 | |
625 wm::WindowState* window1_state = window1->GetWindowState(); | |
626 window1_state->Activate(); | |
627 | |
628 WindowOwner window2_owner( | |
629 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20)))); | |
630 WmWindow* window2 = window2_owner.window(); | |
631 | |
632 wm::WindowState* window2_state = window2->GetWindowState(); | |
633 | |
634 WindowOwner window3_owner( | |
635 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20)))); | |
636 WmWindow* window3 = window3_owner.window(); | |
637 | |
638 wm::WindowState* window3_state = window3->GetWindowState(); | |
639 window3_state->Activate(); | |
640 | |
641 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
642 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
643 gfx::Rect window3_docked_bounds = window3->GetBounds(); | |
644 | |
645 window2_state->Activate(); | |
646 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
647 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
648 window1_state->Activate(); | |
649 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
650 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
651 | |
652 EXPECT_TRUE(window3_state->IsDocked()); | |
653 EXPECT_TRUE(window2_state->IsDocked()); | |
654 EXPECT_TRUE(window1_state->IsDocked()); | |
655 EXPECT_TRUE(window3_state->IsMinimized()); | |
656 | |
657 window1_state->Activate(); | |
658 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
659 window2_state->Activate(); | |
660 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
661 window3_state->Unminimize(); | |
662 EXPECT_FALSE(window1_state->IsDocked()); | |
663 EXPECT_FALSE(window2_state->IsDocked()); | |
664 EXPECT_TRUE(window3_state->IsDocked()); | |
665 EXPECT_EQ(window3_docked_bounds.ToString(), window3->GetBounds().ToString()); | |
666 } | |
667 | |
668 // TODO: Needs CreatePanel(): http://crbug.com/632209. | |
669 /* | |
670 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, | |
671 WindowPanelDockLeftDockRightRestore) { | |
672 WmWndow* window0 = | |
673 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
674 | |
675 std::unique_ptr<aura::Window> window(CreatePanel()); | |
676 wm::WindowState* window_state = wm::GetWindowState(window.get()); | |
677 window_state->Activate(); | |
678 | |
679 gfx::Rect window_restore_bounds2 = window->bounds(); | |
680 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT); | |
681 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent( | |
682 WmWindow::Get(window.get())); | |
683 gfx::Rect window_restore_bounds = window_state->GetRestoreBoundsInScreen(); | |
684 EXPECT_NE(expected_bounds.ToString(), window->bounds().ToString()); | |
685 EXPECT_FALSE(window_state->IsSnapped()); | |
686 EXPECT_FALSE(window_state->IsNormalOrSnapped()); | |
687 EXPECT_TRUE(window_state->IsDocked()); | |
688 window_state->Restore(); | |
689 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
690 EXPECT_TRUE(window_state->IsDocked()); | |
691 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT); | |
692 EXPECT_FALSE(window_state->IsDocked()); | |
693 EXPECT_EQ(window_restore_bounds.ToString(), | |
694 window_restore_bounds2.ToString()); | |
695 EXPECT_EQ(window_restore_bounds.ToString(), window->bounds().ToString()); | |
696 } | |
697 */ | |
698 | |
699 TEST_F(EnabledDockedWindowsAcceleratorControllerTest, CenterWindowAccelerator) { | |
700 WindowOwner window_owner( | |
701 WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20)))); | |
702 WmWindow* window = window_owner.window(); | |
703 wm::WindowState* window_state = window->GetWindowState(); | |
704 window_state->Activate(); | |
705 | |
706 // Center the window using accelerator. | |
707 GetController()->PerformActionIfEnabled(WINDOW_POSITION_CENTER); | |
708 gfx::Rect work_area = window->GetDisplayNearestWindow().work_area(); | |
709 gfx::Rect bounds = window->GetBoundsInScreen(); | |
710 EXPECT_NEAR(bounds.x() - work_area.x(), work_area.right() - bounds.right(), | |
711 1); | |
712 EXPECT_NEAR(bounds.y() - work_area.y(), work_area.bottom() - bounds.bottom(), | |
713 1); | |
714 | |
715 // Add the window to docked container and try to center it. | |
716 window->SetBounds(gfx::Rect(0, 0, 20, 20)); | |
717 const wm::WMEvent event(wm::WM_EVENT_DOCK); | |
718 window->GetWindowState()->OnWMEvent(&event); | |
719 EXPECT_EQ(kShellWindowId_DockedContainer, | |
720 window->GetParent()->GetShellWindowId()); | |
721 | |
722 gfx::Rect docked_bounds = window->GetBoundsInScreen(); | |
723 GetController()->PerformActionIfEnabled(WINDOW_POSITION_CENTER); | |
724 // It should not get centered and should remain docked. | |
725 EXPECT_EQ(kShellWindowId_DockedContainer, | |
726 window->GetParent()->GetShellWindowId()); | |
727 EXPECT_EQ(docked_bounds.ToString(), window->GetBoundsInScreen().ToString()); | |
728 } | |
729 | |
730 // This is commented out for two reasons: | |
731 // . http://crbug.com/630683: ash doesn't see all key events. | |
732 // . http://crbug.com/615033: EventGenerator doesn't work with ash. That can be | |
733 // worked around for the test, but no point until we decide on the first one. | |
734 /* | |
735 TEST_F(AcceleratorControllerTest, AutoRepeat) { | |
736 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
737 accelerator_a.set_type(ui::ET_KEY_PRESSED); | |
738 TestTarget target_a; | |
739 GetController()->Register(accelerator_a, &target_a); | |
740 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_CONTROL_DOWN); | |
741 accelerator_b.set_type(ui::ET_KEY_PRESSED); | |
742 TestTarget target_b; | |
743 GetController()->Register(accelerator_b, &target_b); | |
744 | |
745 ui::test::EventGenerator& generator = GetEventGenerator(); | |
746 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
747 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
748 | |
749 EXPECT_EQ(1, target_a.accelerator_pressed_count()); | |
750 EXPECT_EQ(0, target_a.accelerator_repeat_count()); | |
751 | |
752 // Long press should generate one | |
753 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
754 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT); | |
755 EXPECT_EQ(2, target_a.accelerator_pressed_count()); | |
756 EXPECT_EQ(1, target_a.accelerator_repeat_count()); | |
757 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT); | |
758 EXPECT_EQ(2, target_a.accelerator_pressed_count()); | |
759 EXPECT_EQ(2, target_a.accelerator_repeat_count()); | |
760 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
761 EXPECT_EQ(2, target_a.accelerator_pressed_count()); | |
762 EXPECT_EQ(2, target_a.accelerator_repeat_count()); | |
763 | |
764 // Long press was intercepted by another key press. | |
765 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
766 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT); | |
767 generator.PressKey(ui::VKEY_B, ui::EF_CONTROL_DOWN); | |
768 generator.ReleaseKey(ui::VKEY_B, ui::EF_CONTROL_DOWN); | |
769 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
770 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT); | |
771 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN); | |
772 | |
773 EXPECT_EQ(1, target_b.accelerator_pressed_count()); | |
774 EXPECT_EQ(0, target_b.accelerator_repeat_count()); | |
775 EXPECT_EQ(4, target_a.accelerator_pressed_count()); | |
776 EXPECT_EQ(4, target_a.accelerator_repeat_count()); | |
777 } | |
778 */ | |
779 | |
780 // TODO: update once http://crbug.com/630683 is resolved. | |
781 /* | |
782 TEST_F(AcceleratorControllerTest, Previous) { | |
783 ui::test::EventGenerator& generator = GetEventGenerator(); | |
784 generator.PressKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE); | |
785 generator.ReleaseKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE); | |
786 | |
787 EXPECT_EQ(ui::VKEY_VOLUME_MUTE, GetPreviousAccelerator().key_code()); | |
788 EXPECT_EQ(ui::EF_NONE, GetPreviousAccelerator().modifiers()); | |
789 | |
790 generator.PressKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN); | |
791 generator.ReleaseKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN); | |
792 | |
793 EXPECT_EQ(ui::VKEY_TAB, GetPreviousAccelerator().key_code()); | |
794 EXPECT_EQ(ui::EF_CONTROL_DOWN, GetPreviousAccelerator().modifiers()); | |
795 } | |
796 */ | |
797 | |
798 TEST_F(AcceleratorControllerTest, DontRepeatToggleFullscreen) { | |
799 const AcceleratorData accelerators[] = { | |
800 {true, ui::VKEY_J, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN}, | |
801 {true, ui::VKEY_K, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN}, | |
802 }; | |
803 GetController()->RegisterAccelerators(accelerators, arraysize(accelerators)); | |
804 | |
805 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
806 params.bounds = gfx::Rect(5, 5, 20, 20); | |
807 views::Widget* widget = new views::Widget; | |
808 WmWindow::Get(GetPrimaryRootWindow()) | |
809 ->GetRootWindowController() | |
810 ->ConfigureWidgetInitParamsForContainer( | |
811 widget, kShellWindowId_DefaultContainer, ¶ms); | |
812 widget->Init(params); | |
813 widget->GetNativeView()->SetProperty(aura::client::kResizeBehaviorKey, | |
814 ui::mojom::kResizeBehaviorCanMaximize); | |
815 widget->Show(); | |
816 widget->Activate(); | |
817 | |
818 wm::WindowState* window_state = | |
819 WmLookup::Get()->GetWindowForWidget(widget)->GetWindowState(); | |
820 | |
821 // Toggling not suppressed. | |
822 ProcessAccelerator(ui::VKEY_J, ui::EF_ALT_DOWN); | |
823 EXPECT_TRUE(window_state->IsFullscreen()); | |
824 | |
825 // The same accelerator - toggling suppressed. | |
826 ProcessAccelerator(ui::VKEY_J, ui::EF_ALT_DOWN | ui::EF_IS_REPEAT); | |
827 EXPECT_TRUE(window_state->IsFullscreen()); | |
828 | |
829 // Different accelerator. | |
830 ProcessAccelerator(ui::VKEY_K, ui::EF_ALT_DOWN); | |
831 EXPECT_FALSE(window_state->IsFullscreen()); | |
832 } | |
833 | |
834 TEST_F(AcceleratorControllerTest, GlobalAccelerators) { | |
835 // CycleBackward | |
836 EXPECT_TRUE(ProcessInController( | |
837 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN))); | |
838 // CycleForward | |
839 EXPECT_TRUE( | |
840 ProcessInController(ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN))); | |
841 // CycleLinear | |
842 EXPECT_TRUE(ProcessInController( | |
843 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE))); | |
844 | |
845 // The "Take Screenshot", "Take Partial Screenshot", volume, brightness, and | |
846 // keyboard brightness accelerators are only defined on ChromeOS. | |
847 // TODO: needs ScreenShotDelegate converted: http://crbug.com/612331. | |
848 /* | |
849 { | |
850 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate(); | |
851 delegate->set_can_take_screenshot(false); | |
852 EXPECT_TRUE(ProcessInController( | |
853 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN))); | |
854 EXPECT_TRUE( | |
855 ProcessInController(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
856 EXPECT_TRUE(ProcessInController(ui::Accelerator( | |
857 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); | |
858 | |
859 delegate->set_can_take_screenshot(true); | |
860 EXPECT_EQ(0, delegate->handle_take_screenshot_count()); | |
861 EXPECT_TRUE(ProcessInController( | |
862 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN))); | |
863 EXPECT_EQ(1, delegate->handle_take_screenshot_count()); | |
864 EXPECT_TRUE( | |
865 ProcessInController(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
866 EXPECT_EQ(2, delegate->handle_take_screenshot_count()); | |
867 EXPECT_TRUE(ProcessInController(ui::Accelerator( | |
868 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); | |
869 EXPECT_EQ(2, delegate->handle_take_screenshot_count()); | |
870 } | |
871 */ | |
872 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE); | |
873 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE); | |
874 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE); | |
875 { | |
876 base::UserActionTester user_action_tester; | |
877 ui::AcceleratorHistory* history = GetController()->accelerator_history(); | |
878 | |
879 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeMute_F8")); | |
880 EXPECT_TRUE(ProcessInController(volume_mute)); | |
881 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeMute_F8")); | |
882 EXPECT_EQ(volume_mute, history->current_accelerator()); | |
883 | |
884 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeDown_F9")); | |
885 EXPECT_TRUE(ProcessInController(volume_down)); | |
886 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeDown_F9")); | |
887 EXPECT_EQ(volume_down, history->current_accelerator()); | |
888 | |
889 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeUp_F10")); | |
890 EXPECT_TRUE(ProcessInController(volume_up)); | |
891 EXPECT_EQ(volume_up, history->current_accelerator()); | |
892 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeUp_F10")); | |
893 } | |
894 // Brightness | |
895 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows. | |
896 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); | |
897 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE); | |
898 { | |
899 DummyBrightnessControlDelegate* delegate = | |
900 new DummyBrightnessControlDelegate; | |
901 SetBrightnessControlDelegate( | |
902 std::unique_ptr<BrightnessControlDelegate>(delegate)); | |
903 EXPECT_EQ(0, delegate->handle_brightness_down_count()); | |
904 EXPECT_TRUE(ProcessInController(brightness_down)); | |
905 EXPECT_EQ(1, delegate->handle_brightness_down_count()); | |
906 EXPECT_EQ(brightness_down, delegate->last_accelerator()); | |
907 EXPECT_EQ(0, delegate->handle_brightness_up_count()); | |
908 EXPECT_TRUE(ProcessInController(brightness_up)); | |
909 EXPECT_EQ(1, delegate->handle_brightness_up_count()); | |
910 EXPECT_EQ(brightness_up, delegate->last_accelerator()); | |
911 } | |
912 | |
913 // Keyboard brightness | |
914 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN, | |
915 ui::EF_ALT_DOWN); | |
916 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP, | |
917 ui::EF_ALT_DOWN); | |
918 { | |
919 EXPECT_TRUE(ProcessInController(alt_brightness_down)); | |
920 EXPECT_TRUE(ProcessInController(alt_brightness_up)); | |
921 DummyKeyboardBrightnessControlDelegate* delegate = | |
922 new DummyKeyboardBrightnessControlDelegate; | |
923 SetKeyboardBrightnessControlDelegate( | |
924 std::unique_ptr<KeyboardBrightnessControlDelegate>(delegate)); | |
925 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count()); | |
926 EXPECT_TRUE(ProcessInController(alt_brightness_down)); | |
927 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count()); | |
928 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator()); | |
929 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count()); | |
930 EXPECT_TRUE(ProcessInController(alt_brightness_up)); | |
931 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count()); | |
932 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator()); | |
933 } | |
934 | |
935 // Exit | |
936 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); | |
937 ASSERT_TRUE(ewh); | |
938 StubForTest(ewh); | |
939 EXPECT_TRUE(is_idle(ewh)); | |
940 EXPECT_FALSE(is_ui_shown(ewh)); | |
941 EXPECT_TRUE(ProcessInController( | |
942 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); | |
943 EXPECT_FALSE(is_idle(ewh)); | |
944 EXPECT_TRUE(is_ui_shown(ewh)); | |
945 SimulateTimerExpired(ewh); | |
946 EXPECT_TRUE(is_idle(ewh)); | |
947 EXPECT_FALSE(is_ui_shown(ewh)); | |
948 Reset(ewh); | |
949 | |
950 // New tab | |
951 EXPECT_TRUE( | |
952 ProcessInController(ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN))); | |
953 | |
954 // New incognito window | |
955 EXPECT_TRUE(ProcessInController( | |
956 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); | |
957 | |
958 // New window | |
959 EXPECT_TRUE( | |
960 ProcessInController(ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN))); | |
961 | |
962 // Restore tab | |
963 EXPECT_TRUE(ProcessInController( | |
964 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); | |
965 | |
966 // Show task manager | |
967 EXPECT_TRUE( | |
968 ProcessInController(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN))); | |
969 | |
970 // Open file manager | |
971 EXPECT_TRUE(ProcessInController( | |
972 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN))); | |
973 | |
974 // Lock screen | |
975 // TODO(derat): Reenable this once user sessions work in mash. | |
976 EXPECT_FALSE( | |
977 ProcessInController(ui::Accelerator(ui::VKEY_L, ui::EF_COMMAND_DOWN))); | |
978 } | |
979 | |
980 // TODO: fails in mash, http://crbug.com/632180. | |
981 TEST_F(AcceleratorControllerTest, DISABLED_GlobalAcceleratorsToggleAppList) { | |
982 AccessibilityDelegate* delegate = WmShell::Get()->accessibility_delegate(); | |
983 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); | |
984 | |
985 // The press event should not open the AppList, the release should instead. | |
986 EXPECT_FALSE( | |
987 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
988 EXPECT_EQ(ui::VKEY_LWIN, GetCurrentAccelerator().key_code()); | |
989 | |
990 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); | |
991 | |
992 EXPECT_TRUE( | |
993 ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
994 EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); | |
995 | |
996 EXPECT_EQ(ui::VKEY_LWIN, GetPreviousAccelerator().key_code()); | |
997 | |
998 // When spoken feedback is on, the AppList should not toggle. | |
999 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); | |
1000 EXPECT_FALSE( | |
1001 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1002 EXPECT_FALSE( | |
1003 ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1004 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); | |
1005 EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); | |
1006 | |
1007 EXPECT_FALSE( | |
1008 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1009 EXPECT_TRUE( | |
1010 ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1011 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); | |
1012 | |
1013 // When spoken feedback is on, the AppList should not toggle. | |
1014 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); | |
1015 EXPECT_FALSE( | |
1016 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1017 EXPECT_FALSE( | |
1018 ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); | |
1019 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); | |
1020 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); | |
1021 | |
1022 // The press of VKEY_BROWSER_SEARCH should toggle the AppList | |
1023 EXPECT_TRUE(ProcessInController( | |
1024 ui::Accelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); | |
1025 EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); | |
1026 EXPECT_FALSE(ProcessInController( | |
1027 ReleaseAccelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); | |
1028 EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); | |
1029 } | |
1030 | |
1031 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) { | |
1032 // Test IME shortcuts. | |
1033 ui::Accelerator control_space_down(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); | |
1034 control_space_down.set_type(ui::ET_KEY_PRESSED); | |
1035 ui::Accelerator control_space_up(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); | |
1036 control_space_up.set_type(ui::ET_KEY_RELEASED); | |
1037 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE); | |
1038 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE); | |
1039 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE); | |
1040 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE); | |
1041 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE); | |
1042 EXPECT_FALSE(ProcessInController(control_space_down)); | |
1043 EXPECT_FALSE(ProcessInController(control_space_up)); | |
1044 EXPECT_FALSE(ProcessInController(convert)); | |
1045 EXPECT_FALSE(ProcessInController(non_convert)); | |
1046 EXPECT_FALSE(ProcessInController(wide_half_1)); | |
1047 EXPECT_FALSE(ProcessInController(wide_half_2)); | |
1048 EXPECT_FALSE(ProcessInController(hangul)); | |
1049 DummyImeControlDelegate* delegate = new DummyImeControlDelegate; | |
1050 GetController()->SetImeControlDelegate( | |
1051 std::unique_ptr<ImeControlDelegate>(delegate)); | |
1052 EXPECT_EQ(0, delegate->handle_previous_ime_count()); | |
1053 EXPECT_TRUE(ProcessInController(control_space_down)); | |
1054 EXPECT_EQ(1, delegate->handle_previous_ime_count()); | |
1055 EXPECT_TRUE(ProcessInController(control_space_up)); | |
1056 EXPECT_EQ(1, delegate->handle_previous_ime_count()); | |
1057 EXPECT_EQ(0, delegate->handle_switch_ime_count()); | |
1058 EXPECT_TRUE(ProcessInController(convert)); | |
1059 EXPECT_EQ(1, delegate->handle_switch_ime_count()); | |
1060 EXPECT_TRUE(ProcessInController(non_convert)); | |
1061 EXPECT_EQ(2, delegate->handle_switch_ime_count()); | |
1062 EXPECT_TRUE(ProcessInController(wide_half_1)); | |
1063 EXPECT_EQ(3, delegate->handle_switch_ime_count()); | |
1064 EXPECT_TRUE(ProcessInController(wide_half_2)); | |
1065 EXPECT_EQ(4, delegate->handle_switch_ime_count()); | |
1066 EXPECT_TRUE(ProcessInController(hangul)); | |
1067 EXPECT_EQ(5, delegate->handle_switch_ime_count()); | |
1068 } | |
1069 | |
1070 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way. | |
1071 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) { | |
1072 // The workaround for crbug.com/139556 depends on the fact that we don't | |
1073 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it. | |
1074 const ui::Accelerator shift_alt_return_press( | |
1075 ui::VKEY_RETURN, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN); | |
1076 EXPECT_FALSE(ProcessInController(shift_alt_return_press)); | |
1077 const ui::Accelerator shift_alt_space_press( | |
1078 ui::VKEY_SPACE, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN); | |
1079 EXPECT_FALSE(ProcessInController(shift_alt_space_press)); | |
1080 } | |
1081 | |
1082 TEST_F(AcceleratorControllerTest, PreferredReservedAccelerators) { | |
1083 // Power key is reserved on chromeos. | |
1084 EXPECT_TRUE(GetController()->IsReserved( | |
1085 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE))); | |
1086 EXPECT_FALSE(GetController()->IsPreferred( | |
1087 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE))); | |
1088 // ALT+Tab are not reserved but preferred. | |
1089 EXPECT_FALSE(GetController()->IsReserved( | |
1090 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN))); | |
1091 EXPECT_FALSE(GetController()->IsReserved( | |
1092 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN))); | |
1093 EXPECT_TRUE(GetController()->IsPreferred( | |
1094 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN))); | |
1095 EXPECT_TRUE(GetController()->IsPreferred( | |
1096 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN))); | |
1097 | |
1098 // Others are not reserved nor preferred | |
1099 EXPECT_FALSE(GetController()->IsReserved( | |
1100 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
1101 EXPECT_FALSE(GetController()->IsPreferred( | |
1102 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
1103 EXPECT_FALSE( | |
1104 GetController()->IsReserved(ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE))); | |
1105 EXPECT_FALSE( | |
1106 GetController()->IsPreferred(ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE))); | |
1107 EXPECT_FALSE( | |
1108 GetController()->IsReserved(ui::Accelerator(ui::VKEY_A, ui::EF_NONE))); | |
1109 EXPECT_FALSE( | |
1110 GetController()->IsPreferred(ui::Accelerator(ui::VKEY_A, ui::EF_NONE))); | |
1111 } | |
1112 | |
1113 /* | |
1114 namespace { | |
1115 | |
1116 class PreferredReservedAcceleratorsTest : public test::AshTestBase { | |
1117 public: | |
1118 PreferredReservedAcceleratorsTest() {} | |
1119 ~PreferredReservedAcceleratorsTest() override {} | |
1120 | |
1121 // test::AshTestBase: | |
1122 void SetUp() override { | |
1123 AshTestBase::SetUp(); | |
1124 Shell::GetInstance()->lock_state_controller()->set_animator_for_test( | |
1125 new test::TestSessionStateAnimator); | |
1126 } | |
1127 | |
1128 private: | |
1129 DISALLOW_COPY_AND_ASSIGN(PreferredReservedAcceleratorsTest); | |
1130 }; | |
1131 | |
1132 } // namespace | |
1133 | |
1134 // TODO: needs LockStateController ported: http://crbug.com/632189. | |
1135 TEST_F(PreferredReservedAcceleratorsTest, AcceleratorsWithFullscreen) { | |
1136 WmWindow* w1 = WmWindow::Get(CreateTestWindow(gfx::Rect())); | |
1137 WmWindow* w2 = WmWindow::Get(CreateTestWindow(gfx::Rect())); | |
1138 wm::ActivateWindow(w1); | |
1139 | |
1140 wm::WMEvent fullscreen(wm::WM_EVENT_FULLSCREEN); | |
1141 wm::WindowState* w1_state = w1->GetWindowState(); | |
1142 w1_state->OnWMEvent(&fullscreen); | |
1143 ASSERT_TRUE(w1_state->IsFullscreen()); | |
1144 | |
1145 ui::test::EventGenerator& generator = GetEventGenerator(); | |
1146 // Power key (reserved) should always be handled. | |
1147 LockStateController::TestApi test_api( | |
1148 Shell::GetInstance()->lock_state_controller()); | |
1149 EXPECT_FALSE(test_api.is_animating_lock()); | |
1150 generator.PressKey(ui::VKEY_POWER, ui::EF_NONE); | |
1151 EXPECT_TRUE(test_api.is_animating_lock()); | |
1152 | |
1153 // A fullscreen window can consume ALT-TAB (preferred). | |
1154 ASSERT_EQ(w1, wm::GetActiveWindow()); | |
1155 generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); | |
1156 ASSERT_EQ(w1, wm::GetActiveWindow()); | |
1157 ASSERT_NE(w2, wm::GetActiveWindow()); | |
1158 | |
1159 // ALT-TAB is non repeatable. Press A to cancel the | |
1160 // repeat record. | |
1161 generator.PressKey(ui::VKEY_A, ui::EF_NONE); | |
1162 generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE); | |
1163 | |
1164 // A normal window shouldn't consume preferred accelerator. | |
1165 wm::WMEvent normal(wm::WM_EVENT_NORMAL); | |
1166 w1_state->OnWMEvent(&normal); | |
1167 ASSERT_FALSE(w1_state->IsFullscreen()); | |
1168 | |
1169 EXPECT_EQ(w1, wm::GetActiveWindow()); | |
1170 generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); | |
1171 ASSERT_NE(w1, wm::GetActiveWindow()); | |
1172 ASSERT_EQ(w2, wm::GetActiveWindow()); | |
1173 } | |
1174 | |
1175 // TODO: needs LockStateController ported: http://crbug.com/632189. | |
1176 TEST_F(PreferredReservedAcceleratorsTest, AcceleratorsWithPinned) { | |
1177 aura::Window* w1 = CreateTestWindowInShellWithId(0); | |
1178 aura::Window* w2 = CreateTestWindowInShellWithId(1); | |
1179 wm::ActivateWindow(w1); | |
1180 | |
1181 { | |
1182 wm::WMEvent pin_event(wm::WM_EVENT_PIN); | |
1183 wm::WindowState* w1_state = wm::GetWindowState(w1); | |
1184 w1_state->OnWMEvent(&pin_event); | |
1185 ASSERT_TRUE(w1_state->IsPinned()); | |
1186 } | |
1187 | |
1188 ui::test::EventGenerator& generator = GetEventGenerator(); | |
1189 // Power key (reserved) should always be handled. | |
1190 LockStateController::TestApi test_api( | |
1191 Shell::GetInstance()->lock_state_controller()); | |
1192 EXPECT_FALSE(test_api.is_animating_lock()); | |
1193 generator.PressKey(ui::VKEY_POWER, ui::EF_NONE); | |
1194 EXPECT_TRUE(test_api.is_animating_lock()); | |
1195 | |
1196 // A pinned window can consume ALT-TAB (preferred), but no side effect. | |
1197 ASSERT_EQ(w1, wm::GetActiveWindow()); | |
1198 generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); | |
1199 generator.ReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); | |
1200 ASSERT_EQ(w1, wm::GetActiveWindow()); | |
1201 ASSERT_NE(w2, wm::GetActiveWindow()); | |
1202 } | |
1203 */ | |
1204 | |
1205 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) { | |
1206 std::set<AcceleratorAction> all_actions; | |
1207 for (size_t i = 0; i < kAcceleratorDataLength; ++i) | |
1208 all_actions.insert(kAcceleratorData[i].action); | |
1209 std::set<AcceleratorAction> all_debug_actions; | |
1210 for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i) | |
1211 all_debug_actions.insert(kDebugAcceleratorData[i].action); | |
1212 std::set<AcceleratorAction> all_dev_actions; | |
1213 for (size_t i = 0; i < kDeveloperAcceleratorDataLength; ++i) | |
1214 all_dev_actions.insert(kDeveloperAcceleratorData[i].action); | |
1215 | |
1216 std::set<AcceleratorAction> actionsAllowedAtModalWindow; | |
1217 for (size_t k = 0; k < kActionsAllowedAtModalWindowLength; ++k) | |
1218 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]); | |
1219 for (const auto& action : actionsAllowedAtModalWindow) { | |
1220 EXPECT_TRUE(all_actions.find(action) != all_actions.end() || | |
1221 all_debug_actions.find(action) != all_debug_actions.end() || | |
1222 all_dev_actions.find(action) != all_dev_actions.end()) | |
1223 << " action from kActionsAllowedAtModalWindow" | |
1224 << " not found in kAcceleratorData, kDebugAcceleratorData or" | |
1225 << " kDeveloperAcceleratorData action: " << action; | |
1226 } | |
1227 WmWindow* window = WmWindow::Get(CreateTestWindow(gfx::Rect(5, 5, 20, 20))); | |
1228 window->Activate(); | |
1229 WmShell::Get()->SimulateModalWindowOpenForTesting(true); | |
1230 for (const auto& action : all_actions) { | |
1231 if (actionsAllowedAtModalWindow.find(action) == | |
1232 actionsAllowedAtModalWindow.end()) { | |
1233 EXPECT_TRUE(GetController()->PerformActionIfEnabled(action)) | |
1234 << " for action (disallowed at modal window): " << action; | |
1235 } | |
1236 } | |
1237 // Testing of top row (F5-F10) accelerators that should still work | |
1238 // when a modal window is open | |
1239 // | |
1240 // Screenshot | |
1241 // TODO: needs ScreenShotDelegate converted: http://crbug.com/612331. | |
1242 /* | |
1243 { | |
1244 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate(); | |
1245 delegate->set_can_take_screenshot(false); | |
1246 EXPECT_TRUE(ProcessInController( | |
1247 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN))); | |
1248 EXPECT_TRUE( | |
1249 ProcessInController(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
1250 EXPECT_TRUE(ProcessInController(ui::Accelerator( | |
1251 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | | |
1252 ui::EF_CONTROL_DOWN))); | |
1253 delegate->set_can_take_screenshot(true); | |
1254 EXPECT_EQ(0, delegate->handle_take_screenshot_count()); | |
1255 EXPECT_TRUE(ProcessInController( | |
1256 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN))); | |
1257 EXPECT_EQ(1, delegate->handle_take_screenshot_count()); | |
1258 EXPECT_TRUE( | |
1259 ProcessInController(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE))); | |
1260 EXPECT_EQ(2, delegate->handle_take_screenshot_count()); | |
1261 EXPECT_TRUE(ProcessInController(ui::Accelerator( | |
1262 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | | |
1263 ui::EF_CONTROL_DOWN))); | |
1264 EXPECT_EQ(2, delegate->handle_take_screenshot_count()); | |
1265 } | |
1266 */ | |
1267 // Brightness | |
1268 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); | |
1269 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE); | |
1270 { | |
1271 DummyBrightnessControlDelegate* delegate = | |
1272 new DummyBrightnessControlDelegate; | |
1273 SetBrightnessControlDelegate( | |
1274 std::unique_ptr<BrightnessControlDelegate>(delegate)); | |
1275 EXPECT_EQ(0, delegate->handle_brightness_down_count()); | |
1276 EXPECT_TRUE(ProcessInController(brightness_down)); | |
1277 EXPECT_EQ(1, delegate->handle_brightness_down_count()); | |
1278 EXPECT_EQ(brightness_down, delegate->last_accelerator()); | |
1279 EXPECT_EQ(0, delegate->handle_brightness_up_count()); | |
1280 EXPECT_TRUE(ProcessInController(brightness_up)); | |
1281 EXPECT_EQ(1, delegate->handle_brightness_up_count()); | |
1282 EXPECT_EQ(brightness_up, delegate->last_accelerator()); | |
1283 } | |
1284 // Volume | |
1285 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE); | |
1286 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE); | |
1287 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE); | |
1288 { | |
1289 base::UserActionTester user_action_tester; | |
1290 ui::AcceleratorHistory* history = GetController()->accelerator_history(); | |
1291 | |
1292 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeMute_F8")); | |
1293 EXPECT_TRUE(ProcessInController(volume_mute)); | |
1294 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeMute_F8")); | |
1295 EXPECT_EQ(volume_mute, history->current_accelerator()); | |
1296 | |
1297 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeDown_F9")); | |
1298 EXPECT_TRUE(ProcessInController(volume_down)); | |
1299 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeDown_F9")); | |
1300 EXPECT_EQ(volume_down, history->current_accelerator()); | |
1301 | |
1302 EXPECT_EQ(0, user_action_tester.GetActionCount("Accel_VolumeUp_F10")); | |
1303 EXPECT_TRUE(ProcessInController(volume_up)); | |
1304 EXPECT_EQ(volume_up, history->current_accelerator()); | |
1305 EXPECT_EQ(1, user_action_tester.GetActionCount("Accel_VolumeUp_F10")); | |
1306 } | |
1307 } | |
1308 | |
1309 // TODO: reenable. Disabled because shelf asynchronously created: | |
1310 // http://crbug.com/632192. | |
1311 TEST_F(AcceleratorControllerTest, DISABLED_DisallowedWithNoWindow) { | |
1312 AccessibilityDelegate* delegate = WmShell::Get()->accessibility_delegate(); | |
1313 | |
1314 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) { | |
1315 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE); | |
1316 EXPECT_TRUE( | |
1317 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i])); | |
1318 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED); | |
1319 } | |
1320 | |
1321 // Make sure we don't alert if we do have a window. | |
1322 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) { | |
1323 aura::Window* aura_window = CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
1324 WmWindow::Get(aura_window)->Activate(); | |
1325 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE); | |
1326 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i]); | |
1327 EXPECT_NE(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED); | |
1328 delete aura_window; | |
1329 } | |
1330 | |
1331 // Don't alert if we have a minimized window either. | |
1332 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) { | |
1333 aura::Window* aura_window = CreateTestWindow(gfx::Rect(5, 5, 20, 20)); | |
1334 WmWindow::Get(aura_window)->Activate(); | |
1335 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE); | |
1336 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE); | |
1337 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i]); | |
1338 EXPECT_NE(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED); | |
1339 delete aura_window; | |
1340 } | |
1341 } | |
1342 | |
1343 namespace { | |
1344 | |
1345 // defines a class to test the behavior of deprecated accelerators. | |
1346 class DeprecatedAcceleratorTester : public AcceleratorControllerTest { | |
1347 public: | |
1348 DeprecatedAcceleratorTester() {} | |
1349 ~DeprecatedAcceleratorTester() override {} | |
1350 | |
1351 // TODO: this override should be removed and put in WmTestBase. | |
1352 // http://crbug.com/632200. | |
1353 void UnblockUserSession() {} | |
1354 | |
1355 void SetUp() override { | |
1356 AcceleratorControllerTest::SetUp(); | |
1357 | |
1358 // For testing the deprecated and new IME shortcuts. | |
1359 DummyImeControlDelegate* delegate = new DummyImeControlDelegate; | |
1360 GetController()->SetImeControlDelegate( | |
1361 std::unique_ptr<ImeControlDelegate>(delegate)); | |
1362 } | |
1363 | |
1364 ui::Accelerator CreateAccelerator(const AcceleratorData& data) const { | |
1365 ui::Accelerator result(data.keycode, data.modifiers); | |
1366 result.set_type(data.trigger_on_press ? ui::ET_KEY_PRESSED | |
1367 : ui::ET_KEY_RELEASED); | |
1368 return result; | |
1369 } | |
1370 | |
1371 void ResetStateIfNeeded() { | |
1372 if (WmShell::Get()->GetSessionStateDelegate()->IsScreenLocked() || | |
1373 WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked()) { | |
1374 UnblockUserSession(); | |
1375 } | |
1376 } | |
1377 | |
1378 bool ContainsDeprecatedAcceleratorNotification(const char* const id) const { | |
1379 return nullptr != message_center()->FindVisibleNotificationById(id); | |
1380 } | |
1381 | |
1382 bool IsMessageCenterEmpty() const { | |
1383 return message_center()->GetVisibleNotifications().empty(); | |
1384 } | |
1385 | |
1386 void RemoveAllNotifications() const { | |
1387 message_center()->RemoveAllNotifications( | |
1388 false /* by_user */, message_center::MessageCenter::RemoveType::ALL); | |
1389 } | |
1390 | |
1391 message_center::MessageCenter* message_center() const { | |
1392 return message_center::MessageCenter::Get(); | |
1393 } | |
1394 | |
1395 private: | |
1396 DISALLOW_COPY_AND_ASSIGN(DeprecatedAcceleratorTester); | |
1397 }; | |
1398 | |
1399 } // namespace | |
1400 | |
1401 // TODO: disabled because of UnblockUserSession() not working: | |
1402 // http://crbug.com/632201. | |
1403 TEST_F(DeprecatedAcceleratorTester, | |
1404 DISABLED_TestDeprecatedAcceleratorsBehavior) { | |
1405 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) { | |
1406 const AcceleratorData& entry = kDeprecatedAccelerators[i]; | |
1407 | |
1408 auto itr = GetController()->actions_with_deprecations_.find(entry.action); | |
1409 ASSERT_TRUE(itr != GetController()->actions_with_deprecations_.end()); | |
1410 const DeprecatedAcceleratorData* data = itr->second; | |
1411 | |
1412 EXPECT_TRUE(IsMessageCenterEmpty()); | |
1413 ui::Accelerator deprecated_accelerator = CreateAccelerator(entry); | |
1414 if (data->deprecated_enabled) | |
1415 EXPECT_TRUE(ProcessInController(deprecated_accelerator)); | |
1416 else | |
1417 EXPECT_FALSE(ProcessInController(deprecated_accelerator)); | |
1418 | |
1419 // We expect to see a notification in the message center. | |
1420 EXPECT_TRUE( | |
1421 ContainsDeprecatedAcceleratorNotification(data->uma_histogram_name)); | |
1422 RemoveAllNotifications(); | |
1423 | |
1424 // If the action is LOCK_SCREEN, we must reset the state by unlocking the | |
1425 // screen before we proceed testing the rest of accelerators. | |
1426 ResetStateIfNeeded(); | |
1427 } | |
1428 } | |
1429 | |
1430 // TODO: disabled because of UnblockUserSession() not working: | |
1431 // http://crbug.com/632201. | |
1432 TEST_F(DeprecatedAcceleratorTester, DISABLED_TestNewAccelerators) { | |
1433 // Add below the new accelerators that replaced the deprecated ones (if any). | |
1434 const AcceleratorData kNewAccelerators[] = { | |
1435 {true, ui::VKEY_L, ui::EF_COMMAND_DOWN, LOCK_SCREEN}, | |
1436 {true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, NEXT_IME}, | |
1437 {true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, SHOW_TASK_MANAGER}, | |
1438 }; | |
1439 | |
1440 EXPECT_TRUE(IsMessageCenterEmpty()); | |
1441 | |
1442 for (auto data : kNewAccelerators) { | |
1443 EXPECT_TRUE(ProcessInController(CreateAccelerator(data))); | |
1444 | |
1445 // Expect no notifications from the new accelerators. | |
1446 EXPECT_TRUE(IsMessageCenterEmpty()); | |
1447 | |
1448 // If the action is LOCK_SCREEN, we must reset the state by unlocking the | |
1449 // screen before we proceed testing the rest of accelerators. | |
1450 ResetStateIfNeeded(); | |
1451 } | |
1452 } | |
1453 | |
1454 } // namespace ash | |
OLD | NEW |