display_controller_unittest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)// found in the LICENSE file.
4c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
5c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/display/display_controller.h"
6c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
7c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/display/display_info.h"
8c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/display/display_manager.h"
9c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/launcher/launcher.h"
10c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/screen_ash.h"
11c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/shelf/shelf_widget.h"
12c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/shell.h"
13c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/test/ash_test_base.h"
14c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ash/test/cursor_manager_test_api.h"
15c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/aura/env.h"
16c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/aura/root_window.h"
17c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/aura/test/event_generator.h"
18c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/aura/window_tracker.h"
19c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/base/events/event_handler.h"
20c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/gfx/display.h"
21c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/gfx/screen.h"
22c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "ui/views/widget/widget.h"
23c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
24c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)namespace ash {
25c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)namespace test {
26c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)namespace {
27c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
28c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)const char kDesktopBackgroundView[] = "DesktopBackgroundView";
29c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
30c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)class TestObserver : public DisplayController::Observer {
31c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) public:
32c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  TestObserver() : changing_count_(0), changed_count_(0) {
33c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Shell::GetInstance()->display_controller()->AddObserver(this);
34c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
35c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)  virtual ~TestObserver() {
37323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Shell::GetInstance()->display_controller()->RemoveObserver(this);
38c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
39c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
40c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  virtual void OnDisplayConfigurationChanging() OVERRIDE {
41c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ++changing_count_;
42c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
43c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  virtual void OnDisplayConfigurationChanged() OVERRIDE {
45c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ++changed_count_;
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci  }
47c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
48c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  int CountAndReset() {
49c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    EXPECT_EQ(changing_count_, changed_count_);
50c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    int c = changing_count_;
51c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    changing_count_ = changed_count_ = 0;
52c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return c;
53c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
54c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
55c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) private:
56c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  int changing_count_;
57c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  int changed_count_;
58f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
59f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestObserver);
60c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)};
61c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
62f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)gfx::Display GetPrimaryDisplay() {
63f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)  return Shell::GetScreen()->GetDisplayNearestWindow(
64c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      Shell::GetAllRootWindows()[0]);
65c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
66f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
67c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)gfx::Display GetSecondaryDisplay() {
68c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  return Shell::GetScreen()->GetDisplayNearestWindow(
69c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      Shell::GetAllRootWindows()[1]);
70c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
71c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
72323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position,
73c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                                        int offset) {
74323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)  DisplayController* display_controller =
75c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      Shell::GetInstance()->display_controller();
76c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  DisplayLayout layout(position, offset);
77323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)  ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
78c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  display_controller->SetLayoutForCurrentDisplays(layout);
79323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
80c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
81c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
82c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  SetSecondaryDisplayLayoutAndOffset(position, 0);
83c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
84f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
85c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void SetDefaultDisplayLayout(DisplayLayout::Position position) {
86c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  Shell::GetInstance()->display_controller()->
87c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      SetDefaultDisplayLayout(DisplayLayout(position, 0));
88c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
89c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
90c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)class DisplayControllerShutdownTest : public test::AshTestBase {
91c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) public:
92c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
93f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)    test::AshTestBase::TearDown();
94c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // Make sure that primary display is accessible after shutdown.
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay();
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    EXPECT_EQ("0,0 444x333", primary.bounds().ToString());
97c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
98c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
99c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)};
100c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
101c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)class TestEventHandler : public ui::EventHandler {
102c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) public:
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  TestEventHandler() : target_root_(NULL),
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       touch_radius_x_(0.0),
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       touch_radius_y_(0.0),
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                       scroll_x_offset_(0.0),
107c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                       scroll_y_offset_(0.0),
108c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                       scroll_x_offset_ordinal_(0.0),
109c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)                       scroll_y_offset_ordinal_(0.0) {}
110c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  virtual ~TestEventHandler() {}
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
112c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
113c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (event->flags() & ui::EF_IS_SYNTHESIZED)
114c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      return;
115c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    aura::Window* target = static_cast<aura::Window*>(event->target());
116c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    mouse_location_ = event->root_location();
117c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    target_root_ = target->GetRootWindow();
118c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    event->StopPropagation();
119c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  }
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
122c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    aura::Window* target = static_cast<aura::Window*>(event->target());
123c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // Only record when the target is the background which covers
124323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // entire root window.
125323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (target->name() != kDesktopBackgroundView)
126c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)      return;
127c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    touch_radius_x_ = event->radius_x();
128bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    touch_radius_y_ = event->radius_y();
129c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    event->StopPropagation();
130323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)  }
131c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
132c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    aura::Window* target = static_cast<aura::Window*>(event->target());
134c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // Only record when the target is the background which covers
135    // entire root window.
136    if (target->name() != kDesktopBackgroundView)
137      return;
138
139    if (event->type() == ui::ET_SCROLL) {
140      scroll_x_offset_ = event->x_offset();
141      scroll_y_offset_ = event->y_offset();
142      scroll_x_offset_ordinal_ = event->x_offset_ordinal();
143      scroll_y_offset_ordinal_ = event->y_offset_ordinal();
144    }
145    event->StopPropagation();
146  }
147
148  std::string GetLocationAndReset() {
149    std::string result = mouse_location_.ToString();
150    mouse_location_.SetPoint(0, 0);
151    target_root_ = NULL;
152    return result;
153  }
154
155  float touch_radius_x() { return touch_radius_x_; }
156  float touch_radius_y() { return touch_radius_y_; }
157  float scroll_x_offset() { return scroll_x_offset_; }
158  float scroll_y_offset() { return scroll_y_offset_; }
159  float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; }
160  float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; }
161
162 private:
163  gfx::Point mouse_location_;
164  aura::RootWindow* target_root_;
165
166  float touch_radius_x_;
167  float touch_radius_y_;
168  float scroll_x_offset_;
169  float scroll_y_offset_;
170  float scroll_x_offset_ordinal_;
171  float scroll_y_offset_ordinal_;
172
173  DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
174};
175
176gfx::Display::Rotation GetStoredRotation(int64 id) {
177  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
178}
179
180float GetStoredUIScale(int64 id) {
181  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).ui_scale();
182}
183
184}  // namespace
185
186typedef test::AshTestBase DisplayControllerTest;
187
188TEST_F(DisplayControllerShutdownTest, Shutdown) {
189  UpdateDisplay("444x333, 200x200");
190}
191
192TEST_F(DisplayControllerTest, SecondaryDisplayLayout) {
193  TestObserver observer;
194  UpdateDisplay("500x500,400x400");
195  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
196  gfx::Display* secondary_display =
197      Shell::GetInstance()->display_manager()->GetDisplayAt(1);
198  gfx::Insets insets(5, 5, 5, 5);
199  secondary_display->UpdateWorkAreaFromInsets(insets);
200
201  // Default layout is RIGHT.
202  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
203  EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
204  EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
205
206  // Layout the secondary display to the bottom of the primary.
207  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
208  EXPECT_EQ(1, observer.CountAndReset());
209  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
210  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
211  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
212
213  // Layout the secondary display to the left of the primary.
214  SetSecondaryDisplayLayout(DisplayLayout::LEFT);
215  EXPECT_EQ(1, observer.CountAndReset());
216  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
217  EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
218  EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
219
220  // Layout the secondary display to the top of the primary.
221  SetSecondaryDisplayLayout(DisplayLayout::TOP);
222  EXPECT_EQ(1, observer.CountAndReset());
223  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
224  EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
225  EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
226
227  // Layout to the right with an offset.
228  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300);
229  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
230  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
231  EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
232
233  // Keep the minimum 100.
234  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490);
235  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
236  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
237  EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
238
239  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400);
240  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
241  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
242  EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
243
244  //  Layout to the bottom with an offset.
245  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200);
246  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
247  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
248  EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
249
250  // Keep the minimum 100.
251  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490);
252  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
253  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
254  EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
255
256  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
257  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
258  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
259  EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
260}
261
262TEST_F(DisplayControllerTest, BoundsUpdated) {
263  TestObserver observer;
264  SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
265  UpdateDisplay("200x200,300x300");  // layout, resize and add.
266  EXPECT_EQ(1, observer.CountAndReset());
267
268  internal::DisplayManager* display_manager =
269      Shell::GetInstance()->display_manager();
270  gfx::Display* secondary_display = display_manager->GetDisplayAt(1);
271  gfx::Insets insets(5, 5, 5, 5);
272  secondary_display->UpdateWorkAreaFromInsets(insets);
273
274  EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
275  EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
276  EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
277
278  UpdateDisplay("400x400,200x200");
279  EXPECT_EQ(1, observer.CountAndReset());  // two resizes
280  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
281  EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
282
283  UpdateDisplay("400x400,300x300");
284  EXPECT_EQ(1, observer.CountAndReset());
285  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
286  EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
287
288  UpdateDisplay("400x400");
289  EXPECT_EQ(1, observer.CountAndReset());
290  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
291  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
292
293  UpdateDisplay("400x500*2,300x300");
294  EXPECT_EQ(1, observer.CountAndReset());
295  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
296  EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
297  EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
298
299  // No change
300  UpdateDisplay("400x500*2,300x300");
301  EXPECT_EQ(0, observer.CountAndReset());
302
303  // Rotation
304  int64 primary_id = GetPrimaryDisplay().id();
305  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
306  EXPECT_EQ(1, observer.CountAndReset());
307  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
308  EXPECT_EQ(0, observer.CountAndReset());
309
310  // UI scale is eanbled only on internal display.
311  int64 secondary_id = GetSecondaryDisplay().id();
312  gfx::Display::SetInternalDisplayId(secondary_id);
313  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
314  EXPECT_EQ(1, observer.CountAndReset());
315  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
316  EXPECT_EQ(0, observer.CountAndReset());
317  display_manager->SetDisplayUIScale(primary_id, 1.125f);
318  EXPECT_EQ(0, observer.CountAndReset());
319  display_manager->SetDisplayUIScale(primary_id, 1.125f);
320  EXPECT_EQ(0, observer.CountAndReset());
321}
322
323TEST_F(DisplayControllerTest, MirroredLayout) {
324  DisplayController* display_controller =
325      Shell::GetInstance()->display_controller();
326  UpdateDisplay("500x500,400x400");
327  EXPECT_FALSE(display_controller->GetCurrentDisplayLayout().mirrored);
328  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
329  EXPECT_EQ(
330      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
331
332  UpdateDisplay("500x500,1+0-500x500");
333  EXPECT_TRUE(display_controller->GetCurrentDisplayLayout().mirrored);
334  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
335  EXPECT_EQ(
336      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
337
338  UpdateDisplay("500x500,500x500");
339  EXPECT_FALSE(display_controller->GetCurrentDisplayLayout().mirrored);
340  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
341  EXPECT_EQ(
342      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
343}
344
345TEST_F(DisplayControllerTest, InvertLayout) {
346  EXPECT_EQ("left, 0",
347            DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString());
348  EXPECT_EQ("left, -100",
349            DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString());
350  EXPECT_EQ("left, 50",
351            DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString());
352
353  EXPECT_EQ("right, 0",
354            DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString());
355  EXPECT_EQ("right, -90",
356            DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString());
357  EXPECT_EQ("right, 60",
358            DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString());
359
360  EXPECT_EQ("bottom, 0",
361            DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString());
362  EXPECT_EQ("bottom, -80",
363            DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString());
364  EXPECT_EQ("bottom, 70",
365            DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString());
366
367  EXPECT_EQ("top, 0",
368            DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString());
369  EXPECT_EQ("top, -70",
370            DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString());
371  EXPECT_EQ("top, 80",
372            DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
373}
374
375// Crashes flakily on win8 aura bots: crbug.com/237642
376#if defined(OS_WIN) && defined(USE_AURA)
377#define MAYBE_SwapPrimary DISABLED_SwapPrimary
378#else
379#define MAYBE_SwapPrimary SwapPrimary
380#endif
381TEST_F(DisplayControllerTest, MAYBE_SwapPrimary) {
382  DisplayController* display_controller =
383      Shell::GetInstance()->display_controller();
384
385  UpdateDisplay("200x200,300x300");
386  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
387  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
388
389  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
390  display_controller->SetLayoutForCurrentDisplays(display_layout);
391
392  EXPECT_NE(primary_display.id(), secondary_display.id());
393  aura::RootWindow* primary_root =
394      display_controller->GetRootWindowForDisplayId(primary_display.id());
395  aura::RootWindow* secondary_root =
396      display_controller->GetRootWindowForDisplayId(secondary_display.id());
397  EXPECT_NE(primary_root, secondary_root);
398  aura::Window* launcher_window =
399      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
400  EXPECT_TRUE(primary_root->Contains(launcher_window));
401  EXPECT_FALSE(secondary_root->Contains(launcher_window));
402  EXPECT_EQ(primary_display.id(),
403            Shell::GetScreen()->GetDisplayNearestPoint(
404                gfx::Point(-100, -100)).id());
405  EXPECT_EQ(primary_display.id(),
406            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
407
408  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
409  EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString());
410  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
411  EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString());
412  EXPECT_EQ("right, 50",
413            display_controller->GetCurrentDisplayLayout().ToString());
414
415  // Switch primary and secondary
416  display_controller->SetPrimaryDisplay(secondary_display);
417  const DisplayLayout& inverted_layout =
418      display_controller->GetCurrentDisplayLayout();
419  EXPECT_EQ("left, -50", inverted_layout.ToString());
420
421  EXPECT_EQ(secondary_display.id(),
422            Shell::GetScreen()->GetPrimaryDisplay().id());
423  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
424  EXPECT_EQ(secondary_display.id(),
425            Shell::GetScreen()->GetDisplayNearestPoint(
426                gfx::Point(-100, -100)).id());
427  EXPECT_EQ(secondary_display.id(),
428            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
429
430  EXPECT_EQ(
431      primary_root,
432      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
433  EXPECT_EQ(
434      secondary_root,
435      display_controller->GetRootWindowForDisplayId(primary_display.id()));
436  EXPECT_TRUE(primary_root->Contains(launcher_window));
437  EXPECT_FALSE(secondary_root->Contains(launcher_window));
438
439  // Test if the bounds are correctly swapped.
440  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
441  gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay();
442  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
443  EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString());
444  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
445
446  EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString());
447
448  aura::WindowTracker tracker;
449  tracker.Add(primary_root);
450  tracker.Add(secondary_root);
451
452  // Deleting 2nd display should move the primary to original primary display.
453  UpdateDisplay("200x200");
454  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
455  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
456  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
457  EXPECT_EQ(primary_display.id(),
458            Shell::GetScreen()->GetDisplayNearestPoint(
459                gfx::Point(-100, -100)).id());
460  EXPECT_EQ(primary_display.id(),
461            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
462  EXPECT_TRUE(tracker.Contains(primary_root));
463  EXPECT_FALSE(tracker.Contains(secondary_root));
464  EXPECT_TRUE(primary_root->Contains(launcher_window));
465}
466
467// Crashes flakily on win8 aura bots: crbug.com/237642
468#if defined(OS_WIN) && defined(USE_AURA)
469#define MAYBE_SwapPrimaryById DISABLED_SwapPrimaryById
470#else
471#define MAYBE_SwapPrimaryById SwapPrimaryById
472#endif
473TEST_F(DisplayControllerTest, MAYBE_SwapPrimaryById) {
474  DisplayController* display_controller =
475      Shell::GetInstance()->display_controller();
476
477  UpdateDisplay("200x200,300x300");
478  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
479  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
480
481  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
482  display_controller->SetLayoutForCurrentDisplays(display_layout);
483
484  EXPECT_NE(primary_display.id(), secondary_display.id());
485  aura::RootWindow* primary_root =
486      display_controller->GetRootWindowForDisplayId(primary_display.id());
487  aura::RootWindow* secondary_root =
488      display_controller->GetRootWindowForDisplayId(secondary_display.id());
489  aura::Window* launcher_window =
490      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
491  EXPECT_TRUE(primary_root->Contains(launcher_window));
492  EXPECT_FALSE(secondary_root->Contains(launcher_window));
493  EXPECT_NE(primary_root, secondary_root);
494  EXPECT_EQ(primary_display.id(),
495            Shell::GetScreen()->GetDisplayNearestPoint(
496                gfx::Point(-100, -100)).id());
497  EXPECT_EQ(primary_display.id(),
498            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
499
500  // Switch primary and secondary by display ID.
501  TestObserver observer;
502  display_controller->SetPrimaryDisplayId(secondary_display.id());
503  EXPECT_EQ(secondary_display.id(),
504            Shell::GetScreen()->GetPrimaryDisplay().id());
505  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
506  EXPECT_LT(0, observer.CountAndReset());
507
508  EXPECT_EQ(
509      primary_root,
510      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
511  EXPECT_EQ(
512      secondary_root,
513      display_controller->GetRootWindowForDisplayId(primary_display.id()));
514  EXPECT_TRUE(primary_root->Contains(launcher_window));
515  EXPECT_FALSE(secondary_root->Contains(launcher_window));
516
517  const DisplayLayout& inverted_layout =
518      display_controller->GetCurrentDisplayLayout();
519
520  EXPECT_EQ("left, -50", inverted_layout.ToString());
521
522  // Calling the same ID don't do anything.
523  display_controller->SetPrimaryDisplayId(secondary_display.id());
524  EXPECT_EQ(0, observer.CountAndReset());
525
526  aura::WindowTracker tracker;
527  tracker.Add(primary_root);
528  tracker.Add(secondary_root);
529
530  // Deleting 2nd display should move the primary to original primary display.
531  UpdateDisplay("200x200");
532  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
533  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
534  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
535  EXPECT_EQ(primary_display.id(),
536            Shell::GetScreen()->GetDisplayNearestPoint(
537                gfx::Point(-100, -100)).id());
538  EXPECT_EQ(primary_display.id(),
539            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
540  EXPECT_TRUE(tracker.Contains(primary_root));
541  EXPECT_FALSE(tracker.Contains(secondary_root));
542  EXPECT_TRUE(primary_root->Contains(launcher_window));
543
544  internal::DisplayManager* display_manager =
545      Shell::GetInstance()->display_manager();
546  // Adding 2nd display with the same ID.  The 2nd display should become primary
547  // since secondary id is still stored as desirable_primary_id.
548  std::vector<internal::DisplayInfo> display_info_list;
549  display_info_list.push_back(
550      display_manager->GetDisplayInfo(primary_display.id()));
551  display_info_list.push_back(
552      display_manager->GetDisplayInfo(secondary_display.id()));
553  display_manager->OnNativeDisplaysChanged(display_info_list);
554
555  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
556  EXPECT_EQ(secondary_display.id(),
557            Shell::GetScreen()->GetPrimaryDisplay().id());
558  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
559  EXPECT_EQ(
560      primary_root,
561      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
562  EXPECT_NE(
563      primary_root,
564      display_controller->GetRootWindowForDisplayId(primary_display.id()));
565  EXPECT_TRUE(primary_root->Contains(launcher_window));
566
567  // Deleting 2nd display and adding 2nd display with a different ID.  The 2nd
568  // display shouldn't become primary.
569  UpdateDisplay("200x200");
570  internal::DisplayInfo third_display_info(
571      secondary_display.id() + 1, std::string(), false);
572  third_display_info.SetBounds(secondary_display.bounds());
573  ASSERT_NE(primary_display.id(), third_display_info.id());
574
575  const internal::DisplayInfo& primary_display_info =
576      display_manager->GetDisplayInfo(primary_display.id());
577  std::vector<internal::DisplayInfo> display_info_list2;
578  display_info_list2.push_back(primary_display_info);
579  display_info_list2.push_back(third_display_info);
580  display_manager->OnNativeDisplaysChanged(display_info_list2);
581  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
582  EXPECT_EQ(primary_display.id(),
583            Shell::GetScreen()->GetPrimaryDisplay().id());
584  EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id());
585  EXPECT_EQ(
586      primary_root,
587      display_controller->GetRootWindowForDisplayId(primary_display.id()));
588  EXPECT_NE(
589      primary_root,
590      display_controller->GetRootWindowForDisplayId(third_display_info.id()));
591  EXPECT_TRUE(primary_root->Contains(launcher_window));
592}
593
594#if defined(OS_WIN)
595// Flaky failures on Win8 due to window activation messages. crbug.com/239539
596#define MAYBE_CursorDeviceScaleFactorSwapPrimary \
597    DISABLED_CursorDeviceScaleFactorSwapPrimary
598#else
599#define MAYBE_CursorDeviceScaleFactorSwapPrimary \
600    CursorDeviceScaleFactorSwapPrimary
601#endif
602TEST_F(DisplayControllerTest, MAYBE_CursorDeviceScaleFactorSwapPrimary) {
603  DisplayController* display_controller =
604      Shell::GetInstance()->display_controller();
605
606  UpdateDisplay("200x200,200x200*2");
607  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
608  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
609
610  aura::RootWindow* primary_root =
611      display_controller->GetRootWindowForDisplayId(primary_display.id());
612  aura::RootWindow* secondary_root =
613      display_controller->GetRootWindowForDisplayId(secondary_display.id());
614  EXPECT_NE(primary_root, secondary_root);
615
616  test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
617
618  EXPECT_EQ(1.0f,
619            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
620  primary_root->MoveCursorTo(gfx::Point(50, 50));
621  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
622  EXPECT_EQ(2.0f,
623            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
624  secondary_root->MoveCursorTo(gfx::Point(50, 50));
625  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
626
627  // Switch primary and secondary
628  display_controller->SetPrimaryDisplay(secondary_display);
629
630  // Cursor's device scale factor should be updated accroding to the swap of
631  // primary and secondary.
632  EXPECT_EQ(1.0f,
633            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
634  secondary_root->MoveCursorTo(gfx::Point(50, 50));
635  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
636  primary_root->MoveCursorTo(gfx::Point(50, 50));
637  EXPECT_EQ(2.0f,
638            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
639  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
640
641  // Deleting 2nd display.
642  UpdateDisplay("200x200");
643  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
644
645  // Cursor's device scale factor should be updated even without moving cursor.
646  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
647
648  primary_root->MoveCursorTo(gfx::Point(50, 50));
649  EXPECT_EQ(1.0f,
650            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
651  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
652}
653
654#if defined(OS_WIN)
655// TODO(oshima): On Windows, we don't update the origin/size right away.
656#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin
657#else
658#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin
659#endif
660
661TEST_F(DisplayControllerTest, MAYBE_UpdateDisplayWithHostOrigin) {
662  UpdateDisplay("100x200,300x400");
663  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
664  Shell::RootWindowList root_windows =
665      Shell::GetInstance()->GetAllRootWindows();
666  ASSERT_EQ(2U, root_windows.size());
667  EXPECT_EQ("1,1", root_windows[0]->GetHostOrigin().ToString());
668  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
669  // UpdateDisplay set the origin if it's not set.
670  EXPECT_NE("1,1", root_windows[1]->GetHostOrigin().ToString());
671  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
672
673  UpdateDisplay("100x200,200+300-300x400");
674  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
675  EXPECT_EQ("0,0", root_windows[0]->GetHostOrigin().ToString());
676  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
677  EXPECT_EQ("200,300", root_windows[1]->GetHostOrigin().ToString());
678  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
679
680  UpdateDisplay("400+500-200x300,300x400");
681  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
682  EXPECT_EQ("400,500", root_windows[0]->GetHostOrigin().ToString());
683  EXPECT_EQ("200x300", root_windows[0]->GetHostSize().ToString());
684  EXPECT_EQ("0,0", root_windows[1]->GetHostOrigin().ToString());
685  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
686
687  UpdateDisplay("100+200-100x200,300+500-200x300");
688  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
689  EXPECT_EQ("100,200", root_windows[0]->GetHostOrigin().ToString());
690  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
691  EXPECT_EQ("300,500", root_windows[1]->GetHostOrigin().ToString());
692  EXPECT_EQ("200x300", root_windows[1]->GetHostSize().ToString());
693}
694
695#if defined(OS_WIN)
696// TODO(oshima): Windows does not supoprts insets.
697#define MAYBE_OverscanInsets DISABLED_OverscanInsets
698#else
699#define MAYBE_OverscanInsets OverscanInsets
700#endif
701
702TEST_F(DisplayControllerTest, MAYBE_OverscanInsets) {
703  DisplayController* display_controller =
704      Shell::GetInstance()->display_controller();
705  TestEventHandler event_handler;
706  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
707
708  UpdateDisplay("120x200,300x400*2");
709  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
710  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
711
712  display_controller->SetOverscanInsets(display1.id(),
713                                        gfx::Insets(10, 15, 20, 25));
714  EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
715  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
716  EXPECT_EQ("80,0 150x200",
717            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
718
719  aura::test::EventGenerator generator(root_windows[0]);
720  generator.MoveMouseToInHost(20, 25);
721  EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
722
723  display_controller->ClearCustomOverscanInsets(display1.id());
724  EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
725  EXPECT_EQ("120,0 150x200",
726            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
727
728  generator.MoveMouseToInHost(30, 20);
729  EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
730
731  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
732}
733
734#if defined(OS_WIN)
735// On Win8 bots, the host window can't be resized and
736// SetTransform updates the window using the orignal host window
737// size.
738#define MAYBE_Rotate DISABLED_Rotate
739#define MAYBE_ScaleRootWindow DISABLED_ScaleRootWindow
740#define MAYBE_TouchScale DISABLED_TouchScale
741#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords
742#else
743#define MAYBE_Rotate Rotate
744#define MAYBE_ScaleRootWindow ScaleRootWindow
745#define MAYBE_TouchScale TouchScale
746#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords
747#endif
748
749TEST_F(DisplayControllerTest, MAYBE_Rotate) {
750  DisplayController* display_controller =
751      Shell::GetInstance()->display_controller();
752  internal::DisplayManager* display_manager =
753      Shell::GetInstance()->display_manager();
754  TestEventHandler event_handler;
755  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
756
757  UpdateDisplay("120x200,300x400*2");
758  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
759  int64 display2_id = ScreenAsh::GetSecondaryDisplay().id();
760  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
761  aura::test::EventGenerator generator1(root_windows[0]);
762
763  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
764  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
765  EXPECT_EQ("120,0 150x200",
766            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
767  generator1.MoveMouseToInHost(50, 40);
768  EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
769  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
770  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
771
772  display_manager->SetDisplayRotation(display1.id(),
773                                      gfx::Display::ROTATE_90);
774  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
775  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
776  EXPECT_EQ("200,0 150x200",
777            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
778  generator1.MoveMouseToInHost(50, 40);
779  EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
780  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
781  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
782
783  DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
784  display_controller->SetLayoutForCurrentDisplays(display_layout);
785  EXPECT_EQ("50,120 150x200",
786            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
787
788  display_manager->SetDisplayRotation(display2_id,
789                                      gfx::Display::ROTATE_270);
790  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
791  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
792  EXPECT_EQ("50,120 200x150",
793            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
794  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
795  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
796
797  aura::test::EventGenerator generator2(root_windows[1]);
798  generator2.MoveMouseToInHost(50, 40);
799  EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
800  display_manager->SetDisplayRotation(display1.id(),
801                                      gfx::Display::ROTATE_180);
802
803  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
804  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
805  // Dislay must share at least 100, so the x's offset becomes 20.
806  EXPECT_EQ("20,200 200x150",
807            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
808  EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
809  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
810
811  generator1.MoveMouseToInHost(50, 40);
812  EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
813
814  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
815}
816
817TEST_F(DisplayControllerTest, MAYBE_ScaleRootWindow) {
818  TestEventHandler event_handler;
819  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
820
821  UpdateDisplay("600x400*2@1.5,500x300");
822
823  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
824  gfx::Display::SetInternalDisplayId(display1.id());
825
826  gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
827  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
828  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
829  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
830  EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
831  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
832  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
833
834  aura::test::EventGenerator generator(root_windows[0]);
835  generator.MoveMouseToInHost(599, 200);
836  EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
837
838  internal::DisplayManager* display_manager =
839      Shell::GetInstance()->display_manager();
840  display_manager->SetDisplayUIScale(display1.id(), 1.25f);
841  display1 = Shell::GetScreen()->GetPrimaryDisplay();
842  display2 = ScreenAsh::GetSecondaryDisplay();
843  EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
844  EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
845  EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
846  EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
847  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
848
849  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
850}
851
852TEST_F(DisplayControllerTest, MAYBE_TouchScale) {
853  TestEventHandler event_handler;
854  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
855
856  UpdateDisplay("200x200*2");
857  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
858  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
859  aura::RootWindow* root_window = root_windows[0];
860  aura::test::EventGenerator generator(root_window);
861
862  generator.PressMoveAndReleaseTouchTo(50, 50);
863  // Default test touches have radius_x/y = 1.0, with device scale
864  // factor = 2, the scaled radius_x/y should be 0.5.
865  EXPECT_EQ(0.5, event_handler.touch_radius_x());
866  EXPECT_EQ(0.5, event_handler.touch_radius_y());
867
868  generator.ScrollSequence(gfx::Point(0,0),
869                           base::TimeDelta::FromMilliseconds(100),
870                           10.0, 1.0, 5, 1);
871
872  // With device scale factor = 2, ordinal_offset * 2 = offset.
873  EXPECT_EQ(event_handler.scroll_x_offset(),
874            event_handler.scroll_x_offset_ordinal() * 2);
875  EXPECT_EQ(event_handler.scroll_y_offset(),
876            event_handler.scroll_y_offset_ordinal() * 2);
877
878  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
879}
880
881TEST_F(DisplayControllerTest, MAYBE_ConvertHostToRootCoords) {
882  TestEventHandler event_handler;
883  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
884
885  UpdateDisplay("600x400*2/r@1.5");
886
887  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
888  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
889  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
890  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
891  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
892
893  aura::test::EventGenerator generator(root_windows[0]);
894  generator.MoveMouseToInHost(0, 0);
895  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
896  generator.MoveMouseToInHost(599, 0);
897  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
898  generator.MoveMouseToInHost(599, 399);
899  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
900  generator.MoveMouseToInHost(0, 399);
901  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
902
903  UpdateDisplay("600x400*2/u@1.5");
904  display1 = Shell::GetScreen()->GetPrimaryDisplay();
905  root_windows = Shell::GetAllRootWindows();
906  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
907  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
908  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
909
910  generator.MoveMouseToInHost(0, 0);
911  EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
912  generator.MoveMouseToInHost(599, 0);
913  EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
914  generator.MoveMouseToInHost(599, 399);
915  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
916  generator.MoveMouseToInHost(0, 399);
917  EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
918
919  UpdateDisplay("600x400*2/l@1.5");
920  display1 = Shell::GetScreen()->GetPrimaryDisplay();
921  root_windows = Shell::GetAllRootWindows();
922  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
923  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
924  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
925
926  generator.MoveMouseToInHost(0, 0);
927  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
928  generator.MoveMouseToInHost(599, 0);
929  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
930  generator.MoveMouseToInHost(599, 399);
931  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
932  generator.MoveMouseToInHost(0, 399);
933  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
934
935  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
936}
937
938}  // namespace test
939}  // namespace ash
940