display_manager_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/display/display_manager.h"
6
7#include "ash/display/display_controller.h"
8#include "ash/screen_ash.h"
9#include "ash/shell.h"
10#include "ash/test/ash_test_base.h"
11#include "ash/test/display_manager_test_api.h"
12#include "base/format_macros.h"
13#include "base/stringprintf.h"
14#include "ui/aura/env.h"
15#include "ui/aura/root_window.h"
16#include "ui/aura/window_observer.h"
17#include "ui/gfx/display_observer.h"
18#include "ui/gfx/display.h"
19
20namespace ash {
21namespace internal {
22
23using std::vector;
24using std::string;
25
26using base::StringPrintf;
27
28class DisplayManagerTest : public test::AshTestBase,
29                           public gfx::DisplayObserver,
30                           public aura::WindowObserver {
31 public:
32  DisplayManagerTest()
33      : removed_count_(0U),
34        root_window_destroyed_(false) {
35  }
36  virtual ~DisplayManagerTest() {}
37
38  virtual void SetUp() OVERRIDE {
39    AshTestBase::SetUp();
40    Shell::GetScreen()->AddObserver(this);
41    Shell::GetPrimaryRootWindow()->AddObserver(this);
42  }
43  virtual void TearDown() OVERRIDE {
44    Shell::GetPrimaryRootWindow()->RemoveObserver(this);
45    Shell::GetScreen()->RemoveObserver(this);
46    AshTestBase::TearDown();
47  }
48
49  DisplayManager* display_manager() {
50    return Shell::GetInstance()->display_manager();
51  }
52  const vector<gfx::Display>& changed() const { return changed_; }
53  const vector<gfx::Display>& added() const { return added_; }
54
55  string GetCountSummary() const {
56    return StringPrintf("%"PRIuS" %"PRIuS" %"PRIuS,
57                        changed_.size(), added_.size(), removed_count_);
58  }
59
60  void reset() {
61    changed_.clear();
62    added_.clear();
63    removed_count_ = 0U;
64    root_window_destroyed_ = false;
65  }
66
67  bool root_window_destroyed() const {
68    return root_window_destroyed_;
69  }
70
71  const DisplayInfo& GetDisplayInfo(const gfx::Display& display) {
72    return display_manager()->GetDisplayInfo(display.id());
73  }
74
75  const DisplayInfo& GetDisplayInfoAt(int index) {
76    return GetDisplayInfo(*display_manager()->GetDisplayAt(index));
77  }
78
79  const gfx::Display& FindDisplayForId(int64 id) {
80    return display_manager()->FindDisplayForId(id);
81  }
82
83  const DisplayInfo& FindDisplayInfoForId(int64 id) {
84    return GetDisplayInfo(display_manager()->FindDisplayForId(id));
85  }
86
87  // aura::DisplayObserver overrides:
88  virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
89    changed_.push_back(display);
90  }
91  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
92    added_.push_back(new_display);
93  }
94  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
95    ++removed_count_;
96  }
97
98  // aura::WindowObserver overrides:
99  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
100    ASSERT_EQ(Shell::GetPrimaryRootWindow(), window);
101    root_window_destroyed_ = true;
102  }
103
104 private:
105  vector<gfx::Display> changed_;
106  vector<gfx::Display> added_;
107  size_t removed_count_;
108  bool root_window_destroyed_;
109
110  DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest);
111};
112
113TEST_F(DisplayManagerTest, NativeDisplayTest) {
114  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
115
116  // Update primary and add seconary.
117  UpdateDisplay("100+0-500x500,0+501-400x400");
118  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
119  EXPECT_EQ("0,0 500x500",
120            display_manager()->GetDisplayAt(0)->bounds().ToString());
121
122  EXPECT_EQ("1 1 0", GetCountSummary());
123  EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id());
124  EXPECT_EQ(display_manager()->GetDisplayAt(1)->id(), added()[0].id());
125  EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString());
126  // Secondary display is on right.
127  EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString());
128  EXPECT_EQ("0,501 400x400",
129            GetDisplayInfo(added()[0]).bounds_in_pixel().ToString());
130  reset();
131
132  // Delete secondary.
133  UpdateDisplay("100+0-500x500");
134  EXPECT_EQ("0 0 1", GetCountSummary());
135  reset();
136
137  // Change primary.
138  UpdateDisplay("1+1-1000x600");
139  EXPECT_EQ("1 0 0", GetCountSummary());
140  EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id());
141  EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString());
142  reset();
143
144  // Add secondary.
145  UpdateDisplay("1+1-1000x600,1002+0-600x400");
146  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
147  EXPECT_EQ("0 1 0", GetCountSummary());
148  EXPECT_EQ(display_manager()->GetDisplayAt(1)->id(), added()[0].id());
149  // Secondary display is on right.
150  EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString());
151  EXPECT_EQ("1002,0 600x400",
152            GetDisplayInfo(added()[0]).bounds_in_pixel().ToString());
153  reset();
154
155  // Secondary removed, primary changed.
156  UpdateDisplay("1+1-800x300");
157  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
158  EXPECT_EQ("1 0 1", GetCountSummary());
159  EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id());
160  EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString());
161  reset();
162
163  // # of display can go to zero when screen is off.
164  const vector<DisplayInfo> empty;
165  display_manager()->OnNativeDisplaysChanged(empty);
166  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
167  EXPECT_EQ("0 0 0", GetCountSummary());
168  EXPECT_FALSE(root_window_destroyed());
169  // Display configuration stays the same
170  EXPECT_EQ("0,0 800x300",
171            display_manager()->GetDisplayAt(0)->bounds().ToString());
172  reset();
173
174  // Connect to display again
175  UpdateDisplay("100+100-500x400");
176  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
177  EXPECT_EQ("1 0 0", GetCountSummary());
178  EXPECT_FALSE(root_window_destroyed());
179  EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString());
180  EXPECT_EQ("100,100 500x400",
181            GetDisplayInfo(changed()[0]).bounds_in_pixel().ToString());
182  reset();
183
184  // Go back to zero and wake up with multiple displays.
185  display_manager()->OnNativeDisplaysChanged(empty);
186  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
187  EXPECT_FALSE(root_window_destroyed());
188  reset();
189
190  // Add secondary.
191  UpdateDisplay("0+0-1000x600,1000+1000-600x400");
192  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
193  EXPECT_EQ("0,0 1000x600",
194            display_manager()->GetDisplayAt(0)->bounds().ToString());
195  // Secondary display is on right.
196  EXPECT_EQ("1000,0 600x400",
197            display_manager()->GetDisplayAt(1)->bounds().ToString());
198  EXPECT_EQ("1000,1000 600x400",
199            GetDisplayInfoAt(1).bounds_in_pixel().ToString());
200  reset();
201}
202
203// Test in emulation mode (use_fullscreen_host_window=false)
204TEST_F(DisplayManagerTest, EmulatorTest) {
205  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
206
207  DisplayManager::CycleDisplay();
208  // Update primary and add seconary.
209  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
210  EXPECT_EQ("0 1 0", GetCountSummary());
211  reset();
212
213  DisplayManager::CycleDisplay();
214  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
215  EXPECT_EQ("0 0 1", GetCountSummary());
216  reset();
217
218  DisplayManager::CycleDisplay();
219  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
220  EXPECT_EQ("0 1 0", GetCountSummary());
221  reset();
222}
223
224TEST_F(DisplayManagerTest, OverscanInsetsTest) {
225  UpdateDisplay("0+0-500x500,0+501-400x400");
226  reset();
227  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
228  const DisplayInfo& display_info1 = GetDisplayInfoAt(0);
229  const DisplayInfo& display_info2 = GetDisplayInfoAt(1);
230  display_manager()->SetOverscanInsets(
231      display_info2.id(), gfx::Insets(13, 12, 11, 10));
232
233  std::vector<gfx::Display> changed_displays = changed();
234  EXPECT_EQ(1u, changed_displays.size());
235  EXPECT_EQ(display_info2.id(), changed_displays[0].id());
236  EXPECT_EQ("0,0 500x500",
237            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
238  DisplayInfo updated_display_info2 = GetDisplayInfoAt(1);
239  EXPECT_EQ("0,501 400x400",
240            updated_display_info2.bounds_in_pixel().ToString());
241  EXPECT_EQ("378x376",
242            updated_display_info2.size_in_pixel().ToString());
243  EXPECT_EQ("13,12,11,10",
244            updated_display_info2.overscan_insets_in_dip().ToString());
245  EXPECT_EQ("500,0 378x376",
246            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
247
248  // Make sure that SetOverscanInsets() is idempotent.
249  display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets());
250  display_manager()->SetOverscanInsets(
251      display_info2.id(), gfx::Insets(13, 12, 11, 10));
252  EXPECT_EQ("0,0 500x500",
253            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
254  updated_display_info2 = GetDisplayInfoAt(1);
255  EXPECT_EQ("0,501 400x400",
256            updated_display_info2.bounds_in_pixel().ToString());
257  EXPECT_EQ("378x376",
258            updated_display_info2.size_in_pixel().ToString());
259  EXPECT_EQ("13,12,11,10",
260            updated_display_info2.overscan_insets_in_dip().ToString());
261
262  display_manager()->SetOverscanInsets(
263      display_info2.id(), gfx::Insets(10, 11, 12, 13));
264  EXPECT_EQ("0,0 500x500",
265            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
266  EXPECT_EQ("376x378",
267            GetDisplayInfoAt(1).size_in_pixel().ToString());
268  EXPECT_EQ("10,11,12,13",
269            GetDisplayInfoAt(1).overscan_insets_in_dip().ToString());
270
271  // Recreate a new 2nd display. It won't apply the overscan inset because the
272  // new display has a different ID.
273  UpdateDisplay("0+0-500x500");
274  UpdateDisplay("0+0-500x500,0+501-400x400");
275  EXPECT_EQ("0,0 500x500",
276            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
277  EXPECT_EQ("0,501 400x400",
278            GetDisplayInfoAt(1).bounds_in_pixel().ToString());
279
280  // Recreate the displays with the same ID.  It should apply the overscan
281  // inset.
282  UpdateDisplay("0+0-500x500");
283  std::vector<DisplayInfo> display_info_list;
284  display_info_list.push_back(display_info1);
285  display_info_list.push_back(display_info2);
286  display_manager()->OnNativeDisplaysChanged(display_info_list);
287  EXPECT_EQ("1,1 500x500",
288            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
289  updated_display_info2 = GetDisplayInfoAt(1);
290  EXPECT_EQ("376x378",
291            updated_display_info2.size_in_pixel().ToString());
292  EXPECT_EQ("10,11,12,13",
293            updated_display_info2.overscan_insets_in_dip().ToString());
294
295  // HiDPI but overscan display. The specified insets size should be doubled.
296  UpdateDisplay("0+0-500x500,0+501-400x400*2");
297  display_manager()->SetOverscanInsets(
298      display_manager()->GetDisplayAt(1)->id(), gfx::Insets(4, 5, 6, 7));
299  EXPECT_EQ("0,0 500x500",
300            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
301  updated_display_info2 = GetDisplayInfoAt(1);
302  EXPECT_EQ("0,501 400x400",
303            updated_display_info2.bounds_in_pixel().ToString());
304  EXPECT_EQ("376x380",
305            updated_display_info2.size_in_pixel().ToString());
306  EXPECT_EQ("4,5,6,7",
307            updated_display_info2.overscan_insets_in_dip().ToString());
308  EXPECT_EQ("8,10,12,14",
309            updated_display_info2.GetOverscanInsetsInPixel().ToString());
310
311  // Make sure switching primary display applies the overscan offset only once.
312  ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
313      ScreenAsh::GetSecondaryDisplay());
314  EXPECT_EQ("-500,0 500x500",
315            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
316  EXPECT_EQ("0,0 500x500",
317            GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()).
318            bounds_in_pixel().ToString());
319  EXPECT_EQ("0,501 400x400",
320            GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()).
321            bounds_in_pixel().ToString());
322  EXPECT_EQ("0,0 188x190",
323            Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
324}
325
326TEST_F(DisplayManagerTest, ZeroOverscanInsets) {
327  // Make sure the display change events is emitted for overscan inset changes.
328  UpdateDisplay("0+0-500x500,0+501-400x400");
329  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
330  int64 display2_id = display_manager()->GetDisplayAt(1)->id();
331
332  reset();
333  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
334  EXPECT_EQ(0u, changed().size());
335
336  reset();
337  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0));
338  EXPECT_EQ(1u, changed().size());
339  EXPECT_EQ(display2_id, changed()[0].id());
340
341  reset();
342  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
343  EXPECT_EQ(1u, changed().size());
344  EXPECT_EQ(display2_id, changed()[0].id());
345}
346
347TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
348  UpdateDisplay("1000x600");
349  EXPECT_EQ(1,
350            Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor());
351  EXPECT_EQ("1000x600",
352            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
353  UpdateDisplay("1000x600*2");
354  EXPECT_EQ(2,
355            Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor());
356  EXPECT_EQ("500x300",
357            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
358}
359
360DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
361  DisplayInfo info(id, StringPrintf("x-%d", static_cast<int>(id)), false);
362  info.SetBounds(bounds);
363  return info;
364}
365
366TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) {
367  const int internal_display_id =
368      test::DisplayManagerTestApi(display_manager()).
369      SetFirstDisplayAsInternalDisplay();
370  const int64 invalid_id = gfx::Display::kInvalidDisplayID;
371  const DisplayInfo native_display_info =
372      CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
373  const DisplayInfo external_display_info =
374      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
375  const DisplayInfo mirrored_display_info =
376      CreateDisplayInfo(11, gfx::Rect(0, 0, 500, 500));
377
378  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
379  EXPECT_EQ(1U, display_manager()->num_connected_displays());
380  std::string default_bounds =
381      display_manager()->GetDisplayAt(0)->bounds().ToString();
382
383  std::vector<DisplayInfo> display_info_list;
384  // Primary disconnected.
385  display_manager()->OnNativeDisplaysChanged(display_info_list);
386  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
387  EXPECT_EQ(default_bounds,
388            display_manager()->GetDisplayAt(0)->bounds().ToString());
389  EXPECT_EQ(1U, display_manager()->num_connected_displays());
390  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
391
392  // External connected while primary was disconnected.
393  display_info_list.push_back(external_display_info);
394  display_manager()->OnNativeDisplaysChanged(display_info_list);
395  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
396
397  EXPECT_EQ(default_bounds,
398            FindDisplayForId(internal_display_id).bounds().ToString());
399  EXPECT_EQ("1,1 100x100",
400            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
401  EXPECT_EQ(2U, display_manager()->num_connected_displays());
402  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
403
404  // Primary connected, with different bounds.
405  display_info_list.clear();
406  display_info_list.push_back(native_display_info);
407  display_info_list.push_back(external_display_info);
408  display_manager()->OnNativeDisplaysChanged(display_info_list);
409  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
410  EXPECT_EQ("0,0 500x500",
411            FindDisplayForId(internal_display_id).bounds().ToString());
412  EXPECT_EQ("1,1 100x100",
413            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
414  EXPECT_EQ(2U, display_manager()->num_connected_displays());
415  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
416  EXPECT_EQ(StringPrintf("x-%d", internal_display_id),
417            display_manager()->GetDisplayNameForId(internal_display_id));
418
419  // Turn off primary.
420  display_info_list.clear();
421  display_info_list.push_back(external_display_info);
422  display_manager()->OnNativeDisplaysChanged(display_info_list);
423  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
424  EXPECT_EQ("0,0 500x500",
425            FindDisplayForId(internal_display_id).bounds().ToString());
426  EXPECT_EQ("1,1 100x100",
427            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
428  EXPECT_EQ(2U, display_manager()->num_connected_displays());
429  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
430
431  // Emulate suspend.
432  display_info_list.clear();
433  display_manager()->OnNativeDisplaysChanged(display_info_list);
434  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
435  EXPECT_EQ("0,0 500x500",
436            FindDisplayForId(internal_display_id).bounds().ToString());
437  EXPECT_EQ("1,1 100x100",
438            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
439  EXPECT_EQ(2U, display_manager()->num_connected_displays());
440  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
441  EXPECT_EQ(StringPrintf("x-%d", internal_display_id),
442            display_manager()->GetDisplayNameForId(internal_display_id));
443
444  // External display has disconnected then resumed.
445  display_info_list.push_back(native_display_info);
446  display_manager()->OnNativeDisplaysChanged(display_info_list);
447  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
448  EXPECT_EQ("0,0 500x500",
449            FindDisplayForId(internal_display_id).bounds().ToString());
450  EXPECT_EQ(1U, display_manager()->num_connected_displays());
451  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
452
453  // External display was changed during suspend.
454  display_info_list.push_back(external_display_info);
455  display_manager()->OnNativeDisplaysChanged(display_info_list);
456  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
457  EXPECT_EQ(2U, display_manager()->num_connected_displays());
458  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
459
460  // suspend...
461  display_info_list.clear();
462  display_manager()->OnNativeDisplaysChanged(display_info_list);
463  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
464  EXPECT_EQ(2U, display_manager()->num_connected_displays());
465  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
466
467  // and resume with different external display.
468  display_info_list.push_back(native_display_info);
469  display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100)));
470  display_manager()->OnNativeDisplaysChanged(display_info_list);
471  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
472  EXPECT_EQ(2U, display_manager()->num_connected_displays());
473  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
474  EXPECT_FALSE(display_manager()->IsMirrored());
475
476  // mirrored...
477  display_info_list.clear();
478  display_info_list.push_back(native_display_info);
479  display_info_list.push_back(mirrored_display_info);
480  display_manager()->OnNativeDisplaysChanged(display_info_list);
481  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
482  EXPECT_EQ("0,0 500x500",
483            FindDisplayForId(internal_display_id).bounds().ToString());
484  EXPECT_EQ(2U, display_manager()->num_connected_displays());
485  EXPECT_EQ(11U, display_manager()->mirrored_display_id());
486  EXPECT_TRUE(display_manager()->IsMirrored());
487
488  // Test display name.
489  EXPECT_EQ(StringPrintf("x-%d", internal_display_id),
490            display_manager()->GetDisplayNameForId(internal_display_id));
491  EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10));
492  EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11));
493  EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12));
494  // Default name for the id that doesn't exist.
495  EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100));
496
497  // and exit mirroring.
498  display_info_list.clear();
499  display_info_list.push_back(native_display_info);
500  display_info_list.push_back(external_display_info);
501  display_manager()->OnNativeDisplaysChanged(display_info_list);
502  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
503  EXPECT_EQ(2U, display_manager()->num_connected_displays());
504  EXPECT_FALSE(display_manager()->IsMirrored());
505  EXPECT_EQ("0,0 500x500",
506            FindDisplayForId(internal_display_id).bounds().ToString());
507  EXPECT_EQ("500,0 100x100",
508            FindDisplayForId(10).bounds().ToString());
509}
510
511#if defined(OS_WIN)
512// This test currently fails on Win8/Metro as it picks up the actual
513// display size. http://crbug.com/154081
514#define MAYBE_TestNativeDisplaysChangedNoInternal \
515        DISABLED_TestNativeDisplaysChangedNoInternal
516#else
517#define MAYBE_TestNativeDisplaysChangedNoInternal \
518        TestNativeDisplaysChangedNoInternal
519#endif
520
521TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) {
522  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
523
524  // Don't change the display info if all displays are disconnected.
525  std::vector<DisplayInfo> display_info_list;
526  display_manager()->OnNativeDisplaysChanged(display_info_list);
527  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
528
529  // Connect another display which will become primary.
530  const DisplayInfo external_display_info =
531      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
532  display_info_list.push_back(external_display_info);
533  display_manager()->OnNativeDisplaysChanged(display_info_list);
534  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
535  EXPECT_EQ("1,1 100x100",
536            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
537  EXPECT_EQ("100x100",
538            ash::Shell::GetPrimaryRootWindow()->GetHostSize().ToString());
539}
540
541TEST_F(DisplayManagerTest, EnsurePointerInDisplays) {
542  UpdateDisplay("200x200,300x300");
543  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
544
545  aura::Env* env = aura::Env::GetInstance();
546
547  // Set the initial position.
548  root_windows[0]->MoveCursorTo(gfx::Point(350, 150));
549  EXPECT_EQ("350,150", env->last_mouse_location().ToString());
550
551  // A mouse pointer will be inside 2nd display.
552  UpdateDisplay("300x300,200x200");
553  EXPECT_EQ("350,150", env->last_mouse_location().ToString());
554
555  // A mouse pointer will be outside of displays and move to the
556  // center of 2nd display.
557  UpdateDisplay("300x300,100x100");
558  EXPECT_EQ("350,50", env->last_mouse_location().ToString());
559
560  // 2nd display was disconnected, but the mouse pointer says in the
561  // 1st display.
562  UpdateDisplay("400x400");
563  EXPECT_EQ("350,50", env->last_mouse_location().ToString());
564
565  // 1st display's resolution has changed, and the mouse pointer is
566  // now outside. Move the mouse pointer to the center of 1st display.
567  UpdateDisplay("300x300");
568  EXPECT_EQ("150,150", env->last_mouse_location().ToString());
569
570  // Move the mouse pointer to the bottom of 1st display.
571  root_windows[0]->MoveCursorTo(gfx::Point(150, 290));
572  EXPECT_EQ("150,290", env->last_mouse_location().ToString());
573
574  // The mouse pointer is outside and closest display is 1st one.
575  UpdateDisplay("300x280,200x200");
576  EXPECT_EQ("150,140", env->last_mouse_location().ToString());
577}
578
579TEST_F(DisplayManagerTest, EnsurePointerInDisplays_2ndOnLeft) {
580  UpdateDisplay("200x200,300x300");
581  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
582
583  // Set the 2nd display on the left.
584  DisplayController* display_controller =
585      Shell::GetInstance()->display_controller();
586  DisplayLayout layout = display_controller->default_display_layout();
587  layout.position = DisplayLayout::LEFT;
588  display_controller->SetDefaultDisplayLayout(layout);
589
590  EXPECT_EQ("-300,0 300x300",
591            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
592
593  aura::Env* env = aura::Env::GetInstance();
594
595  // Set the initial position.
596  root_windows[0]->MoveCursorTo(gfx::Point(-150, 150));
597  EXPECT_EQ("-150,150", env->last_mouse_location().ToString());
598
599  // A mouse pointer will be in 2nd display.
600  UpdateDisplay("300x300,200x200");
601  EXPECT_EQ("-150,150", env->last_mouse_location().ToString());
602
603  // A mouse pointer will be outside of displays and move to the
604  // center of 2nd display.
605  UpdateDisplay("300x300,200x100");
606  EXPECT_EQ("-100,50", env->last_mouse_location().ToString());
607
608  // 2nd display was disconnected. Mouse pointer should move to
609  // 1st display.
610  UpdateDisplay("300x300");
611  EXPECT_EQ("150,150", env->last_mouse_location().ToString());
612}
613
614TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
615  const int64 internal_display_id =
616      test::DisplayManagerTestApi(display_manager()).
617      SetFirstDisplayAsInternalDisplay();
618  const DisplayInfo native_display_info =
619      CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
620  const DisplayInfo secondary_display_info =
621      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
622
623  std::vector<DisplayInfo> display_info_list;
624  display_info_list.push_back(native_display_info);
625  display_info_list.push_back(secondary_display_info);
626  display_manager()->OnNativeDisplaysChanged(display_info_list);
627  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
628  EXPECT_EQ("0,0 500x500",
629            FindDisplayForId(internal_display_id).bounds().ToString());
630  EXPECT_EQ("500,0 100x100", FindDisplayForId(10).bounds().ToString());
631
632  ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
633      FindDisplayForId(secondary_display_info.id()));
634  EXPECT_EQ("-500,0 500x500",
635            FindDisplayForId(internal_display_id).bounds().ToString());
636  EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString());
637
638  // OnNativeDisplaysChanged may change the display bounds.  Here makes sure
639  // nothing changed if the exactly same displays are specified.
640  display_manager()->OnNativeDisplaysChanged(display_info_list);
641  EXPECT_EQ("-500,0 500x500",
642            FindDisplayForId(internal_display_id).bounds().ToString());
643  EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString());
644}
645
646TEST_F(DisplayManagerTest, AutomaticOverscanInsets) {
647  UpdateDisplay("200x200,400x400");
648
649  std::vector<DisplayInfo> display_info_list;
650  display_info_list.push_back(GetDisplayInfoAt(0));
651  display_info_list.push_back(GetDisplayInfoAt(1));
652  display_info_list[1].set_has_overscan_for_test(true);
653  int64 id = display_info_list[1].id();
654  // SetDefaultOverscanInsets(&display_info_list[1]);
655  display_manager()->OnNativeDisplaysChanged(display_info_list);
656  // It has overscan insets, although SetOverscanInsets() isn't called.
657  EXPECT_EQ("380x380",
658            GetDisplayInfoAt(1).size_in_pixel().ToString());
659
660  // If custom overscan insets is specified, the specified value is used.
661  display_manager()->SetOverscanInsets(id, gfx::Insets(5, 6, 7, 8));
662  display_manager()->OnNativeDisplaysChanged(display_info_list);
663  EXPECT_EQ("386x388",
664            GetDisplayInfoAt(1).size_in_pixel().ToString());
665
666  // Do not overscan even though it has 'has_overscan' flag, if the custom
667  // insets is empty.
668  display_manager()->SetOverscanInsets(id, gfx::Insets());
669  display_manager()->OnNativeDisplaysChanged(display_info_list);
670  EXPECT_EQ("400x400",
671            GetDisplayInfoAt(1).size_in_pixel().ToString());
672
673  // Clearing the custom overscan should set the bounds to
674  // original.
675  display_manager()->ClearCustomOverscanInsets(id);
676  EXPECT_EQ("380x380",
677            GetDisplayInfoAt(1).size_in_pixel().ToString());
678}
679
680TEST_F(DisplayManagerTest, Rotate) {
681  UpdateDisplay("100x200/r,300x400/l");
682  EXPECT_EQ("1,1 100x200",
683            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
684  EXPECT_EQ("200x100",
685            GetDisplayInfoAt(0).size_in_pixel().ToString());
686
687  EXPECT_EQ("1,201 300x400",
688            GetDisplayInfoAt(1).bounds_in_pixel().ToString());
689  EXPECT_EQ("400x300",
690            GetDisplayInfoAt(1).size_in_pixel().ToString());
691  UpdateDisplay("100x200/b,300x400");
692  EXPECT_EQ("1,1 100x200",
693            GetDisplayInfoAt(0).bounds_in_pixel().ToString());
694  EXPECT_EQ("100x200",
695            GetDisplayInfoAt(0).size_in_pixel().ToString());
696
697  EXPECT_EQ("1,201 300x400",
698            GetDisplayInfoAt(1).bounds_in_pixel().ToString());
699  EXPECT_EQ("300x400",
700            GetDisplayInfoAt(1).size_in_pixel().ToString());
701}
702
703}  // namespace internal
704}  // namespace ash
705