display_controller_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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_controller.h"
6
7#include "ash/display/display_info.h"
8#include "ash/display/display_manager.h"
9#include "ash/launcher/launcher.h"
10#include "ash/screen_ash.h"
11#include "ash/shelf/shelf_widget.h"
12#include "ash/shell.h"
13#include "ash/test/ash_test_base.h"
14#include "ash/test/cursor_manager_test_api.h"
15#include "ui/aura/env.h"
16#include "ui/aura/root_window.h"
17#include "ui/aura/test/event_generator.h"
18#include "ui/aura/window_tracker.h"
19#include "ui/base/events/event_handler.h"
20#include "ui/gfx/display.h"
21#include "ui/gfx/screen.h"
22#include "ui/views/widget/widget.h"
23
24namespace ash {
25namespace test {
26namespace {
27
28class TestObserver : public DisplayController::Observer {
29 public:
30  TestObserver() : changing_count_(0), changed_count_(0) {
31    Shell::GetInstance()->display_controller()->AddObserver(this);
32  }
33
34  virtual ~TestObserver() {
35    Shell::GetInstance()->display_controller()->RemoveObserver(this);
36  }
37
38  virtual void OnDisplayConfigurationChanging() OVERRIDE {
39    ++changing_count_;
40  }
41
42  virtual void OnDisplayConfigurationChanged() OVERRIDE {
43    ++changed_count_;
44  }
45
46  int CountAndReset() {
47    EXPECT_EQ(changing_count_, changed_count_);
48    int c = changing_count_;
49    changing_count_ = changed_count_ = 0;
50    return c;
51  }
52
53 private:
54  int changing_count_;
55  int changed_count_;
56
57  DISALLOW_COPY_AND_ASSIGN(TestObserver);
58};
59
60gfx::Display GetPrimaryDisplay() {
61  return Shell::GetScreen()->GetDisplayNearestWindow(
62      Shell::GetAllRootWindows()[0]);
63}
64
65gfx::Display GetSecondaryDisplay() {
66  return Shell::GetScreen()->GetDisplayNearestWindow(
67      Shell::GetAllRootWindows()[1]);
68}
69
70void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position,
71                                        int offset) {
72  DisplayController* display_controller =
73      Shell::GetInstance()->display_controller();
74  DisplayLayout layout = display_controller->default_display_layout();
75  layout.position = position;
76  layout.offset = offset;
77  display_controller->SetDefaultDisplayLayout(layout);
78}
79
80void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
81  SetSecondaryDisplayLayoutAndOffset(position, 0);
82}
83
84class DisplayControllerShutdownTest : public test::AshTestBase {
85 public:
86  virtual void TearDown() OVERRIDE {
87    test::AshTestBase::TearDown();
88    // Make sure that primary display is accessible after shutdown.
89    gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay();
90    EXPECT_EQ("0,0 444x333", primary.bounds().ToString());
91    EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
92  }
93};
94
95class TestEventHandler : public ui::EventHandler {
96 public:
97  TestEventHandler() : target_root_(NULL) {}
98  virtual ~TestEventHandler() {}
99
100  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
101    aura::Window* target = static_cast<aura::Window*>(event->target());
102    // Only record when the target is the background which covers
103    // entire root window.
104    if (target->name() != "DesktopBackgroundView")
105      return;
106    mouse_location_ = event->location();
107    target_root_ = target->GetRootWindow();
108    event->StopPropagation();
109  }
110
111  std::string GetLocationAndReset() {
112    std::string result = mouse_location_.ToString();
113    mouse_location_.SetPoint(0, 0);
114    target_root_ = NULL;
115    return result;
116  }
117
118 private:
119  gfx::Point mouse_location_;
120  aura::RootWindow* target_root_;
121
122  DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
123};
124
125gfx::Display::Rotation GetStoredRotation(int64 id) {
126  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
127}
128
129float GetStoredUIScale(int64 id) {
130  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).ui_scale();
131}
132
133}  // namespace
134
135typedef test::AshTestBase DisplayControllerTest;
136
137TEST_F(DisplayControllerShutdownTest, Shutdown) {
138  UpdateDisplay("444x333, 200x200");
139}
140
141TEST_F(DisplayControllerTest, SecondaryDisplayLayout) {
142  TestObserver observer;
143  UpdateDisplay("500x500,400x400");
144  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
145  gfx::Display* secondary_display =
146      Shell::GetInstance()->display_manager()->GetDisplayAt(1);
147  gfx::Insets insets(5, 5, 5, 5);
148  secondary_display->UpdateWorkAreaFromInsets(insets);
149
150  // Default layout is RIGHT.
151  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
152  EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
153  EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
154
155  // Layout the secondary display to the bottom of the primary.
156  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
157  EXPECT_EQ(1, observer.CountAndReset());
158  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
159  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
160  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
161
162  // Layout the secondary display to the left of the primary.
163  SetSecondaryDisplayLayout(DisplayLayout::LEFT);
164  EXPECT_EQ(1, observer.CountAndReset());
165  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
166  EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
167  EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
168
169  // Layout the secondary display to the top of the primary.
170  SetSecondaryDisplayLayout(DisplayLayout::TOP);
171  EXPECT_EQ(1, observer.CountAndReset());
172  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
173  EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
174  EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
175
176  // Layout to the right with an offset.
177  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300);
178  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
179  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
180  EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
181
182  // Keep the minimum 100.
183  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490);
184  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
185  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
186  EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
187
188  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400);
189  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
190  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
191  EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
192
193  //  Layout to the bottom with an offset.
194  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200);
195  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
196  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
197  EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
198
199  // Keep the minimum 100.
200  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490);
201  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
202  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
203  EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
204
205  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
206  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
207  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
208  EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
209}
210
211TEST_F(DisplayControllerTest, BoundsUpdated) {
212  TestObserver observer;
213  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
214  UpdateDisplay("200x200,300x300");  // layout, resize and add.
215  EXPECT_EQ(2, observer.CountAndReset());
216
217  internal::DisplayManager* display_manager =
218      Shell::GetInstance()->display_manager();
219  gfx::Display* secondary_display = display_manager->GetDisplayAt(1);
220  gfx::Insets insets(5, 5, 5, 5);
221  secondary_display->UpdateWorkAreaFromInsets(insets);
222
223  EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
224  EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
225  EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
226
227  UpdateDisplay("400x400,200x200");
228  EXPECT_EQ(1, observer.CountAndReset());  // two resizes
229  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
230  EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
231  if (!ash::Shell::IsLauncherPerDisplayEnabled())
232    EXPECT_EQ("5,405 190x190", GetSecondaryDisplay().work_area().ToString());
233
234  UpdateDisplay("400x400,300x300");
235  EXPECT_EQ(1, observer.CountAndReset());
236  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
237  EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
238  if (!ash::Shell::IsLauncherPerDisplayEnabled())
239    EXPECT_EQ("5,405 290x290", GetSecondaryDisplay().work_area().ToString());
240
241  UpdateDisplay("400x400");
242  EXPECT_EQ(1, observer.CountAndReset());
243  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
244  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
245
246  UpdateDisplay("400x500,700x700*2");
247  EXPECT_EQ(1, observer.CountAndReset());
248  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
249  EXPECT_EQ("0,0 400x500", GetPrimaryDisplay().bounds().ToString());
250  EXPECT_EQ("0,500 350x350", GetSecondaryDisplay().bounds().ToString());
251
252  // No change
253  UpdateDisplay("400x500,700x700*2");
254  EXPECT_EQ(0, observer.CountAndReset());
255
256  // Rotation
257  int64 primary_id = GetPrimaryDisplay().id();
258  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
259  EXPECT_EQ(1, observer.CountAndReset());
260  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
261  EXPECT_EQ(0, observer.CountAndReset());
262
263  // UI scale
264  int64 secondary_id = GetSecondaryDisplay().id();
265  gfx::Display::SetInternalDisplayId(secondary_id);
266  display_manager->SetDisplayUIScale(secondary_id, 1.25f);
267  EXPECT_EQ(1, observer.CountAndReset());
268  display_manager->SetDisplayUIScale(secondary_id, 1.25f);
269  EXPECT_EQ(0, observer.CountAndReset());
270}
271
272TEST_F(DisplayControllerTest, MirroredLayout) {
273  DisplayController* display_controller =
274      Shell::GetInstance()->display_controller();
275  UpdateDisplay("500x500,400x400");
276  EXPECT_FALSE(display_controller->GetCurrentDisplayLayout().mirrored);
277  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
278  EXPECT_EQ(
279      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
280
281  UpdateDisplay("500x500,1+0-500x500");
282  EXPECT_TRUE(display_controller->GetCurrentDisplayLayout().mirrored);
283  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
284  EXPECT_EQ(
285      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
286
287  UpdateDisplay("500x500,500x500");
288  EXPECT_FALSE(display_controller->GetCurrentDisplayLayout().mirrored);
289  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
290  EXPECT_EQ(
291      2U, Shell::GetInstance()->display_manager()->num_connected_displays());
292}
293
294TEST_F(DisplayControllerTest, InvertLayout) {
295  EXPECT_EQ("left, 0",
296            DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString());
297  EXPECT_EQ("left, -100",
298            DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString());
299  EXPECT_EQ("left, 50",
300            DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString());
301
302  EXPECT_EQ("right, 0",
303            DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString());
304  EXPECT_EQ("right, -90",
305            DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString());
306  EXPECT_EQ("right, 60",
307            DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString());
308
309  EXPECT_EQ("bottom, 0",
310            DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString());
311  EXPECT_EQ("bottom, -80",
312            DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString());
313  EXPECT_EQ("bottom, 70",
314            DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString());
315
316  EXPECT_EQ("top, 0",
317            DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString());
318  EXPECT_EQ("top, -70",
319            DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString());
320  EXPECT_EQ("top, 80",
321            DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
322}
323
324TEST_F(DisplayControllerTest, SwapPrimary) {
325  DisplayController* display_controller =
326      Shell::GetInstance()->display_controller();
327
328  UpdateDisplay("200x200,300x300");
329  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
330  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
331
332  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
333  display_controller->SetLayoutForCurrentDisplays(display_layout);
334
335  EXPECT_NE(primary_display.id(), secondary_display.id());
336  aura::RootWindow* primary_root =
337      display_controller->GetRootWindowForDisplayId(primary_display.id());
338  aura::RootWindow* secondary_root =
339      display_controller->GetRootWindowForDisplayId(secondary_display.id());
340  EXPECT_NE(primary_root, secondary_root);
341  aura::Window* launcher_window =
342      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
343  EXPECT_TRUE(primary_root->Contains(launcher_window));
344  EXPECT_FALSE(secondary_root->Contains(launcher_window));
345  EXPECT_EQ(primary_display.id(),
346            Shell::GetScreen()->GetDisplayNearestPoint(
347                gfx::Point(-100, -100)).id());
348  EXPECT_EQ(primary_display.id(),
349            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
350
351  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
352  EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString());
353  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
354  if (ash::Shell::IsLauncherPerDisplayEnabled())
355    EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString());
356  else
357    EXPECT_EQ("200,0 300x300", secondary_display.work_area().ToString());
358  EXPECT_EQ("right, 50",
359            display_controller->GetCurrentDisplayLayout().ToString());
360
361  // Switch primary and secondary
362  display_controller->SetPrimaryDisplay(secondary_display);
363  const DisplayLayout& inverted_layout =
364      display_controller->GetCurrentDisplayLayout();
365  EXPECT_EQ("left, -50", inverted_layout.ToString());
366
367  EXPECT_EQ(secondary_display.id(),
368      Shell::GetScreen()->GetPrimaryDisplay().id());
369  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
370  EXPECT_EQ(secondary_display.id(),
371            Shell::GetScreen()->GetDisplayNearestPoint(
372                gfx::Point(-100, -100)).id());
373  EXPECT_EQ(secondary_display.id(),
374            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
375
376  EXPECT_EQ(
377      primary_root,
378      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
379  EXPECT_EQ(
380      secondary_root,
381      display_controller->GetRootWindowForDisplayId(primary_display.id()));
382  EXPECT_TRUE(primary_root->Contains(launcher_window));
383  EXPECT_FALSE(secondary_root->Contains(launcher_window));
384
385  // Test if the bounds are correctly swapped.
386  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
387  gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay();
388  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
389  EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString());
390  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
391
392  if (ash::Shell::IsLauncherPerDisplayEnabled())
393    EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString());
394  else
395    EXPECT_EQ("-200,-50 200x200", swapped_secondary.work_area().ToString());
396
397  aura::WindowTracker tracker;
398  tracker.Add(primary_root);
399  tracker.Add(secondary_root);
400
401  // Deleting 2nd display should move the primary to original primary display.
402  UpdateDisplay("200x200");
403  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
404  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
405  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
406  EXPECT_EQ(primary_display.id(),
407            Shell::GetScreen()->GetDisplayNearestPoint(
408                gfx::Point(-100, -100)).id());
409  EXPECT_EQ(primary_display.id(),
410            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
411  EXPECT_TRUE(tracker.Contains(primary_root));
412  EXPECT_FALSE(tracker.Contains(secondary_root));
413  EXPECT_TRUE(primary_root->Contains(launcher_window));
414}
415
416TEST_F(DisplayControllerTest, SwapPrimaryById) {
417  DisplayController* display_controller =
418      Shell::GetInstance()->display_controller();
419
420  UpdateDisplay("200x200,300x300");
421  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
422  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
423
424  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
425  display_controller->SetLayoutForCurrentDisplays(display_layout);
426
427  EXPECT_NE(primary_display.id(), secondary_display.id());
428  aura::RootWindow* primary_root =
429      display_controller->GetRootWindowForDisplayId(primary_display.id());
430  aura::RootWindow* secondary_root =
431      display_controller->GetRootWindowForDisplayId(secondary_display.id());
432  aura::Window* launcher_window =
433      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
434  EXPECT_TRUE(primary_root->Contains(launcher_window));
435  EXPECT_FALSE(secondary_root->Contains(launcher_window));
436  EXPECT_NE(primary_root, secondary_root);
437  EXPECT_EQ(primary_display.id(),
438            Shell::GetScreen()->GetDisplayNearestPoint(
439                gfx::Point(-100, -100)).id());
440  EXPECT_EQ(primary_display.id(),
441            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
442
443  // Switch primary and secondary by display ID.
444  TestObserver observer;
445  display_controller->SetPrimaryDisplayId(secondary_display.id());
446  EXPECT_EQ(secondary_display.id(),
447            Shell::GetScreen()->GetPrimaryDisplay().id());
448  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
449  EXPECT_LT(0, observer.CountAndReset());
450
451  EXPECT_EQ(
452      primary_root,
453      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
454  EXPECT_EQ(
455      secondary_root,
456      display_controller->GetRootWindowForDisplayId(primary_display.id()));
457  EXPECT_TRUE(primary_root->Contains(launcher_window));
458  EXPECT_FALSE(secondary_root->Contains(launcher_window));
459
460  const DisplayLayout& inverted_layout =
461      display_controller->GetCurrentDisplayLayout();
462
463  EXPECT_EQ("left, -50", inverted_layout.ToString());
464
465  // Calling the same ID don't do anything.
466  display_controller->SetPrimaryDisplayId(secondary_display.id());
467  EXPECT_EQ(0, observer.CountAndReset());
468
469  aura::WindowTracker tracker;
470  tracker.Add(primary_root);
471  tracker.Add(secondary_root);
472
473  // Deleting 2nd display should move the primary to original primary display.
474  UpdateDisplay("200x200");
475  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
476  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
477  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
478  EXPECT_EQ(primary_display.id(),
479            Shell::GetScreen()->GetDisplayNearestPoint(
480                gfx::Point(-100, -100)).id());
481  EXPECT_EQ(primary_display.id(),
482            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
483  EXPECT_TRUE(tracker.Contains(primary_root));
484  EXPECT_FALSE(tracker.Contains(secondary_root));
485  EXPECT_TRUE(primary_root->Contains(launcher_window));
486
487  internal::DisplayManager* display_manager =
488      Shell::GetInstance()->display_manager();
489  // Adding 2nd display with the same ID.  The 2nd display should become primary
490  // since secondary id is still stored as desirable_primary_id.
491  std::vector<internal::DisplayInfo> display_info_list;
492  display_info_list.push_back(
493      display_manager->GetDisplayInfo(primary_display.id()));
494  display_info_list.push_back(
495      display_manager->GetDisplayInfo(secondary_display.id()));
496  display_manager->OnNativeDisplaysChanged(display_info_list);
497
498  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
499  EXPECT_EQ(secondary_display.id(),
500            Shell::GetScreen()->GetPrimaryDisplay().id());
501  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
502  EXPECT_EQ(
503      primary_root,
504      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
505  EXPECT_NE(
506      primary_root,
507      display_controller->GetRootWindowForDisplayId(primary_display.id()));
508  EXPECT_TRUE(primary_root->Contains(launcher_window));
509
510  // Deleting 2nd display and adding 2nd display with a different ID.  The 2nd
511  // display shouldn't become primary.
512  UpdateDisplay("200x200");
513  internal::DisplayInfo third_display_info(
514      secondary_display.id() + 1, std::string(), false);
515  third_display_info.SetBounds(secondary_display.bounds());
516  ASSERT_NE(primary_display.id(), third_display_info.id());
517
518  const internal::DisplayInfo& primary_display_info =
519      display_manager->GetDisplayInfo(primary_display.id());
520  std::vector<internal::DisplayInfo> display_info_list2;
521  display_info_list2.push_back(primary_display_info);
522  display_info_list2.push_back(third_display_info);
523  display_manager->OnNativeDisplaysChanged(display_info_list2);
524  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
525  EXPECT_EQ(primary_display.id(),
526            Shell::GetScreen()->GetPrimaryDisplay().id());
527  EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id());
528  EXPECT_EQ(
529      primary_root,
530      display_controller->GetRootWindowForDisplayId(primary_display.id()));
531  EXPECT_NE(
532      primary_root,
533      display_controller->GetRootWindowForDisplayId(third_display_info.id()));
534  EXPECT_TRUE(primary_root->Contains(launcher_window));
535}
536
537TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) {
538  DisplayController* display_controller =
539      Shell::GetInstance()->display_controller();
540
541  UpdateDisplay("200x200,200x200*2");
542  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
543  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
544
545  aura::RootWindow* primary_root =
546      display_controller->GetRootWindowForDisplayId(primary_display.id());
547  aura::RootWindow* secondary_root =
548      display_controller->GetRootWindowForDisplayId(secondary_display.id());
549  EXPECT_NE(primary_root, secondary_root);
550
551  test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
552
553  EXPECT_EQ(1.0f,
554            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
555  primary_root->MoveCursorTo(gfx::Point(50, 50));
556  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
557  EXPECT_EQ(2.0f,
558            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
559  secondary_root->MoveCursorTo(gfx::Point(50, 50));
560  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
561
562  // Switch primary and secondary
563  display_controller->SetPrimaryDisplay(secondary_display);
564
565  // Cursor's device scale factor should be updated accroding to the swap of
566  // primary and secondary.
567  EXPECT_EQ(1.0f,
568            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
569  secondary_root->MoveCursorTo(gfx::Point(50, 50));
570  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
571  primary_root->MoveCursorTo(gfx::Point(50, 50));
572  EXPECT_EQ(2.0f,
573            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
574  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
575
576  // Deleting 2nd display.
577  UpdateDisplay("200x200");
578  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
579
580  // Cursor's device scale factor should be updated even without moving cursor.
581  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
582
583  primary_root->MoveCursorTo(gfx::Point(50, 50));
584  EXPECT_EQ(1.0f,
585            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
586  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
587}
588
589#if defined(OS_WIN)
590// TODO(oshima): On Windows, we don't update the origin/size right away.
591#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin
592#else
593#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin
594#endif
595
596TEST_F(DisplayControllerTest, MAYBE_UpdateDisplayWithHostOrigin) {
597  UpdateDisplay("100x200,300x400");
598  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
599  Shell::RootWindowList root_windows =
600      Shell::GetInstance()->GetAllRootWindows();
601  ASSERT_EQ(2U, root_windows.size());
602  EXPECT_EQ("1,1", root_windows[0]->GetHostOrigin().ToString());
603  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
604  // UpdateDisplay set the origin if it's not set.
605  EXPECT_NE("1,1", root_windows[1]->GetHostOrigin().ToString());
606  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
607
608  UpdateDisplay("100x200,200+300-300x400");
609  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
610  EXPECT_EQ("0,0", root_windows[0]->GetHostOrigin().ToString());
611  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
612  EXPECT_EQ("200,300", root_windows[1]->GetHostOrigin().ToString());
613  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
614
615  UpdateDisplay("400+500-200x300,300x400");
616  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
617  EXPECT_EQ("400,500", root_windows[0]->GetHostOrigin().ToString());
618  EXPECT_EQ("200x300", root_windows[0]->GetHostSize().ToString());
619  EXPECT_EQ("0,0", root_windows[1]->GetHostOrigin().ToString());
620  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
621
622  UpdateDisplay("100+200-100x200,300+500-200x300");
623  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
624  EXPECT_EQ("100,200", root_windows[0]->GetHostOrigin().ToString());
625  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
626  EXPECT_EQ("300,500", root_windows[1]->GetHostOrigin().ToString());
627  EXPECT_EQ("200x300", root_windows[1]->GetHostSize().ToString());
628}
629
630#if defined(OS_WIN)
631// TODO(oshima): Windows does not supoprts insets.
632#define MAYBE_OverscanInsets DISABLED_OverscanInsets
633#else
634#define MAYBE_OverscanInsets OverscanInsets
635#endif
636
637TEST_F(DisplayControllerTest, MAYBE_OverscanInsets) {
638  DisplayController* display_controller =
639      Shell::GetInstance()->display_controller();
640  TestEventHandler event_handler;
641  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
642
643  UpdateDisplay("120x200,300x400*2");
644  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
645  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
646
647  display_controller->SetOverscanInsets(display1.id(),
648                                        gfx::Insets(10, 15, 20, 25));
649  EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
650  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
651  EXPECT_EQ("80,0 150x200",
652            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
653
654  aura::test::EventGenerator generator(root_windows[0]);
655  generator.MoveMouseTo(20, 25);
656  EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
657
658  display_controller->ClearCustomOverscanInsets(display1.id());
659  EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
660  EXPECT_EQ("120,0 150x200",
661            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
662
663  generator.MoveMouseTo(30, 20);
664  EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
665
666  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
667}
668
669#if defined(OS_WIN)
670// On Win8 bots, the host window can't be resized and
671// SetTransform updates the window using the orignal host window
672// size.
673#define MAYBE_Rotate DISABLED_Rotate
674#else
675#define MAYBE_Rotate Rotate
676#endif
677
678TEST_F(DisplayControllerTest, MAYBE_Rotate) {
679  DisplayController* display_controller =
680      Shell::GetInstance()->display_controller();
681  internal::DisplayManager* display_manager =
682      Shell::GetInstance()->display_manager();
683  TestEventHandler event_handler;
684  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
685
686  UpdateDisplay("120x200,300x400*2");
687  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
688  int64 display2_id = ScreenAsh::GetSecondaryDisplay().id();
689  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
690  aura::test::EventGenerator generator1(root_windows[0]);
691
692  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
693  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
694  EXPECT_EQ("120,0 150x200",
695            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
696  generator1.MoveMouseTo(50, 40);
697  EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
698  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
699  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
700
701  display_manager->SetDisplayRotation(display1.id(),
702                                      gfx::Display::ROTATE_90);
703  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
704  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
705  EXPECT_EQ("200,0 150x200",
706            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
707  generator1.MoveMouseTo(50, 40);
708  EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
709  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
710  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
711
712  DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
713  display_controller->SetLayoutForCurrentDisplays(display_layout);
714  EXPECT_EQ("50,120 150x200",
715            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
716
717  display_manager->SetDisplayRotation(display2_id,
718                                      gfx::Display::ROTATE_270);
719  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
720  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
721  EXPECT_EQ("50,120 200x150",
722            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
723  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
724  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
725
726  aura::test::EventGenerator generator2(root_windows[1]);
727  generator2.MoveMouseTo(50, 40);
728  EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
729  display_manager->SetDisplayRotation(display1.id(),
730                                      gfx::Display::ROTATE_180);
731
732  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
733  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
734  // Dislay must share at least 100, so the x's offset becomes 20.
735  EXPECT_EQ("20,200 200x150",
736            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
737  EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
738  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
739
740  generator1.MoveMouseTo(50, 40);
741  EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
742
743  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
744}
745
746#if defined(OS_WIN)
747// On Win8 bots, the host window can't be resized and
748// SetTransform updates the window using the orignal host window
749// size.
750#define MAYBE_ScaleRootWindow DISABLED_ScaleRootWindow
751#else
752#define MAYBE_ScaleRootWindow ScaleRootWindow
753#endif
754
755TEST_F(DisplayControllerTest, MAYBE_ScaleRootWindow) {
756  TestEventHandler event_handler;
757  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
758
759  UpdateDisplay("600x400*2@1.5,500x300");
760
761  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
762  gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
763  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
764  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
765  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
766  EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
767  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
768  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
769
770  aura::test::EventGenerator generator(root_windows[0]);
771  generator.MoveMouseTo(599, 200);
772  EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
773
774  internal::DisplayManager* display_manager =
775      Shell::GetInstance()->display_manager();
776  display_manager->SetDisplayUIScale(display1.id(), 1.25);
777  display1 = Shell::GetScreen()->GetPrimaryDisplay();
778  display2 = ScreenAsh::GetSecondaryDisplay();
779  EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
780  EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
781  EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
782  EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
783  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
784
785  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
786}
787
788}  // namespace test
789}  // namespace ash
790