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