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