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