Update To 11.40.268.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 #include "ui/views/widget/widget.h"
21
22 namespace ash {
23
24 class TouchHudTestBase : public test::AshTestBase {
25  public:
26   TouchHudTestBase() {}
27   ~TouchHudTestBase() override {}
28
29   void SetUp() override {
30     test::AshTestBase::SetUp();
31
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_ = test::DisplayManagerTestApi(GetDisplayManager()).
35         SetFirstDisplayAsInternalDisplay();
36     external_display_id_ = 10;
37     mirrored_display_id_ = 11;
38
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));
45   }
46
47   gfx::Display GetPrimaryDisplay() {
48     return Shell::GetScreen()->GetPrimaryDisplay();
49   }
50
51   const gfx::Display& GetSecondaryDisplay() {
52     return ScreenUtil::GetSecondaryDisplay();
53   }
54
55   void SetupSingleDisplay() {
56     display_info_list_.clear();
57     display_info_list_.push_back(internal_display_info_);
58     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
59   }
60
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_);
66   }
67
68   void SetInternalAsPrimary() {
69     const gfx::Display& internal_display =
70         GetDisplayManager()->GetDisplayForId(internal_display_id_);
71     GetDisplayController()->SetPrimaryDisplay(internal_display);
72   }
73
74   void SetExternalAsPrimary() {
75     const gfx::Display& external_display =
76         GetDisplayManager()->GetDisplayForId(external_display_id_);
77     GetDisplayController()->SetPrimaryDisplay(external_display);
78   }
79
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_);
86   }
87
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_);
94   }
95
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_);
101   }
102
103   void RemoveExternalDisplay() {
104     DCHECK_EQ(2U, display_info_list_.size());
105     display_info_list_.pop_back();
106     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
107   }
108
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_);
113   }
114
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_);
119   }
120
121   int64 internal_display_id() const {
122     return internal_display_id_;
123   }
124
125   int64 external_display_id() const {
126     return external_display_id_;
127   }
128
129  protected:
130   DisplayManager* GetDisplayManager() {
131     return Shell::GetInstance()->display_manager();
132   }
133
134   DisplayController* GetDisplayController() {
135     return Shell::GetInstance()->display_controller();
136   }
137
138   const gfx::Display& GetInternalDisplay() {
139     return GetDisplayManager()->GetDisplayForId(internal_display_id_);
140   }
141
142   const gfx::Display& GetExternalDisplay() {
143     return GetDisplayManager()->GetDisplayForId(external_display_id_);
144   }
145
146   aura::Window* GetInternalRootWindow() {
147     return GetDisplayController()->GetRootWindowForDisplayId(
148         internal_display_id_);
149   }
150
151   aura::Window* GetExternalRootWindow() {
152     return GetDisplayController()->GetRootWindowForDisplayId(
153         external_display_id_);
154   }
155
156   aura::Window* GetPrimaryRootWindow() {
157     const gfx::Display& display = GetPrimaryDisplay();
158     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
159   }
160
161   aura::Window* GetSecondaryRootWindow() {
162     const gfx::Display& display = GetSecondaryDisplay();
163     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
164   }
165
166   RootWindowController* GetInternalRootController() {
167     aura::Window* root = GetInternalRootWindow();
168     return GetRootWindowController(root);
169   }
170
171   RootWindowController* GetExternalRootController() {
172     aura::Window* root = GetExternalRootWindow();
173     return GetRootWindowController(root);
174   }
175
176   RootWindowController* GetPrimaryRootController() {
177     aura::Window* root = GetPrimaryRootWindow();
178     return GetRootWindowController(root);
179   }
180
181   RootWindowController* GetSecondaryRootController() {
182     aura::Window* root = GetSecondaryRootWindow();
183     return GetRootWindowController(root);
184   }
185
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;
190   }
191
192   aura::Window* GetRootWindowForTouchHud(TouchObserverHUD* hud) {
193     return hud->root_window_;
194   }
195
196   views::Widget* GetWidgetForTouchHud(TouchObserverHUD* hud) {
197     return hud->widget_;
198   }
199
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_;
206
207   std::vector<DisplayInfo> display_info_list_;
208
209   DISALLOW_COPY_AND_ASSIGN(TouchHudTestBase);
210 };
211
212 class TouchHudDebugTest : public TouchHudTestBase {
213  public:
214   TouchHudDebugTest() {}
215   ~TouchHudDebugTest() override {}
216
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);
222
223     TouchHudTestBase::SetUp();
224   }
225
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());
237   }
238
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());
250   }
251
252  private:
253   TouchHudDebug* GetInternalTouchHudDebug() {
254     return GetInternalRootController()->touch_hud_debug();
255   }
256
257   TouchHudDebug* GetExternalTouchHudDebug() {
258     return GetExternalRootController()->touch_hud_debug();
259   }
260
261   TouchHudDebug* GetPrimaryTouchHudDebug() {
262     return GetPrimaryRootController()->touch_hud_debug();
263   }
264
265   TouchHudDebug* GetSecondaryTouchHudDebug() {
266     return GetSecondaryRootController()->touch_hud_debug();
267   }
268
269   DISALLOW_COPY_AND_ASSIGN(TouchHudDebugTest);
270 };
271
272 class TouchHudProjectionTest : public TouchHudTestBase {
273  public:
274   TouchHudProjectionTest() {}
275   ~TouchHudProjectionTest() override {}
276
277   void EnableTouchHudProjection() {
278     Shell::GetInstance()->SetTouchHudProjectionEnabled(true);
279   }
280
281   void DisableTouchHudProjection() {
282     Shell::GetInstance()->SetTouchHudProjectionEnabled(false);
283   }
284
285   TouchHudProjection* GetInternalTouchHudProjection() {
286     return GetInternalRootController()->touch_hud_projection();
287   }
288
289   int GetInternalTouchPointsCount() {
290     return GetInternalTouchHudProjection()->points_.size();
291   }
292
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);
298
299     // Advance time for next event.
300     event_time += base::TimeDelta::FromMilliseconds(100);
301   }
302
303  private:
304   base::TimeDelta event_time;
305
306   DISALLOW_COPY_AND_ASSIGN(TouchHudProjectionTest);
307 };
308
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();
313
314   // Check if touch HUD is set correctly and associated with appropriate
315   // display.
316   CheckInternalDisplay();
317 }
318
319 // Checks if debug touch HUDs are correctly initialized for two displays.
320 TEST_F(TouchHudDebugTest, DualDisplays) {
321   if (!SupportsMultipleDisplays())
322     return;
323
324   // Setup a dual display setting.
325   SetupDualDisplays();
326
327   // Check if touch HUDs are set correctly and associated with appropriate
328   // displays.
329   CheckInternalDisplay();
330   CheckExternalDisplay();
331 }
332
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;
338
339   // Setup a dual display setting.
340   SetupDualDisplays();
341
342   // Set the primary display to the external one.
343   SetExternalAsPrimary();
344
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();
350
351   // Set the primary display back to the internal one.
352   SetInternalAsPrimary();
353
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();
359 }
360
361 // Checks if debug touch HUDs are correctly handled when displays are mirrored.
362 TEST_F(TouchHudDebugTest, MirrorDisplays) {
363   if (!SupportsMultipleDisplays())
364     return;
365
366   // Setup a dual display setting.
367   SetupDualDisplays();
368
369   // Mirror displays.
370   MirrorDisplays();
371
372   // Check if the internal display is intact.
373   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
374   CheckInternalDisplay();
375
376   // Unmirror displays.
377   UnmirrorDisplays();
378
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();
384 }
385
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;
391
392   // Setup a dual display setting.
393   SetupDualDisplays();
394
395   // Set the primary display to the external one.
396   SetExternalAsPrimary();
397
398   // Mirror displays.
399   MirrorDisplays();
400
401   // Check if the internal display is set as the primary one.
402   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
403   CheckInternalDisplay();
404
405   // Unmirror displays.
406   UnmirrorDisplays();
407
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();
414 }
415
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;
421
422   // Setup a dual display setting.
423   SetupDualDisplays();
424
425   // Remove external display which is the secondary one.
426   RemoveExternalDisplay();
427
428   // Check if the internal display is intact.
429   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
430   CheckInternalDisplay();
431
432   // Add external display back.
433   AddExternalDisplay();
434
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();
440 }
441
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;
447
448   // Setup a dual display setting.
449   SetupDualDisplays();
450
451   // Set the primary display to the external one.
452   SetExternalAsPrimary();
453
454   // Remove the external display which is the primary display.
455   RemoveExternalDisplay();
456
457   // Check if the internal display is set as the primary one.
458   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
459   CheckInternalDisplay();
460
461   // Add the external display back.
462   AddExternalDisplay();
463
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();
470 }
471
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;
477
478   // Setup a single display setting.
479   SetupSingleDisplay();
480
481   // Remove the only display which is the internal one.
482   RemoveInternalDisplay();
483
484   // Add the internal display back.
485   AddInternalDisplay();
486
487   // Check if the display's touch HUD is set correctly.
488   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
489   CheckInternalDisplay();
490 }
491
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());
497
498   EnableTouchHudProjection();
499   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
500             GetInternalTouchHudProjection());
501   EXPECT_EQ(0, GetInternalTouchPointsCount());
502
503   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
504   EXPECT_EQ(1, GetInternalTouchPointsCount());
505
506   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
507   EXPECT_EQ(1, GetInternalTouchPointsCount());
508
509   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
510   EXPECT_EQ(0, GetInternalTouchPointsCount());
511
512   // Disabling projection touch HUD shoud remove it without crashing.
513   DisableTouchHudProjection();
514   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
515 }
516
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());
522
523   EnableTouchHudProjection();
524   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
525             GetInternalTouchHudProjection());
526   EXPECT_EQ(0, GetInternalTouchPointsCount());
527
528   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
529   EXPECT_EQ(1, GetInternalTouchPointsCount());
530
531   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
532   EXPECT_EQ(1, GetInternalTouchPointsCount());
533
534   SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
535   EXPECT_EQ(0, GetInternalTouchPointsCount());
536
537   // Disabling projection touch HUD shoud remove it without crashing.
538   DisableTouchHudProjection();
539   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
540 }
541
542 // Checks projection touch HUD with two simultaneous touches.
543 TEST_F(TouchHudProjectionTest, DoubleTouch) {
544   SetupSingleDisplay();
545   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
546
547   EnableTouchHudProjection();
548   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
549             GetInternalTouchHudProjection());
550   EXPECT_EQ(0, GetInternalTouchPointsCount());
551
552   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
553   EXPECT_EQ(1, GetInternalTouchPointsCount());
554
555   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
556   EXPECT_EQ(2, GetInternalTouchPointsCount());
557
558   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
559   EXPECT_EQ(2, GetInternalTouchPointsCount());
560
561   SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
562   EXPECT_EQ(2, GetInternalTouchPointsCount());
563
564   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
565   EXPECT_EQ(1, GetInternalTouchPointsCount());
566
567   SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
568   EXPECT_EQ(0, GetInternalTouchPointsCount());
569
570   // Disabling projection touch HUD shoud remove it without crashing.
571   DisableTouchHudProjection();
572   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
573 }
574
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());
580
581   EnableTouchHudProjection();
582   EXPECT_NE(static_cast<TouchHudProjection*>(NULL),
583             GetInternalTouchHudProjection());
584   EXPECT_EQ(0, GetInternalTouchPointsCount());
585
586   SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
587   EXPECT_EQ(1, GetInternalTouchPointsCount());
588
589   // Disabling projection touch HUD shoud remove it without crashing.
590   DisableTouchHudProjection();
591   EXPECT_EQ(NULL, GetInternalTouchHudProjection());
592 }
593
594 }  // namespace ash