touch_observer_hud_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/shell.h"
11#include "ash/test/ash_test_base.h"
12#include "ash/test/display_manager_test_api.h"
13#include "ash/touch/touch_hud_debug.h"
14#include "ash/wm/property_util.h"
15#include "base/command_line.h"
16#include "base/format_macros.h"
17#include "base/strings/stringprintf.h"
18#include "ui/aura/window.h"
19
20namespace ash {
21namespace internal {
22
23class TouchHudTest : public test::AshTestBase {
24 public:
25  TouchHudTest() {}
26  virtual ~TouchHudTest() {}
27
28  virtual void SetUp() OVERRIDE {
29    // Add ash-touch-hud flag to enable touch HUD. This flag should be set
30    // before Ash environment is set up, i.e., before
31    // test::AshTestBase::SetUp().
32    CommandLine::ForCurrentProcess()->AppendSwitch(
33        ash::switches::kAshTouchHud);
34
35    test::AshTestBase::SetUp();
36
37    // Initialize display infos. They should be initialized after Ash
38    // environment is set up, i.e., after test::AshTestBase::SetUp().
39    internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()).
40        SetFirstDisplayAsInternalDisplay();
41    external_display_id_ = 10;
42    mirrored_display_id_ = 11;
43
44    internal_display_info_ =
45        CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
46    external_display_info_ =
47        CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
48    mirrored_display_info_ =
49        CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
50  }
51
52  const gfx::Display& GetPrimaryDisplay() {
53    return GetDisplayController()->GetPrimaryDisplay();
54  }
55
56  const gfx::Display& GetSecondaryDisplay() {
57    return *GetDisplayController()->GetSecondaryDisplay();
58  }
59
60  void SetupSingleDisplay() {
61    display_info_list_.clear();
62    display_info_list_.push_back(internal_display_info_);
63    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
64  }
65
66  void SetupDualDisplays() {
67    display_info_list_.clear();
68    display_info_list_.push_back(internal_display_info_);
69    display_info_list_.push_back(external_display_info_);
70    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
71  }
72
73  void SetInternalAsPrimary() {
74    const gfx::Display& internal_display =
75        GetDisplayManager()->GetDisplayForId(internal_display_id_);
76    GetDisplayController()->SetPrimaryDisplay(internal_display);
77  }
78
79  void SetExternalAsPrimary() {
80    const gfx::Display& external_display =
81        GetDisplayManager()->GetDisplayForId(external_display_id_);
82    GetDisplayController()->SetPrimaryDisplay(external_display);
83  }
84
85  void MirrorDisplays() {
86    DCHECK_EQ(2U, display_info_list_.size());
87    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
88    DCHECK_EQ(external_display_id_, display_info_list_[1].id());
89    display_info_list_[1] = mirrored_display_info_;
90    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
91  }
92
93  void UnmirrorDisplays() {
94    DCHECK_EQ(2U, display_info_list_.size());
95    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
96    DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
97    display_info_list_[1] = external_display_info_;
98    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
99  }
100
101  void RemoveInternalDisplay() {
102    DCHECK_LT(0U, display_info_list_.size());
103    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
104    display_info_list_.erase(display_info_list_.begin());
105    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
106  }
107
108  void RemoveExternalDisplay() {
109    DCHECK_EQ(2U, display_info_list_.size());
110    display_info_list_.pop_back();
111    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
112  }
113
114  void AddInternalDisplay() {
115    DCHECK_EQ(0U, display_info_list_.size());
116    display_info_list_.push_back(internal_display_info_);
117    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
118  }
119
120  void AddExternalDisplay() {
121    DCHECK_EQ(1U, display_info_list_.size());
122    display_info_list_.push_back(external_display_info_);
123    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
124  }
125
126  int64 internal_display_id() const {
127    return internal_display_id_;
128  }
129
130  int64 external_display_id() const {
131    return external_display_id_;
132  }
133
134  void CheckInternalDisplay() {
135    EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
136              GetInternalTouchHud());
137    EXPECT_EQ(internal_display_id(), GetInternalTouchHud()->display_id_);
138    EXPECT_EQ(GetInternalRootWindow(), GetInternalTouchHud()->root_window_);
139    EXPECT_EQ(GetInternalRootWindow(),
140              GetInternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
141    EXPECT_EQ(GetInternalDisplay().size(),
142              GetInternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
143  }
144
145  void CheckExternalDisplay() {
146    EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
147              GetExternalTouchHud());
148    EXPECT_EQ(external_display_id(), GetExternalTouchHud()->display_id_);
149    EXPECT_EQ(GetExternalRootWindow(), GetExternalTouchHud()->root_window_);
150    EXPECT_EQ(GetExternalRootWindow(),
151              GetExternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
152    EXPECT_EQ(GetExternalDisplay().size(),
153              GetExternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
154  }
155
156 private:
157  DisplayManager* GetDisplayManager() {
158    return Shell::GetInstance()->display_manager();
159  }
160
161  DisplayController* GetDisplayController() {
162    return Shell::GetInstance()->display_controller();
163  }
164
165  const gfx::Display& GetInternalDisplay() {
166    return GetDisplayManager()->GetDisplayForId(internal_display_id_);
167  }
168
169  const gfx::Display& GetExternalDisplay() {
170    return GetDisplayManager()->GetDisplayForId(external_display_id_);
171  }
172
173  aura::RootWindow* GetInternalRootWindow() {
174    return GetDisplayController()->GetRootWindowForDisplayId(
175        internal_display_id_);
176  }
177
178  aura::RootWindow* GetExternalRootWindow() {
179    return GetDisplayController()->GetRootWindowForDisplayId(
180        external_display_id_);
181  }
182
183  aura::RootWindow* GetPrimaryRootWindow() {
184    const gfx::Display& display = GetPrimaryDisplay();
185    return GetDisplayController()->GetRootWindowForDisplayId(display.id());
186  }
187
188  aura::RootWindow* GetSecondaryRootWindow() {
189    const gfx::Display& display = GetSecondaryDisplay();
190    return GetDisplayController()->GetRootWindowForDisplayId(display.id());
191  }
192
193  internal::RootWindowController* GetInternalRootController() {
194    aura::RootWindow* root = GetInternalRootWindow();
195    return GetRootWindowController(root);
196  }
197
198  internal::RootWindowController* GetExternalRootController() {
199    aura::RootWindow* root = GetExternalRootWindow();
200    return GetRootWindowController(root);
201  }
202
203  internal::RootWindowController* GetPrimaryRootController() {
204    aura::RootWindow* root = GetPrimaryRootWindow();
205    return GetRootWindowController(root);
206  }
207
208  internal::RootWindowController* GetSecondaryRootController() {
209    aura::RootWindow* root = GetSecondaryRootWindow();
210    return GetRootWindowController(root);
211  }
212
213  internal::TouchObserverHUD* GetInternalTouchHud() {
214    return GetInternalRootController()->touch_hud_debug();
215  }
216
217  internal::TouchObserverHUD* GetExternalTouchHud() {
218    return GetExternalRootController()->touch_hud_debug();
219  }
220
221  internal::TouchObserverHUD* GetPrimaryTouchHud() {
222    return GetPrimaryRootController()->touch_hud_debug();
223  }
224
225  internal::TouchObserverHUD* GetSecondaryTouchHud() {
226    return GetSecondaryRootController()->touch_hud_debug();
227  }
228
229  DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
230    DisplayInfo info(id, base::StringPrintf("x-%"PRId64, id), false);
231    info.SetBounds(bounds);
232    return info;
233  }
234
235  int64 internal_display_id_;
236  int64 external_display_id_;
237  int64 mirrored_display_id_;
238  DisplayInfo internal_display_info_;
239  DisplayInfo external_display_info_;
240  DisplayInfo mirrored_display_info_;
241
242  std::vector<DisplayInfo> display_info_list_;
243
244  DISALLOW_COPY_AND_ASSIGN(TouchHudTest);
245};
246
247// Checks if touch HUDs are correctly initialized for displays.
248TEST_F(TouchHudTest, Basic) {
249  if (!SupportsMultipleDisplays())
250    return;
251
252  // Setup a dual display setting.
253  SetupDualDisplays();
254
255  // Check if touch HUDs are set correctly and associated with appropriate
256  // displays.
257  CheckInternalDisplay();
258  CheckExternalDisplay();
259}
260
261// Checks if touch HUDs are correctly handled when primary display is changed.
262TEST_F(TouchHudTest, SwapPrimaryDisplay) {
263  if (!SupportsMultipleDisplays())
264    return;
265
266  // Setup a dual display setting.
267  SetupDualDisplays();
268
269  // Set the primary display to the external one.
270  SetExternalAsPrimary();
271
272  // Check if displays' touch HUDs are not swapped as root windows are.
273  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
274  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
275  CheckInternalDisplay();
276  CheckExternalDisplay();
277
278  // Set the primary display back to the internal one.
279  SetInternalAsPrimary();
280
281  // Check if displays' touch HUDs are not swapped back as root windows are.
282  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
283  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
284  CheckInternalDisplay();
285  CheckExternalDisplay();
286}
287
288// Checks if touch HUDs are correctly handled when displays are mirrored.
289TEST_F(TouchHudTest, MirrorDisplays) {
290  if (!SupportsMultipleDisplays())
291    return;
292
293  // Setup a dual display setting.
294  SetupDualDisplays();
295
296  // Mirror displays.
297  MirrorDisplays();
298
299  // Check if the internal display is intact.
300  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
301  CheckInternalDisplay();
302
303  // Unmirror displays.
304  UnmirrorDisplays();
305
306  // Check if external display is added back correctly.
307  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
308  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
309  CheckInternalDisplay();
310  CheckExternalDisplay();
311}
312
313// Checks if touch HUDs are correctly handled when displays are mirrored after
314// setting the external display as the primary one.
315TEST_F(TouchHudTest, SwapPrimaryThenMirrorDisplays) {
316  if (!SupportsMultipleDisplays())
317    return;
318
319  // Setup a dual display setting.
320  SetupDualDisplays();
321
322  // Set the primary display to the external one.
323  SetExternalAsPrimary();
324
325  // Mirror displays.
326  MirrorDisplays();
327
328  // Check if the internal display is set as the primary one.
329  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
330  CheckInternalDisplay();
331
332  // Unmirror displays.
333  UnmirrorDisplays();
334
335  // Check if the external display is added back as the primary display and
336  // touch HUDs are set correctly.
337  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
338  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
339  CheckInternalDisplay();
340  CheckExternalDisplay();
341}
342
343// Checks if touch HUDs are correctly handled when the external display, which
344// is the secondary one, is removed.
345TEST_F(TouchHudTest, RemoveSecondaryDisplay) {
346  if (!SupportsMultipleDisplays())
347    return;
348
349  // Setup a dual display setting.
350  SetupDualDisplays();
351
352  // Remove external display which is the secondary one.
353  RemoveExternalDisplay();
354
355  // Check if the internal display is intact.
356  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
357  CheckInternalDisplay();
358
359  // Add external display back.
360  AddExternalDisplay();
361
362  // Check if displays' touch HUDs are set correctly.
363  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
364  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
365  CheckInternalDisplay();
366  CheckExternalDisplay();
367}
368
369// Checks if touch HUDs are correctly handled when the external display, which
370// is set as the primary display, is removed.
371TEST_F(TouchHudTest, RemovePrimaryDisplay) {
372  if (!SupportsMultipleDisplays())
373    return;
374
375  // Setup a dual display setting.
376  SetupDualDisplays();
377
378  // Set the primary display to the external one.
379  SetExternalAsPrimary();
380
381  // Remove the external display which is the primary display.
382  RemoveExternalDisplay();
383
384  // Check if the internal display is set as the primary one.
385  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
386  CheckInternalDisplay();
387
388  // Add the external display back.
389  AddExternalDisplay();
390
391  // Check if the external display is set as primary and touch HUDs are set
392  // correctly.
393  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
394  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
395  CheckInternalDisplay();
396  CheckExternalDisplay();
397}
398
399// Checks if touch HUDs are correctly handled when all displays are removed.
400TEST_F(TouchHudTest, Headless) {
401  if (!SupportsMultipleDisplays())
402    return;
403
404  // Setup a single display setting.
405  SetupSingleDisplay();
406
407  // Remove the only display which is the internal one.
408  RemoveInternalDisplay();
409
410  // Add the internal display back.
411  AddInternalDisplay();
412
413  // Check if the display's touch HUD is set correctly.
414  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
415  CheckInternalDisplay();
416}
417
418}  // namespace internal
419}  // namespace ash
420