Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ash / touch / touch_observer_hud_unittest.cc
blobf7293a55a429d3ee8bb6d7e7049355b91d3985c8
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/touch/touch_observer_hud.h"
7 #include "ash/ash_switches.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/root_window_controller.h"
10 #include "ash/screen_util.h"
11 #include "ash/shell.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/test/display_manager_test_api.h"
14 #include "ash/touch/touch_hud_debug.h"
15 #include "ash/touch/touch_hud_projection.h"
16 #include "base/command_line.h"
17 #include "base/format_macros.h"
18 #include "base/strings/stringprintf.h"
19 #include "ui/aura/window.h"
20 #include "ui/views/widget/widget.h"
22 namespace ash {
24 class TouchHudTestBase : public test::AshTestBase {
25 public:
26 TouchHudTestBase() {}
27 ~TouchHudTestBase() override {}
29 void SetUp() override {
30 test::AshTestBase::SetUp();
32 // Initialize display infos. They should be initialized after Ash
33 // environment is set up, i.e., after test::AshTestBase::SetUp().
34 internal_display_id_ =
35 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
36 external_display_id_ = 10;
37 mirrored_display_id_ = 11;
39 internal_display_info_ =
40 CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
41 external_display_info_ =
42 CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
43 mirrored_display_info_ =
44 CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
47 gfx::Display GetPrimaryDisplay() {
48 return Shell::GetScreen()->GetPrimaryDisplay();
51 const gfx::Display& GetSecondaryDisplay() {
52 return ScreenUtil::GetSecondaryDisplay();
55 void SetupSingleDisplay() {
56 display_info_list_.clear();
57 display_info_list_.push_back(internal_display_info_);
58 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
61 void SetupDualDisplays() {
62 display_info_list_.clear();
63 display_info_list_.push_back(internal_display_info_);
64 display_info_list_.push_back(external_display_info_);
65 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
68 void SetInternalAsPrimary() {
69 const gfx::Display& internal_display =
70 GetDisplayManager()->GetDisplayForId(internal_display_id_);
71 GetWindowTreeHostManager()->SetPrimaryDisplay(internal_display);
74 void SetExternalAsPrimary() {
75 const gfx::Display& external_display =
76 GetDisplayManager()->GetDisplayForId(external_display_id_);
77 GetWindowTreeHostManager()->SetPrimaryDisplay(external_display);
80 void MirrorDisplays() {
81 DCHECK_EQ(2U, display_info_list_.size());
82 DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
83 DCHECK_EQ(external_display_id_, display_info_list_[1].id());
84 display_info_list_[1] = mirrored_display_info_;
85 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
88 void UnmirrorDisplays() {
89 DCHECK_EQ(2U, display_info_list_.size());
90 DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
91 DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
92 display_info_list_[1] = external_display_info_;
93 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
96 void RemoveInternalDisplay() {
97 DCHECK_LT(0U, display_info_list_.size());
98 DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
99 display_info_list_.erase(display_info_list_.begin());
100 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
103 void RemoveExternalDisplay() {
104 DCHECK_EQ(2U, display_info_list_.size());
105 display_info_list_.pop_back();
106 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
109 void AddInternalDisplay() {
110 DCHECK_EQ(0U, display_info_list_.size());
111 display_info_list_.push_back(internal_display_info_);
112 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
115 void AddExternalDisplay() {
116 DCHECK_EQ(1U, display_info_list_.size());
117 display_info_list_.push_back(external_display_info_);
118 GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
121 int64 internal_display_id() const {
122 return internal_display_id_;
125 int64 external_display_id() const {
126 return external_display_id_;
129 protected:
130 DisplayManager* GetDisplayManager() {
131 return Shell::GetInstance()->display_manager();
134 WindowTreeHostManager* GetWindowTreeHostManager() {
135 return Shell::GetInstance()->window_tree_host_manager();
138 const gfx::Display& GetInternalDisplay() {
139 return GetDisplayManager()->GetDisplayForId(internal_display_id_);
142 const gfx::Display& GetExternalDisplay() {
143 return GetDisplayManager()->GetDisplayForId(external_display_id_);
146 aura::Window* GetInternalRootWindow() {
147 return GetWindowTreeHostManager()->GetRootWindowForDisplayId(
148 internal_display_id_);
151 aura::Window* GetExternalRootWindow() {
152 return GetWindowTreeHostManager()->GetRootWindowForDisplayId(
153 external_display_id_);
156 aura::Window* GetPrimaryRootWindow() {
157 const gfx::Display& display = GetPrimaryDisplay();
158 return GetWindowTreeHostManager()->GetRootWindowForDisplayId(display.id());
161 aura::Window* GetSecondaryRootWindow() {
162 const gfx::Display& display = GetSecondaryDisplay();
163 return GetWindowTreeHostManager()->GetRootWindowForDisplayId(display.id());
166 RootWindowController* GetInternalRootController() {
167 aura::Window* root = GetInternalRootWindow();
168 return GetRootWindowController(root);
171 RootWindowController* GetExternalRootController() {
172 aura::Window* root = GetExternalRootWindow();
173 return GetRootWindowController(root);
176 RootWindowController* GetPrimaryRootController() {
177 aura::Window* root = GetPrimaryRootWindow();
178 return GetRootWindowController(root);
181 RootWindowController* GetSecondaryRootController() {
182 aura::Window* root = GetSecondaryRootWindow();
183 return GetRootWindowController(root);
186 DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
187 DisplayInfo info(id, base::StringPrintf("x-%" PRId64, id), false);
188 info.SetBounds(bounds);
189 return info;
192 aura::Window* GetRootWindowForTouchHud(TouchObserverHUD* hud) {
193 return hud->root_window_;
196 views::Widget* GetWidgetForTouchHud(TouchObserverHUD* hud) {
197 return hud->widget_;
200 int64 internal_display_id_;
201 int64 external_display_id_;
202 int64 mirrored_display_id_;
203 DisplayInfo internal_display_info_;
204 DisplayInfo external_display_info_;
205 DisplayInfo mirrored_display_info_;
207 std::vector<DisplayInfo> display_info_list_;
209 DISALLOW_COPY_AND_ASSIGN(TouchHudTestBase);
212 class TouchHudDebugTest : public TouchHudTestBase {
213 public:
214 TouchHudDebugTest() {}
215 ~TouchHudDebugTest() override {}
217 void SetUp() override {
218 // Add ash-touch-hud flag to enable debug touch HUD. This flag should be set
219 // before Ash environment is set up, i.e., before TouchHudTestBase::SetUp().
220 base::CommandLine::ForCurrentProcess()->AppendSwitch(
221 ash::switches::kAshTouchHud);
223 TouchHudTestBase::SetUp();
226 void CheckInternalDisplay() {
227 EXPECT_NE(static_cast<TouchObserverHUD*>(NULL), GetInternalTouchHudDebug());
228 EXPECT_EQ(internal_display_id(), GetInternalTouchHudDebug()->display_id());
229 EXPECT_EQ(GetInternalRootWindow(),
230 GetRootWindowForTouchHud(GetInternalTouchHudDebug()));
231 EXPECT_EQ(GetInternalRootWindow(),
232 GetWidgetForTouchHud(GetInternalTouchHudDebug())->
233 GetNativeView()->GetRootWindow());
234 EXPECT_EQ(GetInternalDisplay().size(),
235 GetWidgetForTouchHud(GetInternalTouchHudDebug())->
236 GetWindowBoundsInScreen().size());
239 void CheckExternalDisplay() {
240 EXPECT_NE(static_cast<TouchHudDebug*>(NULL), GetExternalTouchHudDebug());
241 EXPECT_EQ(external_display_id(), GetExternalTouchHudDebug()->display_id());
242 EXPECT_EQ(GetExternalRootWindow(),
243 GetRootWindowForTouchHud(GetExternalTouchHudDebug()));
244 EXPECT_EQ(GetExternalRootWindow(),
245 GetWidgetForTouchHud(GetExternalTouchHudDebug())->
246 GetNativeView()->GetRootWindow());
247 EXPECT_EQ(GetExternalDisplay().size(),
248 GetWidgetForTouchHud(GetExternalTouchHudDebug())->
249 GetWindowBoundsInScreen().size());
252 private:
253 TouchHudDebug* GetInternalTouchHudDebug() {
254 return GetInternalRootController()->touch_hud_debug();
257 TouchHudDebug* GetExternalTouchHudDebug() {
258 return GetExternalRootController()->touch_hud_debug();
261 TouchHudDebug* GetPrimaryTouchHudDebug() {
262 return GetPrimaryRootController()->touch_hud_debug();
265 TouchHudDebug* GetSecondaryTouchHudDebug() {
266 return GetSecondaryRootController()->touch_hud_debug();
269 DISALLOW_COPY_AND_ASSIGN(TouchHudDebugTest);
272 class TouchHudProjectionTest : public TouchHudTestBase {
273 public:
274 TouchHudProjectionTest() {}
275 ~TouchHudProjectionTest() override {}
277 void EnableTouchHudProjection() {
278 Shell::GetInstance()->SetTouchHudProjectionEnabled(true);
281 void DisableTouchHudProjection() {
282 Shell::GetInstance()->SetTouchHudProjectionEnabled(false);
285 TouchHudProjection* GetInternalTouchHudProjection() {
286 return GetInternalRootController()->touch_hud_projection();
289 int GetInternalTouchPointsCount() {
290 return GetInternalTouchHudProjection()->points_.size();
293 void SendTouchEventToInternalHud(ui::EventType type,
294 const gfx::Point& location,
295 int touch_id) {
296 ui::TouchEvent event(type, location, touch_id, event_time);
297 GetInternalTouchHudProjection()->OnTouchEvent(&event);
299 // Advance time for next event.
300 event_time += base::TimeDelta::FromMilliseconds(100);
303 private:
304 base::TimeDelta event_time;
306 DISALLOW_COPY_AND_ASSIGN(TouchHudProjectionTest);
309 // Checks if debug touch HUD is correctly initialized for a single display.
310 TEST_F(TouchHudDebugTest, SingleDisplay) {
311 // Setup a single display setting.
312 SetupSingleDisplay();
314 // Check if touch HUD is set correctly and associated with appropriate
315 // display.
316 CheckInternalDisplay();
319 // Checks if debug touch HUDs are correctly initialized for two displays.
320 TEST_F(TouchHudDebugTest, DualDisplays) {
321 if (!SupportsMultipleDisplays())
322 return;
324 // Setup a dual display setting.
325 SetupDualDisplays();
327 // Check if touch HUDs are set correctly and associated with appropriate
328 // displays.
329 CheckInternalDisplay();
330 CheckExternalDisplay();
333 // Checks if debug touch HUDs are correctly handled when primary display is
334 // changed.
335 TEST_F(TouchHudDebugTest, SwapPrimaryDisplay) {
336 if (!SupportsMultipleDisplays())
337 return;
339 // Setup a dual display setting.
340 SetupDualDisplays();
342 // Set the primary display to the external one.
343 SetExternalAsPrimary();
345 // Check if displays' touch HUDs are not swapped as root windows are.
346 EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
347 EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
348 CheckInternalDisplay();
349 CheckExternalDisplay();
351 // Set the primary display back to the internal one.
352 SetInternalAsPrimary();
354 // Check if displays' touch HUDs are not swapped back as root windows are.
355 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
356 EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
357 CheckInternalDisplay();
358 CheckExternalDisplay();
361 // Checks if debug touch HUDs are correctly handled when displays are mirrored.
362 TEST_F(TouchHudDebugTest, MirrorDisplays) {
363 if (!SupportsMultipleDisplays())
364 return;
366 // Setup a dual display setting.
367 SetupDualDisplays();
369 // Mirror displays.
370 MirrorDisplays();
372 // Check if the internal display is intact.
373 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
374 CheckInternalDisplay();
376 // Unmirror displays.
377 UnmirrorDisplays();
379 // Check if external display is added back correctly.
380 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
381 EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
382 CheckInternalDisplay();
383 CheckExternalDisplay();
386 // Checks if debug touch HUDs are correctly handled when displays are mirrored
387 // after setting the external display as the primary one.
388 TEST_F(TouchHudDebugTest, SwapPrimaryThenMirrorDisplays) {
389 if (!SupportsMultipleDisplays())
390 return;
392 // Setup a dual display setting.
393 SetupDualDisplays();
395 // Set the primary display to the external one.
396 SetExternalAsPrimary();
398 // Mirror displays.
399 MirrorDisplays();
401 // Check if the internal display is set as the primary one.
402 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
403 CheckInternalDisplay();
405 // Unmirror displays.
406 UnmirrorDisplays();
408 // Check if the external display is added back as the primary display and
409 // touch HUDs are set correctly.
410 EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
411 EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
412 CheckInternalDisplay();
413 CheckExternalDisplay();
416 // Checks if debug touch HUDs are correctly handled when the external display,
417 // which is the secondary one, is removed.
418 TEST_F(TouchHudDebugTest, RemoveSecondaryDisplay) {
419 if (!SupportsMultipleDisplays())
420 return;
422 // Setup a dual display setting.
423 SetupDualDisplays();
425 // Remove external display which is the secondary one.
426 RemoveExternalDisplay();
428 // Check if the internal display is intact.
429 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
430 CheckInternalDisplay();
432 // Add external display back.
433 AddExternalDisplay();
435 // Check if displays' touch HUDs are set correctly.
436 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
437 EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
438 CheckInternalDisplay();
439 CheckExternalDisplay();
442 // Checks if debug touch HUDs are correctly handled when the external display,
443 // which is set as the primary display, is removed.
444 TEST_F(TouchHudDebugTest, RemovePrimaryDisplay) {
445 if (!SupportsMultipleDisplays())
446 return;
448 // Setup a dual display setting.
449 SetupDualDisplays();
451 // Set the primary display to the external one.
452 SetExternalAsPrimary();
454 // Remove the external display which is the primary display.
455 RemoveExternalDisplay();
457 // Check if the internal display is set as the primary one.
458 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
459 CheckInternalDisplay();
461 // Add the external display back.
462 AddExternalDisplay();
464 // Check if the external display is set as primary and touch HUDs are set
465 // correctly.
466 EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
467 EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
468 CheckInternalDisplay();
469 CheckExternalDisplay();
472 // Checks if debug touch HUDs are correctly handled when all displays are
473 // removed.
474 TEST_F(TouchHudDebugTest, Headless) {
475 if (!SupportsMultipleDisplays())
476 return;
478 // Setup a single display setting.
479 SetupSingleDisplay();
481 // Remove the only display which is the internal one.
482 RemoveInternalDisplay();
484 // Add the internal display back.
485 AddInternalDisplay();
487 // Check if the display's touch HUD is set correctly.
488 EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
489 CheckInternalDisplay();
492 // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
493 // and touch-released events.
494 TEST_F(TouchHudProjectionTest, TouchMoveRelease) {
495 SetupSingleDisplay();
496 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
498 EnableTouchHudProjection();
499 EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
500 GetInternalTouchHudProjection());
501 EXPECT_EQ(0, GetInternalTouchPointsCount());
503 SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
504 EXPECT_EQ(1, GetInternalTouchPointsCount());
506 SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
507 EXPECT_EQ(1, GetInternalTouchPointsCount());
509 SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
510 EXPECT_EQ(0, GetInternalTouchPointsCount());
512 // Disabling projection touch HUD shoud remove it without crashing.
513 DisableTouchHudProjection();
514 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
517 // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
518 // and touch-cancelled events.
519 TEST_F(TouchHudProjectionTest, TouchMoveCancel) {
520 SetupSingleDisplay();
521 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
523 EnableTouchHudProjection();
524 EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
525 GetInternalTouchHudProjection());
526 EXPECT_EQ(0, GetInternalTouchPointsCount());
528 SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
529 EXPECT_EQ(1, GetInternalTouchPointsCount());
531 SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
532 EXPECT_EQ(1, GetInternalTouchPointsCount());
534 SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
535 EXPECT_EQ(0, GetInternalTouchPointsCount());
537 // Disabling projection touch HUD shoud remove it without crashing.
538 DisableTouchHudProjection();
539 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
542 // Checks projection touch HUD with two simultaneous touches.
543 TEST_F(TouchHudProjectionTest, DoubleTouch) {
544 SetupSingleDisplay();
545 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
547 EnableTouchHudProjection();
548 EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
549 GetInternalTouchHudProjection());
550 EXPECT_EQ(0, GetInternalTouchPointsCount());
552 SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
553 EXPECT_EQ(1, GetInternalTouchPointsCount());
555 SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
556 EXPECT_EQ(2, GetInternalTouchPointsCount());
558 SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
559 EXPECT_EQ(2, GetInternalTouchPointsCount());
561 SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
562 EXPECT_EQ(2, GetInternalTouchPointsCount());
564 SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
565 EXPECT_EQ(1, GetInternalTouchPointsCount());
567 SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
568 EXPECT_EQ(0, GetInternalTouchPointsCount());
570 // Disabling projection touch HUD shoud remove it without crashing.
571 DisableTouchHudProjection();
572 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
575 // Checks if turning off touch HUD projection while touching the screen is
576 // handled correctly.
577 TEST_F(TouchHudProjectionTest, DisableWhileTouching) {
578 SetupSingleDisplay();
579 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
581 EnableTouchHudProjection();
582 EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
583 GetInternalTouchHudProjection());
584 EXPECT_EQ(0, GetInternalTouchPointsCount());
586 SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
587 EXPECT_EQ(1, GetInternalTouchPointsCount());
589 // Disabling projection touch HUD shoud remove it without crashing.
590 DisableTouchHudProjection();
591 EXPECT_EQ(NULL, GetInternalTouchHudProjection());
594 } // namespace ash