display_manager_unittest.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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/display/display_layout_store.h"
9#include "ash/screen_ash.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/test/mirror_window_test_api.h"
14#include "base/format_macros.h"
15#include "base/strings/string_number_conversions.h"
16#include "base/strings/stringprintf.h"
17#include "ui/aura/env.h"
18#include "ui/aura/root_window.h"
19#include "ui/aura/test/event_generator.h"
20#include "ui/aura/window_observer.h"
21#include "ui/gfx/display_observer.h"
22#include "ui/gfx/display.h"
23
24namespace ash {
25namespace internal {
26
27using std::vector;
28using std::string;
29
30using base::StringPrintf;
31
32namespace {
33
34std::string ToDisplayName(int64 id) {
35  return "x-" + base::Int64ToString(id);
36}
37
38}  // namespace
39
40class DisplayManagerTest : public test::AshTestBase,
41                           public gfx::DisplayObserver,
42                           public aura::WindowObserver {
43 public:
44  DisplayManagerTest()
45      : removed_count_(0U),
46        root_window_destroyed_(false) {
47  }
48  virtual ~DisplayManagerTest() {}
49
50  virtual void SetUp() OVERRIDE {
51    AshTestBase::SetUp();
52    Shell::GetScreen()->AddObserver(this);
53    Shell::GetPrimaryRootWindow()->AddObserver(this);
54  }
55  virtual void TearDown() OVERRIDE {
56    Shell::GetPrimaryRootWindow()->RemoveObserver(this);
57    Shell::GetScreen()->RemoveObserver(this);
58    AshTestBase::TearDown();
59  }
60
61  DisplayManager* display_manager() {
62    return Shell::GetInstance()->display_manager();
63  }
64  const vector<gfx::Display>& changed() const { return changed_; }
65  const vector<gfx::Display>& added() const { return added_; }
66
67  string GetCountSummary() const {
68    return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS,
69                        changed_.size(), added_.size(), removed_count_);
70  }
71
72  void reset() {
73    changed_.clear();
74    added_.clear();
75    removed_count_ = 0U;
76    root_window_destroyed_ = false;
77  }
78
79  bool root_window_destroyed() const {
80    return root_window_destroyed_;
81  }
82
83  const DisplayInfo& GetDisplayInfo(const gfx::Display& display) {
84    return display_manager()->GetDisplayInfo(display.id());
85  }
86
87  const DisplayInfo& GetDisplayInfoAt(int index) {
88    return GetDisplayInfo(display_manager()->GetDisplayAt(index));
89  }
90
91  const gfx::Display& GetDisplayForId(int64 id) {
92    return display_manager()->GetDisplayForId(id);
93  }
94
95  const DisplayInfo& GetDisplayInfoForId(int64 id) {
96    return GetDisplayInfo(display_manager()->GetDisplayForId(id));
97  }
98
99  const gfx::Display GetMirroredDisplay() {
100    return Shell::GetInstance()->display_manager()->mirrored_display();
101  }
102
103  // aura::DisplayObserver overrides:
104  virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
105    changed_.push_back(display);
106  }
107  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
108    added_.push_back(new_display);
109  }
110  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
111    ++removed_count_;
112  }
113
114  // aura::WindowObserver overrides:
115  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
116    ASSERT_EQ(Shell::GetPrimaryRootWindow(), window);
117    root_window_destroyed_ = true;
118  }
119
120 private:
121  vector<gfx::Display> changed_;
122  vector<gfx::Display> added_;
123  size_t removed_count_;
124  bool root_window_destroyed_;
125
126  DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest);
127};
128
129TEST_F(DisplayManagerTest, UpdateDisplayTest) {
130  if (!SupportsMultipleDisplays())
131    return;
132
133  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
134
135  // Update primary and add seconary.
136  UpdateDisplay("100+0-500x500,0+501-400x400");
137  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
138  EXPECT_EQ("0,0 500x500",
139            display_manager()->GetDisplayAt(0).bounds().ToString());
140
141  EXPECT_EQ("1 1 0", GetCountSummary());
142  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
143  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
144  EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString());
145  // Secondary display is on right.
146  EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString());
147  EXPECT_EQ("0,501 400x400",
148            GetDisplayInfo(added()[0]).bounds_in_native().ToString());
149  reset();
150
151  // Delete secondary.
152  UpdateDisplay("100+0-500x500");
153  EXPECT_EQ("0 0 1", GetCountSummary());
154  reset();
155
156  // Change primary.
157  UpdateDisplay("1+1-1000x600");
158  EXPECT_EQ("1 0 0", GetCountSummary());
159  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
160  EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString());
161  reset();
162
163  // Add secondary.
164  UpdateDisplay("1+1-1000x600,1002+0-600x400");
165  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
166  EXPECT_EQ("0 1 0", GetCountSummary());
167  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
168  // Secondary display is on right.
169  EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString());
170  EXPECT_EQ("1002,0 600x400",
171            GetDisplayInfo(added()[0]).bounds_in_native().ToString());
172  reset();
173
174  // Secondary removed, primary changed.
175  UpdateDisplay("1+1-800x300");
176  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
177  EXPECT_EQ("1 0 1", GetCountSummary());
178  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
179  EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString());
180  reset();
181
182  // # of display can go to zero when screen is off.
183  const vector<DisplayInfo> empty;
184  display_manager()->OnNativeDisplaysChanged(empty);
185  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
186  EXPECT_EQ("0 0 0", GetCountSummary());
187  EXPECT_FALSE(root_window_destroyed());
188  // Display configuration stays the same
189  EXPECT_EQ("0,0 800x300",
190            display_manager()->GetDisplayAt(0).bounds().ToString());
191  reset();
192
193  // Connect to display again
194  UpdateDisplay("100+100-500x400");
195  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
196  EXPECT_EQ("1 0 0", GetCountSummary());
197  EXPECT_FALSE(root_window_destroyed());
198  EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString());
199  EXPECT_EQ("100,100 500x400",
200            GetDisplayInfo(changed()[0]).bounds_in_native().ToString());
201  reset();
202
203  // Go back to zero and wake up with multiple displays.
204  display_manager()->OnNativeDisplaysChanged(empty);
205  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
206  EXPECT_FALSE(root_window_destroyed());
207  reset();
208
209  // Add secondary.
210  UpdateDisplay("0+0-1000x600,1000+1000-600x400");
211  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
212  EXPECT_EQ("0,0 1000x600",
213            display_manager()->GetDisplayAt(0).bounds().ToString());
214  // Secondary display is on right.
215  EXPECT_EQ("1000,0 600x400",
216            display_manager()->GetDisplayAt(1).bounds().ToString());
217  EXPECT_EQ("1000,1000 600x400",
218            GetDisplayInfoAt(1).bounds_in_native().ToString());
219  reset();
220
221  // Changing primary will update secondary as well.
222  UpdateDisplay("0+0-800x600,1000+1000-600x400");
223  EXPECT_EQ("2 0 0", GetCountSummary());
224  reset();
225  EXPECT_EQ("0,0 800x600",
226            display_manager()->GetDisplayAt(0).bounds().ToString());
227  EXPECT_EQ("800,0 600x400",
228            display_manager()->GetDisplayAt(1).bounds().ToString());
229}
230
231// Test in emulation mode (use_fullscreen_host_window=false)
232TEST_F(DisplayManagerTest, EmulatorTest) {
233  if (!SupportsMultipleDisplays())
234    return;
235
236  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
237
238  display_manager()->AddRemoveDisplay();
239  // Update primary and add seconary.
240  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
241  EXPECT_EQ("0 1 0", GetCountSummary());
242  reset();
243
244  display_manager()->AddRemoveDisplay();
245  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
246  EXPECT_EQ("0 0 1", GetCountSummary());
247  reset();
248
249  display_manager()->AddRemoveDisplay();
250  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
251  EXPECT_EQ("0 1 0", GetCountSummary());
252  reset();
253}
254
255TEST_F(DisplayManagerTest, OverscanInsetsTest) {
256  if (!SupportsMultipleDisplays())
257    return;
258
259  UpdateDisplay("0+0-500x500,0+501-400x400");
260  reset();
261  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
262  const DisplayInfo& display_info1 = GetDisplayInfoAt(0);
263  const DisplayInfo& display_info2 = GetDisplayInfoAt(1);
264  display_manager()->SetOverscanInsets(
265      display_info2.id(), gfx::Insets(13, 12, 11, 10));
266
267  std::vector<gfx::Display> changed_displays = changed();
268  EXPECT_EQ(1u, changed_displays.size());
269  EXPECT_EQ(display_info2.id(), changed_displays[0].id());
270  EXPECT_EQ("0,0 500x500",
271            GetDisplayInfoAt(0).bounds_in_native().ToString());
272  DisplayInfo updated_display_info2 = GetDisplayInfoAt(1);
273  EXPECT_EQ("0,501 400x400",
274            updated_display_info2.bounds_in_native().ToString());
275  EXPECT_EQ("378x376",
276            updated_display_info2.size_in_pixel().ToString());
277  EXPECT_EQ("13,12,11,10",
278            updated_display_info2.overscan_insets_in_dip().ToString());
279  EXPECT_EQ("500,0 378x376",
280            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
281
282  // Make sure that SetOverscanInsets() is idempotent.
283  display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets());
284  display_manager()->SetOverscanInsets(
285      display_info2.id(), gfx::Insets(13, 12, 11, 10));
286  EXPECT_EQ("0,0 500x500",
287            GetDisplayInfoAt(0).bounds_in_native().ToString());
288  updated_display_info2 = GetDisplayInfoAt(1);
289  EXPECT_EQ("0,501 400x400",
290            updated_display_info2.bounds_in_native().ToString());
291  EXPECT_EQ("378x376",
292            updated_display_info2.size_in_pixel().ToString());
293  EXPECT_EQ("13,12,11,10",
294            updated_display_info2.overscan_insets_in_dip().ToString());
295
296  display_manager()->SetOverscanInsets(
297      display_info2.id(), gfx::Insets(10, 11, 12, 13));
298  EXPECT_EQ("0,0 500x500",
299            GetDisplayInfoAt(0).bounds_in_native().ToString());
300  EXPECT_EQ("376x378",
301            GetDisplayInfoAt(1).size_in_pixel().ToString());
302  EXPECT_EQ("10,11,12,13",
303            GetDisplayInfoAt(1).overscan_insets_in_dip().ToString());
304
305  // Recreate a new 2nd display. It won't apply the overscan inset because the
306  // new display has a different ID.
307  UpdateDisplay("0+0-500x500");
308  UpdateDisplay("0+0-500x500,0+501-400x400");
309  EXPECT_EQ("0,0 500x500",
310            GetDisplayInfoAt(0).bounds_in_native().ToString());
311  EXPECT_EQ("0,501 400x400",
312            GetDisplayInfoAt(1).bounds_in_native().ToString());
313
314  // Recreate the displays with the same ID.  It should apply the overscan
315  // inset.
316  UpdateDisplay("0+0-500x500");
317  std::vector<DisplayInfo> display_info_list;
318  display_info_list.push_back(display_info1);
319  display_info_list.push_back(display_info2);
320  display_manager()->OnNativeDisplaysChanged(display_info_list);
321  EXPECT_EQ("1,1 500x500",
322            GetDisplayInfoAt(0).bounds_in_native().ToString());
323  updated_display_info2 = GetDisplayInfoAt(1);
324  EXPECT_EQ("376x378",
325            updated_display_info2.size_in_pixel().ToString());
326  EXPECT_EQ("10,11,12,13",
327            updated_display_info2.overscan_insets_in_dip().ToString());
328
329  // HiDPI but overscan display. The specified insets size should be doubled.
330  UpdateDisplay("0+0-500x500,0+501-400x400*2");
331  display_manager()->SetOverscanInsets(
332      display_manager()->GetDisplayAt(1).id(), gfx::Insets(4, 5, 6, 7));
333  EXPECT_EQ("0,0 500x500",
334            GetDisplayInfoAt(0).bounds_in_native().ToString());
335  updated_display_info2 = GetDisplayInfoAt(1);
336  EXPECT_EQ("0,501 400x400",
337            updated_display_info2.bounds_in_native().ToString());
338  EXPECT_EQ("376x380",
339            updated_display_info2.size_in_pixel().ToString());
340  EXPECT_EQ("4,5,6,7",
341            updated_display_info2.overscan_insets_in_dip().ToString());
342  EXPECT_EQ("8,10,12,14",
343            updated_display_info2.GetOverscanInsetsInPixel().ToString());
344
345  // Make sure switching primary display applies the overscan offset only once.
346  ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
347      ScreenAsh::GetSecondaryDisplay());
348  EXPECT_EQ("-500,0 500x500",
349            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
350  EXPECT_EQ("0,0 500x500",
351            GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()).
352            bounds_in_native().ToString());
353  EXPECT_EQ("0,501 400x400",
354            GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()).
355            bounds_in_native().ToString());
356  EXPECT_EQ("0,0 188x190",
357            Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
358}
359
360TEST_F(DisplayManagerTest, ZeroOverscanInsets) {
361  if (!SupportsMultipleDisplays())
362    return;
363
364  // Make sure the display change events is emitted for overscan inset changes.
365  UpdateDisplay("0+0-500x500,0+501-400x400");
366  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
367  int64 display2_id = display_manager()->GetDisplayAt(1).id();
368
369  reset();
370  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
371  EXPECT_EQ(0u, changed().size());
372
373  reset();
374  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0));
375  EXPECT_EQ(1u, changed().size());
376  EXPECT_EQ(display2_id, changed()[0].id());
377
378  reset();
379  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
380  EXPECT_EQ(1u, changed().size());
381  EXPECT_EQ(display2_id, changed()[0].id());
382}
383
384TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
385  if (!SupportsHostWindowResize())
386    return;
387
388  UpdateDisplay("1000x600");
389  EXPECT_EQ(1,
390            Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor());
391  EXPECT_EQ("1000x600",
392            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
393  UpdateDisplay("1000x600*2");
394  EXPECT_EQ(2,
395            Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor());
396  EXPECT_EQ("500x300",
397            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
398}
399
400DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
401  DisplayInfo info(id, ToDisplayName(id), false);
402  info.SetBounds(bounds);
403  return info;
404}
405
406TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) {
407  const int64 internal_display_id =
408      test::DisplayManagerTestApi(display_manager()).
409      SetFirstDisplayAsInternalDisplay();
410  const int external_id = 10;
411  const int mirror_id = 11;
412  const int64 invalid_id = gfx::Display::kInvalidDisplayID;
413  const DisplayInfo internal_display_info =
414      CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
415  const DisplayInfo external_display_info =
416      CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
417  const DisplayInfo mirrored_display_info =
418      CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500));
419
420  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
421  EXPECT_EQ(1U, display_manager()->num_connected_displays());
422  std::string default_bounds =
423      display_manager()->GetDisplayAt(0).bounds().ToString();
424
425  std::vector<DisplayInfo> display_info_list;
426  // Primary disconnected.
427  display_manager()->OnNativeDisplaysChanged(display_info_list);
428  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
429  EXPECT_EQ(default_bounds,
430            display_manager()->GetDisplayAt(0).bounds().ToString());
431  EXPECT_EQ(1U, display_manager()->num_connected_displays());
432  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
433
434  if (!SupportsMultipleDisplays())
435    return;
436
437  // External connected while primary was disconnected.
438  display_info_list.push_back(external_display_info);
439  display_manager()->OnNativeDisplaysChanged(display_info_list);
440  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
441
442  EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
443  EXPECT_EQ("1,1 100x100",
444            GetDisplayInfoForId(external_id).bounds_in_native().ToString());
445  EXPECT_EQ(1U, display_manager()->num_connected_displays());
446  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
447  EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id());
448
449  EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId());
450
451  // Primary connected, with different bounds.
452  display_info_list.clear();
453  display_info_list.push_back(internal_display_info);
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(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id());
458
459  // This combinatino is new, so internal display becomes primary.
460  EXPECT_EQ("0,0 500x500",
461            GetDisplayForId(internal_display_id).bounds().ToString());
462  EXPECT_EQ("1,1 100x100",
463            GetDisplayInfoForId(10).bounds_in_native().ToString());
464  EXPECT_EQ(2U, display_manager()->num_connected_displays());
465  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
466  EXPECT_EQ(ToDisplayName(internal_display_id),
467            display_manager()->GetDisplayNameForId(internal_display_id));
468
469  // Emulate suspend.
470  display_info_list.clear();
471  display_manager()->OnNativeDisplaysChanged(display_info_list);
472  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
473  EXPECT_EQ("0,0 500x500",
474            GetDisplayForId(internal_display_id).bounds().ToString());
475  EXPECT_EQ("1,1 100x100",
476            GetDisplayInfoForId(10).bounds_in_native().ToString());
477  EXPECT_EQ(2U, display_manager()->num_connected_displays());
478  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
479  EXPECT_EQ(ToDisplayName(internal_display_id),
480            display_manager()->GetDisplayNameForId(internal_display_id));
481
482  // External display has disconnected then resumed.
483  display_info_list.push_back(internal_display_info);
484  display_manager()->OnNativeDisplaysChanged(display_info_list);
485  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
486  EXPECT_EQ("0,0 500x500",
487            GetDisplayForId(internal_display_id).bounds().ToString());
488  EXPECT_EQ(1U, display_manager()->num_connected_displays());
489  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
490
491  // External display was changed during suspend.
492  display_info_list.push_back(external_display_info);
493  display_manager()->OnNativeDisplaysChanged(display_info_list);
494  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
495  EXPECT_EQ(2U, display_manager()->num_connected_displays());
496  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
497
498  // suspend...
499  display_info_list.clear();
500  display_manager()->OnNativeDisplaysChanged(display_info_list);
501  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
502  EXPECT_EQ(2U, display_manager()->num_connected_displays());
503  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
504
505  // and resume with different external display.
506  display_info_list.push_back(internal_display_info);
507  display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100)));
508  display_manager()->OnNativeDisplaysChanged(display_info_list);
509  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
510  EXPECT_EQ(2U, display_manager()->num_connected_displays());
511  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
512  EXPECT_FALSE(display_manager()->IsMirrored());
513
514  // mirrored...
515  display_info_list.clear();
516  display_info_list.push_back(internal_display_info);
517  display_info_list.push_back(mirrored_display_info);
518  display_manager()->OnNativeDisplaysChanged(display_info_list);
519  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
520  EXPECT_EQ("0,0 500x500",
521            GetDisplayForId(internal_display_id).bounds().ToString());
522  EXPECT_EQ(2U, display_manager()->num_connected_displays());
523  EXPECT_EQ(11U, display_manager()->mirrored_display().id());
524  EXPECT_TRUE(display_manager()->IsMirrored());
525
526  // Test display name.
527  EXPECT_EQ(ToDisplayName(internal_display_id),
528            display_manager()->GetDisplayNameForId(internal_display_id));
529  EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10));
530  EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11));
531  EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12));
532  // Default name for the id that doesn't exist.
533  EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100));
534
535  // and exit mirroring.
536  display_info_list.clear();
537  display_info_list.push_back(internal_display_info);
538  display_info_list.push_back(external_display_info);
539  display_manager()->OnNativeDisplaysChanged(display_info_list);
540  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
541  EXPECT_EQ(2U, display_manager()->num_connected_displays());
542  EXPECT_FALSE(display_manager()->IsMirrored());
543  EXPECT_EQ("0,0 500x500",
544            GetDisplayForId(internal_display_id).bounds().ToString());
545  EXPECT_EQ("500,0 100x100",
546            GetDisplayForId(10).bounds().ToString());
547
548  // Turn off internal
549  display_info_list.clear();
550  display_info_list.push_back(external_display_info);
551  display_manager()->OnNativeDisplaysChanged(display_info_list);
552  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
553  EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
554  EXPECT_EQ("1,1 100x100",
555            GetDisplayInfoForId(external_id).bounds_in_native().ToString());
556  EXPECT_EQ(1U, display_manager()->num_connected_displays());
557  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
558
559  // Switched to another display
560  display_info_list.clear();
561  display_info_list.push_back(internal_display_info);
562  display_manager()->OnNativeDisplaysChanged(display_info_list);
563  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
564  EXPECT_EQ(
565      "0,0 500x500",
566      GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString());
567  EXPECT_EQ(1U, display_manager()->num_connected_displays());
568  EXPECT_FALSE(display_manager()->mirrored_display().is_valid());
569}
570
571#if defined(OS_WIN)
572// TODO(scottmg): RootWindow doesn't get resized on Windows
573// Ash. http://crbug.com/247916.
574#define MAYBE_TestNativeDisplaysChangedNoInternal \
575        DISABLED_TestNativeDisplaysChangedNoInternal
576#else
577#define MAYBE_TestNativeDisplaysChangedNoInternal \
578        TestNativeDisplaysChangedNoInternal
579#endif
580
581TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) {
582  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
583
584  // Don't change the display info if all displays are disconnected.
585  std::vector<DisplayInfo> display_info_list;
586  display_manager()->OnNativeDisplaysChanged(display_info_list);
587  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
588
589  // Connect another display which will become primary.
590  const DisplayInfo external_display_info =
591      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
592  display_info_list.push_back(external_display_info);
593  display_manager()->OnNativeDisplaysChanged(display_info_list);
594  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
595  EXPECT_EQ("1,1 100x100",
596            GetDisplayInfoForId(10).bounds_in_native().ToString());
597  EXPECT_EQ("100x100",
598            ash::Shell::GetPrimaryRootWindow()->GetHostSize().ToString());
599}
600
601#if defined(OS_WIN)
602// Tests that rely on the actual host size/location does not work on windows.
603#define MAYBE_EnsurePointerInDisplays DISABLED_EnsurePointerInDisplays
604#define MAYBE_EnsurePointerInDisplays_2ndOnLeft DISABLED_EnsurePointerInDisplays_2ndOnLeft
605#else
606#define MAYBE_EnsurePointerInDisplays EnsurePointerInDisplays
607#define MAYBE_EnsurePointerInDisplays_2ndOnLeft EnsurePointerInDisplays_2ndOnLeft
608#endif
609
610TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays) {
611  UpdateDisplay("200x200,300x300");
612  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
613
614  aura::Env* env = aura::Env::GetInstance();
615
616  aura::test::EventGenerator generator(root_windows[0]);
617
618  // Set the initial position.
619  generator.MoveMouseToInHost(350, 150);
620  EXPECT_EQ("350,150", env->last_mouse_location().ToString());
621
622  // A mouse pointer will stay in the 2nd display.
623  UpdateDisplay("300x300,200x200");
624  EXPECT_EQ("450,50", env->last_mouse_location().ToString());
625
626  // A mouse pointer will be outside of displays and move to the
627  // center of 2nd display.
628  UpdateDisplay("300x300,100x100");
629  EXPECT_EQ("350,50", env->last_mouse_location().ToString());
630
631  // 2nd display was disconnected, and the cursor is
632  // now in the 1st display.
633  UpdateDisplay("400x400");
634  EXPECT_EQ("50,350", env->last_mouse_location().ToString());
635
636  // 1st display's resolution has changed, and the mouse pointer is
637  // now outside. Move the mouse pointer to the center of 1st display.
638  UpdateDisplay("300x300");
639  EXPECT_EQ("150,150", env->last_mouse_location().ToString());
640
641  // Move the mouse pointer to the bottom of 1st display.
642  generator.MoveMouseToInHost(150, 290);
643  EXPECT_EQ("150,290", env->last_mouse_location().ToString());
644
645  // The mouse pointer is now on 2nd display.
646  UpdateDisplay("300x280,200x200");
647  EXPECT_EQ("450,10", env->last_mouse_location().ToString());
648}
649
650TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays_2ndOnLeft) {
651  // Set the 2nd display on the left.
652  DisplayLayoutStore* layout_store =
653      Shell::GetInstance()->display_manager()->layout_store();
654  DisplayLayout layout = layout_store->default_display_layout();
655  layout.position = DisplayLayout::LEFT;
656  layout_store->SetDefaultDisplayLayout(layout);
657
658  UpdateDisplay("200x200,300x300");
659  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
660
661  EXPECT_EQ("-300,0 300x300",
662            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
663
664  aura::Env* env = aura::Env::GetInstance();
665
666  // Set the initial position.
667  root_windows[0]->MoveCursorTo(gfx::Point(-150, 250));
668  EXPECT_EQ("-150,250", env->last_mouse_location().ToString());
669
670  // A mouse pointer will stay in 2nd display.
671  UpdateDisplay("300x300,200x300");
672  EXPECT_EQ("-50,150", env->last_mouse_location().ToString());
673
674  // A mouse pointer will be outside of displays and move to the
675  // center of 2nd display.
676  UpdateDisplay("300x300,200x100");
677  EXPECT_EQ("-100,50", env->last_mouse_location().ToString());
678
679  // 2nd display was disconnected. Mouse pointer should move to
680  // 1st display.
681  UpdateDisplay("300x300");
682  EXPECT_EQ("150,150", env->last_mouse_location().ToString());
683}
684
685TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
686  if (!SupportsMultipleDisplays())
687    return;
688
689  const int64 internal_display_id =
690      test::DisplayManagerTestApi(display_manager()).
691      SetFirstDisplayAsInternalDisplay();
692  const DisplayInfo native_display_info =
693      CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
694  const DisplayInfo secondary_display_info =
695      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
696
697  std::vector<DisplayInfo> display_info_list;
698  display_info_list.push_back(native_display_info);
699  display_info_list.push_back(secondary_display_info);
700  display_manager()->OnNativeDisplaysChanged(display_info_list);
701  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
702  EXPECT_EQ("0,0 500x500",
703            GetDisplayForId(internal_display_id).bounds().ToString());
704  EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString());
705
706  ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay(
707      GetDisplayForId(secondary_display_info.id()));
708  EXPECT_EQ("-500,0 500x500",
709            GetDisplayForId(internal_display_id).bounds().ToString());
710  EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());
711
712  // OnNativeDisplaysChanged may change the display bounds.  Here makes sure
713  // nothing changed if the exactly same displays are specified.
714  display_manager()->OnNativeDisplaysChanged(display_info_list);
715  EXPECT_EQ("-500,0 500x500",
716            GetDisplayForId(internal_display_id).bounds().ToString());
717  EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());
718}
719
720TEST_F(DisplayManagerTest, DontRememberBestResolution) {
721  int display_id = 1000;
722  DisplayInfo native_display_info =
723      CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
724  std::vector<Resolution> resolutions;
725  resolutions.push_back(Resolution(gfx::Size(1000, 500), false));
726  resolutions.push_back(Resolution(gfx::Size(800, 300), false));
727  resolutions.push_back(Resolution(gfx::Size(400, 500), false));
728
729  native_display_info.set_resolutions(resolutions);
730
731  std::vector<DisplayInfo> display_info_list;
732  display_info_list.push_back(native_display_info);
733  display_manager()->OnNativeDisplaysChanged(display_info_list);
734
735  gfx::Size selected;
736  EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId(
737      display_id, &selected));
738
739  // Unsupported resolution.
740  display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 4000));
741  EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId(
742      display_id, &selected));
743
744  // Supported resolution.
745  display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300));
746  EXPECT_TRUE(display_manager()->GetSelectedResolutionForDisplayId(
747      display_id, &selected));
748  EXPECT_EQ("800x300", selected.ToString());
749
750  // Best resolution.
751  display_manager()->SetDisplayResolution(display_id, gfx::Size(1000, 500));
752  EXPECT_FALSE(display_manager()->GetSelectedResolutionForDisplayId(
753      display_id, &selected));
754}
755
756TEST_F(DisplayManagerTest, Rotate) {
757  if (!SupportsMultipleDisplays())
758    return;
759
760  UpdateDisplay("100x200/r,300x400/l");
761  EXPECT_EQ("1,1 100x200",
762            GetDisplayInfoAt(0).bounds_in_native().ToString());
763  EXPECT_EQ("200x100",
764            GetDisplayInfoAt(0).size_in_pixel().ToString());
765
766  EXPECT_EQ("1,201 300x400",
767            GetDisplayInfoAt(1).bounds_in_native().ToString());
768  EXPECT_EQ("400x300",
769            GetDisplayInfoAt(1).size_in_pixel().ToString());
770  reset();
771  UpdateDisplay("100x200/b,300x400");
772  EXPECT_EQ("2 0 0", GetCountSummary());
773  reset();
774
775  EXPECT_EQ("1,1 100x200",
776            GetDisplayInfoAt(0).bounds_in_native().ToString());
777  EXPECT_EQ("100x200",
778            GetDisplayInfoAt(0).size_in_pixel().ToString());
779
780  EXPECT_EQ("1,201 300x400",
781            GetDisplayInfoAt(1).bounds_in_native().ToString());
782  EXPECT_EQ("300x400",
783            GetDisplayInfoAt(1).size_in_pixel().ToString());
784
785  // Just Rotating display will change the bounds on both display.
786  UpdateDisplay("100x200/l,300x400");
787  EXPECT_EQ("2 0 0", GetCountSummary());
788  reset();
789
790  // Updating tothe same configuration should report no changes.
791  UpdateDisplay("100x200/l,300x400");
792  EXPECT_EQ("0 0 0", GetCountSummary());
793  reset();
794
795  UpdateDisplay("100x200/l,300x400");
796  EXPECT_EQ("0 0 0", GetCountSummary());
797  reset();
798
799  UpdateDisplay("200x200");
800  EXPECT_EQ("1 0 1", GetCountSummary());
801  reset();
802
803  UpdateDisplay("200x200/l");
804  EXPECT_EQ("1 0 0", GetCountSummary());
805}
806
807TEST_F(DisplayManagerTest, UIScale) {
808  UpdateDisplay("1280x800");
809  int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id();
810  display_manager()->SetDisplayUIScale(display_id, 1.125f);
811  EXPECT_EQ(1.0, GetDisplayInfoAt(0).ui_scale());
812  display_manager()->SetDisplayUIScale(display_id, 0.8f);
813  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
814  display_manager()->SetDisplayUIScale(display_id, 0.75f);
815  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
816  display_manager()->SetDisplayUIScale(display_id, 0.625f);
817  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
818
819  gfx::Display::SetInternalDisplayId(display_id);
820
821  display_manager()->SetDisplayUIScale(display_id, 1.5f);
822  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
823  display_manager()->SetDisplayUIScale(display_id, 1.25f);
824  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
825  display_manager()->SetDisplayUIScale(display_id, 1.125f);
826  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
827  display_manager()->SetDisplayUIScale(display_id, 0.8f);
828  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
829  display_manager()->SetDisplayUIScale(display_id, 0.75f);
830  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
831  display_manager()->SetDisplayUIScale(display_id, 0.625f);
832  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
833  display_manager()->SetDisplayUIScale(display_id, 0.6f);
834  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
835  display_manager()->SetDisplayUIScale(display_id, 0.5f);
836  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
837
838  UpdateDisplay("1366x768");
839  display_manager()->SetDisplayUIScale(display_id, 1.5f);
840  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
841  display_manager()->SetDisplayUIScale(display_id, 1.25f);
842  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
843  display_manager()->SetDisplayUIScale(display_id, 1.125f);
844  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
845  display_manager()->SetDisplayUIScale(display_id, 0.8f);
846  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
847  display_manager()->SetDisplayUIScale(display_id, 0.75f);
848  EXPECT_EQ(0.75f, GetDisplayInfoAt(0).ui_scale());
849  display_manager()->SetDisplayUIScale(display_id, 0.6f);
850  EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale());
851  display_manager()->SetDisplayUIScale(display_id, 0.625f);
852  EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale());
853  display_manager()->SetDisplayUIScale(display_id, 0.5f);
854  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
855
856  UpdateDisplay("1280x850*2");
857  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
858  display_manager()->SetDisplayUIScale(display_id, 1.5f);
859  EXPECT_EQ(1.5f, GetDisplayInfoAt(0).ui_scale());
860  display_manager()->SetDisplayUIScale(display_id, 1.25f);
861  EXPECT_EQ(1.25f, GetDisplayInfoAt(0).ui_scale());
862  display_manager()->SetDisplayUIScale(display_id, 1.125f);
863  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
864  display_manager()->SetDisplayUIScale(display_id, 0.8f);
865  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
866  display_manager()->SetDisplayUIScale(display_id, 0.75f);
867  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
868  display_manager()->SetDisplayUIScale(display_id, 0.625f);
869  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
870  display_manager()->SetDisplayUIScale(display_id, 0.6f);
871  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
872  display_manager()->SetDisplayUIScale(display_id, 0.5f);
873  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
874}
875
876
877#if defined(OS_WIN)
878// TODO(scottmg): RootWindow doesn't get resized on Windows
879// Ash. http://crbug.com/247916.
880#define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom
881#else
882#define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom
883#endif
884
885TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) {
886  // Make sure just rotating will not change native location.
887  UpdateDisplay("300x200,200x150");
888  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
889  aura::Env* env = aura::Env::GetInstance();
890
891  aura::test::EventGenerator generator1(root_windows[0]);
892  aura::test::EventGenerator generator2(root_windows[1]);
893
894  // Test on 1st display.
895  generator1.MoveMouseToInHost(150, 50);
896  EXPECT_EQ("150,50", env->last_mouse_location().ToString());
897  UpdateDisplay("300x200/r,200x150");
898  EXPECT_EQ("50,149", env->last_mouse_location().ToString());
899
900  // Test on 2nd display.
901  generator2.MoveMouseToInHost(50, 100);
902  EXPECT_EQ("250,100", env->last_mouse_location().ToString());
903  UpdateDisplay("300x200/r,200x150/l");
904  EXPECT_EQ("249,50", env->last_mouse_location().ToString());
905
906  // The native location is now outside, so move to the center
907  // of closest display.
908  UpdateDisplay("300x200/r,100x50/l");
909  EXPECT_EQ("225,50", env->last_mouse_location().ToString());
910
911  // Make sure just zooming will not change native location.
912  UpdateDisplay("600x400*2,400x300");
913
914  // Test on 1st display.
915  generator1.MoveMouseToInHost(200, 300);
916  EXPECT_EQ("100,150", env->last_mouse_location().ToString());
917  UpdateDisplay("600x400*2@1.5,400x300");
918  EXPECT_EQ("150,225", env->last_mouse_location().ToString());
919
920  // Test on 2nd display.
921  UpdateDisplay("600x400,400x300*2");
922  generator2.MoveMouseToInHost(200, 250);
923  EXPECT_EQ("700,125", env->last_mouse_location().ToString());
924  UpdateDisplay("600x400,400x300*2@1.5");
925  EXPECT_EQ("750,187", env->last_mouse_location().ToString());
926
927  // The native location is now outside, so move to the
928  // center of closest display.
929  UpdateDisplay("600x400,400x200*2@1.5");
930  EXPECT_EQ("750,75", env->last_mouse_location().ToString());
931}
932
933class TestDisplayObserver : public gfx::DisplayObserver {
934 public:
935  TestDisplayObserver() : changed_(false) {}
936  virtual ~TestDisplayObserver() {}
937
938  // gfx::DisplayObserver overrides:
939  virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
940  }
941  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
942    // Mirror window should already be delete before restoring
943    // the external dispay.
944    EXPECT_FALSE(test_api.GetRootWindow());
945    changed_ = true;
946  }
947  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
948    // Mirror window should not be created until the external display
949    // is removed.
950    EXPECT_FALSE(test_api.GetRootWindow());
951    changed_ = true;
952  }
953
954  bool changed_and_reset() {
955    bool changed = changed_;
956    changed_ = false;
957    return changed;
958  }
959
960 private:
961  test::MirrorWindowTestApi test_api;
962  bool changed_;
963
964  DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver);
965};
966
967TEST_F(DisplayManagerTest, SoftwareMirroring) {
968  if (!SupportsMultipleDisplays())
969    return;
970
971  UpdateDisplay("300x400,400x500");
972
973  test::MirrorWindowTestApi test_api;
974  EXPECT_EQ(NULL, test_api.GetRootWindow());
975
976  TestDisplayObserver display_observer;
977  Shell::GetScreen()->AddObserver(&display_observer);
978
979  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
980  display_manager->SetSoftwareMirroring(true);
981  display_manager->UpdateDisplays();
982  EXPECT_TRUE(display_observer.changed_and_reset());
983  EXPECT_EQ(1U, display_manager->GetNumDisplays());
984  EXPECT_EQ("0,0 300x400",
985            Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString());
986  EXPECT_EQ("400x500", test_api.GetRootWindow()->GetHostSize().ToString());
987  EXPECT_EQ("300x400", test_api.GetRootWindow()->bounds().size().ToString());
988  EXPECT_TRUE(display_manager->IsMirrored());
989
990  display_manager->SetMirrorMode(false);
991  EXPECT_TRUE(display_observer.changed_and_reset());
992  EXPECT_EQ(NULL, test_api.GetRootWindow());
993  EXPECT_EQ(2U, display_manager->GetNumDisplays());
994  EXPECT_FALSE(display_manager->IsMirrored());
995
996  // Make sure the mirror window has the pixel size of the
997  // source display.
998  display_manager->SetMirrorMode(true);
999  EXPECT_TRUE(display_observer.changed_and_reset());
1000
1001  UpdateDisplay("300x400@0.5,400x500");
1002  EXPECT_FALSE(display_observer.changed_and_reset());
1003  EXPECT_EQ("300x400", test_api.GetRootWindow()->bounds().size().ToString());
1004  EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString());
1005
1006  UpdateDisplay("310x410*2,400x500");
1007  EXPECT_FALSE(display_observer.changed_and_reset());
1008  EXPECT_EQ("310x410", test_api.GetRootWindow()->bounds().size().ToString());
1009  EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString());
1010
1011  UpdateDisplay("320x420/r,400x500");
1012  EXPECT_FALSE(display_observer.changed_and_reset());
1013  EXPECT_EQ("320x420", test_api.GetRootWindow()->bounds().size().ToString());
1014  EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString());
1015
1016  UpdateDisplay("330x440/r,400x500");
1017  EXPECT_FALSE(display_observer.changed_and_reset());
1018  EXPECT_EQ("330x440", test_api.GetRootWindow()->bounds().size().ToString());
1019  EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString());
1020
1021  // Overscan insets are ignored.
1022  UpdateDisplay("400x600/o,600x800/o");
1023  EXPECT_FALSE(display_observer.changed_and_reset());
1024  EXPECT_EQ("400x600", test_api.GetRootWindow()->bounds().size().ToString());
1025  EXPECT_EQ("600x800", GetMirroredDisplay().size().ToString());
1026
1027  Shell::GetScreen()->RemoveObserver(&display_observer);
1028}
1029
1030TEST_F(DisplayManagerTest, MirroredLayout) {
1031  if (!SupportsMultipleDisplays())
1032    return;
1033
1034  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
1035  UpdateDisplay("500x500,400x400");
1036  EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored);
1037  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1038  EXPECT_EQ(2U, display_manager->num_connected_displays());
1039
1040  UpdateDisplay("1+0-500x500,1+0-500x500");
1041  EXPECT_TRUE(display_manager->GetCurrentDisplayLayout().mirrored);
1042  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
1043  EXPECT_EQ(2U, display_manager->num_connected_displays());
1044
1045  UpdateDisplay("500x500,500x500");
1046  EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored);
1047  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1048  EXPECT_EQ(2U, display_manager->num_connected_displays());
1049}
1050
1051TEST_F(DisplayManagerTest, InvertLayout) {
1052  EXPECT_EQ("left, 0",
1053            DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString());
1054  EXPECT_EQ("left, -100",
1055            DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString());
1056  EXPECT_EQ("left, 50",
1057            DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString());
1058
1059  EXPECT_EQ("right, 0",
1060            DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString());
1061  EXPECT_EQ("right, -90",
1062            DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString());
1063  EXPECT_EQ("right, 60",
1064            DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString());
1065
1066  EXPECT_EQ("bottom, 0",
1067            DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString());
1068  EXPECT_EQ("bottom, -80",
1069            DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString());
1070  EXPECT_EQ("bottom, 70",
1071            DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString());
1072
1073  EXPECT_EQ("top, 0",
1074            DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString());
1075  EXPECT_EQ("top, -70",
1076            DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString());
1077  EXPECT_EQ("top, 80",
1078            DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
1079}
1080
1081#if defined(OS_WIN)
1082// TODO(scottmg): RootWindow doesn't get resized on Windows
1083// Ash. http://crbug.com/247916.
1084#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin
1085#else
1086#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin
1087#endif
1088
1089TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) {
1090  UpdateDisplay("100x200,300x400");
1091  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1092  Shell::RootWindowList root_windows =
1093      Shell::GetInstance()->GetAllRootWindows();
1094  ASSERT_EQ(2U, root_windows.size());
1095  EXPECT_EQ("1,1", root_windows[0]->GetHostOrigin().ToString());
1096  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
1097  // UpdateDisplay set the origin if it's not set.
1098  EXPECT_NE("1,1", root_windows[1]->GetHostOrigin().ToString());
1099  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
1100
1101  UpdateDisplay("100x200,200+300-300x400");
1102  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1103  EXPECT_EQ("0,0", root_windows[0]->GetHostOrigin().ToString());
1104  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
1105  EXPECT_EQ("200,300", root_windows[1]->GetHostOrigin().ToString());
1106  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
1107
1108  UpdateDisplay("400+500-200x300,300x400");
1109  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1110  EXPECT_EQ("400,500", root_windows[0]->GetHostOrigin().ToString());
1111  EXPECT_EQ("200x300", root_windows[0]->GetHostSize().ToString());
1112  EXPECT_EQ("0,0", root_windows[1]->GetHostOrigin().ToString());
1113  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
1114
1115  UpdateDisplay("100+200-100x200,300+500-200x300");
1116  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1117  EXPECT_EQ("100,200", root_windows[0]->GetHostOrigin().ToString());
1118  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
1119  EXPECT_EQ("300,500", root_windows[1]->GetHostOrigin().ToString());
1120  EXPECT_EQ("200x300", root_windows[1]->GetHostSize().ToString());
1121}
1122
1123}  // namespace internal
1124}  // namespace ash
1125