Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / touch / touch_observer_hud_unittest.cc
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.
4
5 #include "ash/touch/touch_observer_hud.h"
6
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
21 namespace ash {
22
23 class TouchHudTestBase : public test::AshTestBase {
24  public:
25   TouchHudTestBase() {}
26   virtual ~TouchHudTestBase() {}
27
28   virtual void SetUp() OVERRIDE {
29     test::AshTestBase::SetUp();
30
31     // Initialize display infos. They should be initialized after Ash
32     // environment is set up, i.e., after test::AshTestBase::SetUp().
33     internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()).
34         SetFirstDisplayAsInternalDisplay();
35     external_display_id_ = 10;
36     mirrored_display_id_ = 11;
37
38     internal_display_info_ =
39         CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
40     external_display_info_ =
41         CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
42     mirrored_display_info_ =
43         CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
44   }
45
46   gfx::Display GetPrimaryDisplay() {
47     return Shell::GetScreen()->GetPrimaryDisplay();
48   }
49
50   const gfx::Display& GetSecondaryDisplay() {
51     return ScreenUtil::GetSecondaryDisplay();
52   }
53
54   void SetupSingleDisplay() {
55     display_info_list_.clear();
56     display_info_list_.push_back(internal_display_info_);
57     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
58   }
59
60   void SetupDualDisplays() {
61     display_info_list_.clear();
62     display_info_list_.push_back(internal_display_info_);
63     display_info_list_.push_back(external_display_info_);
64     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
65   }
66
67   void SetInternalAsPrimary() {
68     const gfx::Display& internal_display =
69         GetDisplayManager()->GetDisplayForId(internal_display_id_);
70     GetDisplayController()->SetPrimaryDisplay(internal_display);
71   }
72
73   void SetExternalAsPrimary() {
74     const gfx::Display& external_display =
75         GetDisplayManager()->GetDisplayForId(external_display_id_);
76     GetDisplayController()->SetPrimaryDisplay(external_display);
77   }
78
79   void MirrorDisplays() {
80     DCHECK_EQ(2U, display_info_list_.size());
81     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
82     DCHECK_EQ(external_display_id_, display_info_list_[1].id());
83     display_info_list_[1] = mirrored_display_info_;
84     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
85   }
86
87   void UnmirrorDisplays() {
88     DCHECK_EQ(2U, display_info_list_.size());
89     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
90     DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
91     display_info_list_[1] = external_display_info_;
92     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
93   }
94
95   void RemoveInternalDisplay() {
96     DCHECK_LT(0U, display_info_list_.size());
97     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
98     display_info_list_.erase(display_info_list_.begin());
99     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
100   }
101
102   void RemoveExternalDisplay() {
103     DCHECK_EQ(2U, display_info_list_.size());
104     display_info_list_.pop_back();
105     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
106   }
107
108   void AddInternalDisplay() {
109     DCHECK_EQ(0U, display_info_list_.size());
110     display_info_list_.push_back(internal_display_info_);
111     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
112   }
113
114   void AddExternalDisplay() {
115     DCHECK_EQ(1U, display_info_list_.size());
116     display_info_list_.push_back(external_display_info_);
117     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
118   }
119
120   int64 internal_display_id() const {
121     return internal_display_id_;
122   }
123
124   int64 external_display_id() const {
125     return external_display_id_;
126   }
127
128  protected:
129   DisplayManager* GetDisplayManager() {
130     return Shell::GetInstance()->display_manager();
131   }
132
133   DisplayController* GetDisplayController() {
134     return Shell::GetInstance()->display_controller();
135   }
136
137   const gfx::Display& GetInternalDisplay() {
138     return GetDisplayManager()->GetDisplayForId(internal_display_id_);
139   }
140
141   const gfx::Display& GetExternalDisplay() {
142     return GetDisplayManager()->GetDisplayForId(external_display_id_);
143   }
144
145   aura::Window* GetInternalRootWindow() {
146     return GetDisplayController()->GetRootWindowForDisplayId(
147         internal_display_id_);
148   }
149
150   aura::Window* GetExternalRootWindow() {
151     return GetDisplayController()->GetRootWindowForDisplayId(
152         external_display_id_);
153   }
154
155   aura::Window* GetPrimaryRootWindow() {
156     const gfx::Display& display = GetPrimaryDisplay();
157     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
158   }
159
160   aura::Window* GetSecondaryRootWindow() {
161     const gfx::Display& display = GetSecondaryDisplay();
162     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
163   }
164
165   RootWindowController* GetInternalRootController() {
166     aura::Window* root = GetInternalRootWindow();
167     return GetRootWindowController(root);
168   }
169
170   RootWindowController* GetExternalRootController() {
171     aura::Window* root = GetExternalRootWindow();
172     return GetRootWindowController(root);
173   }
174
175   RootWindowController* GetPrimaryRootController() {
176     aura::Window* root = GetPrimaryRootWindow();
177     return GetRootWindowController(root);
178   }
179
180   RootWindowController* GetSecondaryRootController() {
181     aura::Window* root = GetSecondaryRootWindow();
182     return GetRootWindowController(root);
183   }
184
185   DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
186     DisplayInfo info(id, base::StringPrintf("x-%" PRId64, id), false);
187     info.SetBounds(bounds);
188     return info;
189   }
190
191   aura::Window* GetRootWindowForTouchHud(TouchObserverHUD* hud) {
192     return hud->root_window_;
193   }
194
195   views::Widget* GetWidgetForTouchHud(TouchObserverHUD* hud) {
196     return hud->widget_;
197   }
198
199   int64 internal_display_id_;
200   int64 external_display_id_;
201   int64 mirrored_display_id_;
202   DisplayInfo internal_display_info_;
203   DisplayInfo external_display_info_;
204   DisplayInfo mirrored_display_info_;
205
206   std::vector<DisplayInfo> display_info_list_;
207
208   DISALLOW_COPY_AND_ASSIGN(TouchHudTestBase);
209 };
210
211 class TouchHudDebugTest : public TouchHudTestBase {
212  public:
213   TouchHudDebugTest() {}
214   virtual ~TouchHudDebugTest() {}
215
216   virtual void SetUp() OVERRIDE {
217     // Add ash-touch-hud flag to enable debug touch HUD. This flag should be set
218     // before Ash environment is set up, i.e., before TouchHudTestBase::SetUp().
219     CommandLine::ForCurrentProcess()->AppendSwitch(
220         ash::switches::kAshTouchHud);
221
222     TouchHudTestBase::SetUp();
223   }
224
225   void CheckInternalDisplay() {
226     EXPECT_NE(static_cast<TouchObserverHUD*>(NULL), GetInternalTouchHudDebug());
227     EXPECT_EQ(internal_display_id(), GetInternalTouchHudDebug()->display_id());
228     EXPECT_EQ(GetInternalRootWindow(),
229               GetRootWindowForTouchHud(GetInternalTouchHudDebug()));
230     EXPECT_EQ(GetInternalRootWindow(),
231               GetWidgetForTouchHud(GetInternalTouchHudDebug())->
232                   GetNativeView()->GetRootWindow());
233     EXPECT_EQ(GetInternalDisplay().size(),
234               GetWidgetForTouchHud(GetInternalTouchHudDebug())->
235                   GetWindowBoundsInScreen().size());
236   }
237
238   void CheckExternalDisplay() {
239     EXPECT_NE(static_cast<TouchHudDebug*>(NULL), GetExternalTouchHudDebug());
240     EXPECT_EQ(external_display_id(), GetExternalTouchHudDebug()->display_id());
241     EXPECT_EQ(GetExternalRootWindow(),
242               GetRootWindowForTouchHud(GetExternalTouchHudDebug()));
243     EXPECT_EQ(GetExternalRootWindow(),
244               GetWidgetForTouchHud(GetExternalTouchHudDebug())->
245                   GetNativeView()->GetRootWindow());
246     EXPECT_EQ(GetExternalDisplay().size(),
247               GetWidgetForTouchHud(GetExternalTouchHudDebug())->
248                   GetWindowBoundsInScreen().size());
249   }
250
251  private:
252   TouchHudDebug* GetInternalTouchHudDebug() {
253     return GetInternalRootController()->touch_hud_debug();
254   }
255
256   TouchHudDebug* GetExternalTouchHudDebug() {
257     return GetExternalRootController()->touch_hud_debug();
258   }
259
260   TouchHudDebug* GetPrimaryTouchHudDebug() {
261     return GetPrimaryRootController()->touch_hud_debug();
262   }
263
264   TouchHudDebug* GetSecondaryTouchHudDebug() {
265     return GetSecondaryRootController()->touch_hud_debug();
266   }
267
268   DISALLOW_COPY_AND_ASSIGN(TouchHudDebugTest);
269 };
270
271 class TouchHudProjectionTest : public TouchHudTestBase {
272  public:
273   TouchHudProjectionTest() {}
274   virtual ~TouchHudProjectionTest() {}
275
276   void EnableTouchHudProjection() {
277     Shell::GetInstance()->SetTouchHudProjectionEnabled(true);
278   }
279
280   void DisableTouchHudProjection() {
281     Shell::GetInstance()->SetTouchHudProjectionEnabled(false);
282   }
283
284   TouchHudProjection* GetInternalTouchHudProjection() {
285     return GetInternalRootController()->touch_hud_projection();
286   }
287
288   int GetInternalTouchPointsCount() {
289     return GetInternalTouchHudProjection()->points_.size();
290   }
291
292   void SendTouchEventToInternalHud(ui::EventType type,
293                                    const gfx::Point& location,
294                                    int touch_id) {
295     ui::TouchEvent event(type, location, touch_id, event_time);
296     GetInternalTouchHudProjection()->OnTouchEvent(&event);
297
298     // Advance time for next event.
299     event_time += base::TimeDelta::FromMilliseconds(100);
300   }
301
302  private:
303   base::TimeDelta event_time;
304
305   DISALLOW_COPY_AND_ASSIGN(TouchHudProjectionTest);
306 };
307
308 // Checks if debug touch HUD is correctly initialized for a single display.
309 TEST_F(TouchHudDebugTest, SingleDisplay) {
310   // Setup a single display setting.
311   SetupSingleDisplay();
312
313   // Check if touch HUD is set correctly and associated with appropriate
314   // display.
315   CheckInternalDisplay();
316 }
317
318 // Checks if debug touch HUDs are correctly initialized for two displays.
319 TEST_F(TouchHudDebugTest, DualDisplays) {
320   if (!SupportsMultipleDisplays())
321     return;
322
323   // Setup a dual display setting.
324   SetupDualDisplays();
325
326   // Check if touch HUDs are set correctly and associated with appropriate
327   // displays.
328   CheckInternalDisplay();
329   CheckExternalDisplay();
330 }
331
332 // Checks if debug touch HUDs are correctly handled when primary display is
333 // changed.
334 TEST_F(TouchHudDebugTest, SwapPrimaryDisplay) {
335   if (!SupportsMultipleDisplays())
336     return;
337
338   // Setup a dual display setting.
339   SetupDualDisplays();
340
341   // Set the primary display to the external one.
342   SetExternalAsPrimary();
343
344   // Check if displays' touch HUDs are not swapped as root windows are.
345   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
346   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
347   CheckInternalDisplay();
348   CheckExternalDisplay();
349
350   // Set the primary display back to the internal one.
351   SetInternalAsPrimary();
352
353   // Check if displays' touch HUDs are not swapped back as root windows are.
354   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
355   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
356   CheckInternalDisplay();
357   CheckExternalDisplay();
358 }
359
360 // Checks if debug touch HUDs are correctly handled when displays are mirrored.
361 TEST_F(TouchHudDebugTest, MirrorDisplays) {
362   if (!SupportsMultipleDisplays())
363     return;
364
365   // Setup a dual display setting.
366   SetupDualDisplays();
367
368   // Mirror displays.
369   MirrorDisplays();
370
371   // Check if the internal display is intact.
372   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
373   CheckInternalDisplay();
374
375   // Unmirror displays.
376   UnmirrorDisplays();
377
378   // Check if external display is added back correctly.
379   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
380   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
381   CheckInternalDisplay();
382   CheckExternalDisplay();
383 }
384
385 // Checks if debug touch HUDs are correctly handled when displays are mirrored
386 // after setting the external display as the primary one.
387 TEST_F(TouchHudDebugTest, SwapPrimaryThenMirrorDisplays) {
388   if (!SupportsMultipleDisplays())
389     return;
390
391   // Setup a dual display setting.
392   SetupDualDisplays();
393
394   // Set the primary display to the external one.
395   SetExternalAsPrimary();
396
397   // Mirror displays.
398   MirrorDisplays();
399
400   // Check if the internal display is set as the primary one.
401   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
402   CheckInternalDisplay();
403
404   // Unmirror displays.
405   UnmirrorDisplays();
406
407   // Check if the external display is added back as the primary display and
408   // touch HUDs are set correctly.
409   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
410   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
411   CheckInternalDisplay();
412   CheckExternalDisplay();
413 }
414
415 // Checks if debug touch HUDs are correctly handled when the external display,
416 // which is the secondary one, is removed.
417 TEST_F(TouchHudDebugTest, RemoveSecondaryDisplay) {
418   if (!SupportsMultipleDisplays())
419     return;
420
421   // Setup a dual display setting.
422   SetupDualDisplays();
423
424   // Remove external display which is the secondary one.
425   RemoveExternalDisplay();
426
427   // Check if the internal display is intact.
428   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
429   CheckInternalDisplay();
430
431   // Add external display back.
432   AddExternalDisplay();
433
434   // Check if displays' touch HUDs are set correctly.
435   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
436   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
437   CheckInternalDisplay();
438   CheckExternalDisplay();
439 }
440
441 // Checks if debug touch HUDs are correctly handled when the external display,
442 // which is set as the primary display, is removed.
443 TEST_F(TouchHudDebugTest, RemovePrimaryDisplay) {
444   if (!SupportsMultipleDisplays())
445     return;
446
447   // Setup a dual display setting.
448   SetupDualDisplays();
449
450   // Set the primary display to the external one.
451   SetExternalAsPrimary();
452
453   // Remove the external display which is the primary display.
454   RemoveExternalDisplay();
455
456   // Check if the internal display is set as the primary one.
457   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
458   CheckInternalDisplay();
459
460   // Add the external display back.
461   AddExternalDisplay();
462
463   // Check if the external display is set as primary and touch HUDs are set
464   // correctly.
465   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
466   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
467   CheckInternalDisplay();
468   CheckExternalDisplay();
469 }
470
471 // Checks if debug touch HUDs are correctly handled when all displays are
472 // removed.
473 TEST_F(TouchHudDebugTest, Headless) {
474   if (!SupportsMultipleDisplays())
475     return;
476
477   // Setup a single display setting.
478   SetupSingleDisplay();
479
480   // Remove the only display which is the internal one.
481   RemoveInternalDisplay();
482
483   // Add the internal display back.
484   AddInternalDisplay();
485
486   // Check if the display's touch HUD is set correctly.
487   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
488   CheckInternalDisplay();
489 }
490
491 // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
492 // and touch-released events.
493 TEST_F(TouchHudProjectionTest, TouchMoveRelease) {
494   SetupSingleDisplay();
495   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
496
497   EnableTouchHudProjection();
498   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
499             GetInternalTouchHudProjection());
500   EXPECT_EQ(0, GetInternalTouchPointsCount());
501
502   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
503   EXPECT_EQ(1, GetInternalTouchPointsCount());
504
505   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
506   EXPECT_EQ(1, GetInternalTouchPointsCount());
507
508   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
509   EXPECT_EQ(0, GetInternalTouchPointsCount());
510
511   // Disabling projection touch HUD shoud remove it without crashing.
512   DisableTouchHudProjection();
513   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
514 }
515
516 // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
517 // and touch-cancelled events.
518 TEST_F(TouchHudProjectionTest, TouchMoveCancel) {
519   SetupSingleDisplay();
520   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
521
522   EnableTouchHudProjection();
523   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
524             GetInternalTouchHudProjection());
525   EXPECT_EQ(0, GetInternalTouchPointsCount());
526
527   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
528   EXPECT_EQ(1, GetInternalTouchPointsCount());
529
530   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
531   EXPECT_EQ(1, GetInternalTouchPointsCount());
532
533   SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
534   EXPECT_EQ(0, GetInternalTouchPointsCount());
535
536   // Disabling projection touch HUD shoud remove it without crashing.
537   DisableTouchHudProjection();
538   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
539 }
540
541 // Checks projection touch HUD with two simultaneous touches.
542 TEST_F(TouchHudProjectionTest, DoubleTouch) {
543   SetupSingleDisplay();
544   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
545
546   EnableTouchHudProjection();
547   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
548             GetInternalTouchHudProjection());
549   EXPECT_EQ(0, GetInternalTouchPointsCount());
550
551   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
552   EXPECT_EQ(1, GetInternalTouchPointsCount());
553
554   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
555   EXPECT_EQ(2, GetInternalTouchPointsCount());
556
557   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
558   EXPECT_EQ(2, GetInternalTouchPointsCount());
559
560   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
561   EXPECT_EQ(2, GetInternalTouchPointsCount());
562
563   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
564   EXPECT_EQ(1, GetInternalTouchPointsCount());
565
566   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
567   EXPECT_EQ(0, GetInternalTouchPointsCount());
568
569   // Disabling projection touch HUD shoud remove it without crashing.
570   DisableTouchHudProjection();
571   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
572 }
573
574 // Checks if turning off touch HUD projection while touching the screen is
575 // handled correctly.
576 TEST_F(TouchHudProjectionTest, DisableWhileTouching) {
577   SetupSingleDisplay();
578   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
579
580   EnableTouchHudProjection();
581   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
582             GetInternalTouchHudProjection());
583   EXPECT_EQ(0, GetInternalTouchPointsCount());
584
585   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
586   EXPECT_EQ(1, GetInternalTouchPointsCount());
587
588   // Disabling projection touch HUD shoud remove it without crashing.
589   DisableTouchHudProjection();
590   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
591 }
592
593 }  // namespace ash