display_controller_unittest.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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/ash_switches.h"
8#include "ash/display/display_info.h"
9#include "ash/display/display_layout_store.h"
10#include "ash/display/display_manager.h"
11#include "ash/launcher/launcher.h"
12#include "ash/screen_ash.h"
13#include "ash/shelf/shelf_widget.h"
14#include "ash/shell.h"
15#include "ash/test/ash_test_base.h"
16#include "ash/test/cursor_manager_test_api.h"
17#include "base/command_line.h"
18#include "ui/aura/env.h"
19#include "ui/aura/root_window.h"
20#include "ui/aura/test/event_generator.h"
21#include "ui/aura/window_tracker.h"
22#include "ui/base/events/event_handler.h"
23#include "ui/gfx/display.h"
24#include "ui/gfx/screen.h"
25#include "ui/views/widget/widget.h"
26
27#if defined(USE_X11)
28#include "ui/base/x/x11_util.h"
29#include <X11/Xlib.h>
30#undef RootWindow
31#endif
32
33namespace ash {
34namespace {
35
36const char kDesktopBackgroundView[] = "DesktopBackgroundView";
37
38class TestObserver : public DisplayController::Observer,
39                     public gfx::DisplayObserver {
40 public:
41  TestObserver()
42      : changing_count_(0),
43        changed_count_(0),
44        bounds_changed_count_(0),
45        changed_display_id_(0) {
46    Shell::GetInstance()->display_controller()->AddObserver(this);
47    Shell::GetScreen()->AddObserver(this);
48  }
49
50  virtual ~TestObserver() {
51    Shell::GetInstance()->display_controller()->RemoveObserver(this);
52    Shell::GetScreen()->RemoveObserver(this);
53  }
54
55  // Overridden from DisplayController::Observer
56  virtual void OnDisplayConfigurationChanging() OVERRIDE {
57    ++changing_count_;
58  }
59  virtual void OnDisplayConfigurationChanged() OVERRIDE {
60    ++changed_count_;
61  }
62
63  // Overrideen from gfx::DisplayObserver
64  virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
65    changed_display_id_ = display.id();
66    bounds_changed_count_ ++;
67  }
68  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
69  }
70  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
71  }
72
73  int CountAndReset() {
74    EXPECT_EQ(changing_count_, changed_count_);
75    int count = changing_count_;
76    changing_count_ = changed_count_ = 0;
77    return count;
78  }
79
80  int64 GetBoundsChangedCountAndReset() {
81    int count = bounds_changed_count_;
82    bounds_changed_count_ = 0;
83    return count;
84  }
85
86  int64 GetChangedDisplayIdAndReset() {
87    int64 id = changed_display_id_;
88    changed_display_id_ = 0;
89    return id;
90  }
91
92 private:
93  int changing_count_;
94  int changed_count_;
95
96  int bounds_changed_count_;
97  int64 changed_display_id_;
98
99  DISALLOW_COPY_AND_ASSIGN(TestObserver);
100};
101
102gfx::Display GetPrimaryDisplay() {
103  return Shell::GetScreen()->GetDisplayNearestWindow(
104      Shell::GetAllRootWindows()[0]);
105}
106
107gfx::Display GetSecondaryDisplay() {
108  return Shell::GetScreen()->GetDisplayNearestWindow(
109      Shell::GetAllRootWindows()[1]);
110}
111
112void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position,
113                                        int offset) {
114  DisplayLayout layout(position, offset);
115  ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
116  Shell::GetInstance()->display_controller()->
117      SetLayoutForCurrentDisplays(layout);
118}
119
120void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
121  SetSecondaryDisplayLayoutAndOffset(position, 0);
122}
123
124void SetDefaultDisplayLayout(DisplayLayout::Position position) {
125  Shell::GetInstance()->display_manager()->layout_store()->
126      SetDefaultDisplayLayout(DisplayLayout(position, 0));
127}
128
129class DisplayControllerShutdownTest : public test::AshTestBase {
130 public:
131  virtual void TearDown() OVERRIDE {
132    test::AshTestBase::TearDown();
133    if (!SupportsMultipleDisplays())
134      return;
135
136    // Make sure that primary display is accessible after shutdown.
137    gfx::Display primary = Shell::GetScreen()->GetPrimaryDisplay();
138    EXPECT_EQ("0,0 444x333", primary.bounds().ToString());
139    EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
140  }
141};
142
143class TestEventHandler : public ui::EventHandler {
144 public:
145  TestEventHandler() : target_root_(NULL),
146                       touch_radius_x_(0.0),
147                       touch_radius_y_(0.0),
148                       scroll_x_offset_(0.0),
149                       scroll_y_offset_(0.0),
150                       scroll_x_offset_ordinal_(0.0),
151                       scroll_y_offset_ordinal_(0.0) {}
152  virtual ~TestEventHandler() {}
153
154  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
155    if (event->flags() & ui::EF_IS_SYNTHESIZED &&
156        event->type() != ui::ET_MOUSE_EXITED &&
157        event->type() != ui::ET_MOUSE_ENTERED) {
158      return;
159    }
160    aura::Window* target = static_cast<aura::Window*>(event->target());
161    mouse_location_ = event->root_location();
162    target_root_ = target->GetRootWindow();
163    event->StopPropagation();
164  }
165
166  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
167    aura::Window* target = static_cast<aura::Window*>(event->target());
168    // Only record when the target is the background which covers
169    // entire root window.
170    if (target->name() != kDesktopBackgroundView)
171      return;
172    touch_radius_x_ = event->radius_x();
173    touch_radius_y_ = event->radius_y();
174    event->StopPropagation();
175  }
176
177  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
178    aura::Window* target = static_cast<aura::Window*>(event->target());
179    // Only record when the target is the background which covers
180    // entire root window.
181    if (target->name() != kDesktopBackgroundView)
182      return;
183
184    if (event->type() == ui::ET_SCROLL) {
185      scroll_x_offset_ = event->x_offset();
186      scroll_y_offset_ = event->y_offset();
187      scroll_x_offset_ordinal_ = event->x_offset_ordinal();
188      scroll_y_offset_ordinal_ = event->y_offset_ordinal();
189    }
190    event->StopPropagation();
191  }
192
193  std::string GetLocationAndReset() {
194    std::string result = mouse_location_.ToString();
195    mouse_location_.SetPoint(0, 0);
196    target_root_ = NULL;
197    return result;
198  }
199
200  float touch_radius_x() { return touch_radius_x_; }
201  float touch_radius_y() { return touch_radius_y_; }
202  float scroll_x_offset() { return scroll_x_offset_; }
203  float scroll_y_offset() { return scroll_y_offset_; }
204  float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; }
205  float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; }
206
207 private:
208  gfx::Point mouse_location_;
209  aura::RootWindow* target_root_;
210
211  float touch_radius_x_;
212  float touch_radius_y_;
213  float scroll_x_offset_;
214  float scroll_y_offset_;
215  float scroll_x_offset_ordinal_;
216  float scroll_y_offset_ordinal_;
217
218  DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
219};
220
221gfx::Display::Rotation GetStoredRotation(int64 id) {
222  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
223}
224
225float GetStoredUIScale(int64 id) {
226  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).ui_scale();
227}
228
229#if defined(USE_X11)
230void GetPrimaryAndSeconary(aura::RootWindow** primary,
231                           aura::RootWindow** secondary) {
232  *primary = Shell::GetPrimaryRootWindow();
233  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
234  *secondary = root_windows[0] == *primary ? root_windows[1] : root_windows[0];
235}
236
237std::string GetXWindowName(aura::RootWindow* window) {
238  char* name = NULL;
239  XFetchName(ui::GetXDisplay(), window->GetAcceleratedWidget(), &name);
240  std::string ret(name);
241  XFree(name);
242  return ret;
243}
244#endif
245
246}  // namespace
247
248typedef test::AshTestBase DisplayControllerTest;
249
250TEST_F(DisplayControllerShutdownTest, Shutdown) {
251  if (!SupportsMultipleDisplays())
252    return;
253
254  UpdateDisplay("444x333, 200x200");
255}
256
257TEST_F(DisplayControllerTest, SecondaryDisplayLayout) {
258  if (!SupportsMultipleDisplays())
259    return;
260
261  TestObserver observer;
262  UpdateDisplay("500x500,400x400");
263  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
264  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
265  gfx::Insets insets(5, 5, 5, 5);
266  int64 secondary_display_id = ScreenAsh::GetSecondaryDisplay().id();
267  Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay(
268      secondary_display_id, insets);
269
270  // Default layout is RIGHT.
271  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
272  EXPECT_EQ("500,0 400x400", GetSecondaryDisplay().bounds().ToString());
273  EXPECT_EQ("505,5 390x390", GetSecondaryDisplay().work_area().ToString());
274
275  // Layout the secondary display to the bottom of the primary.
276  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
277  EXPECT_EQ(1, observer.CountAndReset());
278  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
279  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
280  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
281  EXPECT_EQ("0,500 400x400", GetSecondaryDisplay().bounds().ToString());
282  EXPECT_EQ("5,505 390x390", GetSecondaryDisplay().work_area().ToString());
283
284  // Layout the secondary display to the left of the primary.
285  SetSecondaryDisplayLayout(DisplayLayout::LEFT);
286  EXPECT_EQ(1, observer.CountAndReset());
287  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
288  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
289  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
290  EXPECT_EQ("-400,0 400x400", GetSecondaryDisplay().bounds().ToString());
291  EXPECT_EQ("-395,5 390x390", GetSecondaryDisplay().work_area().ToString());
292
293  // Layout the secondary display to the top of the primary.
294  SetSecondaryDisplayLayout(DisplayLayout::TOP);
295  EXPECT_EQ(1, observer.CountAndReset());
296  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
297  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
298  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
299  EXPECT_EQ("0,-400 400x400", GetSecondaryDisplay().bounds().ToString());
300  EXPECT_EQ("5,-395 390x390", GetSecondaryDisplay().work_area().ToString());
301
302  // Layout to the right with an offset.
303  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 300);
304  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
305  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
306  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
307  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
308  EXPECT_EQ("500,300 400x400", GetSecondaryDisplay().bounds().ToString());
309
310  // Keep the minimum 100.
311  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, 490);
312  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
313  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
314  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
315  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
316  EXPECT_EQ("500,400 400x400", GetSecondaryDisplay().bounds().ToString());
317
318  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::RIGHT, -400);
319  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
320  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
321  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
322  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
323  EXPECT_EQ("500,-300 400x400", GetSecondaryDisplay().bounds().ToString());
324
325  //  Layout to the bottom with an offset.
326  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -200);
327  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
328  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
329  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
330  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
331  EXPECT_EQ("-200,500 400x400", GetSecondaryDisplay().bounds().ToString());
332
333  // Keep the minimum 100.
334  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, 490);
335  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
336  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
337  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
338  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
339  EXPECT_EQ("400,500 400x400", GetSecondaryDisplay().bounds().ToString());
340
341  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
342  EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
343  EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
344  EXPECT_EQ(1, observer.CountAndReset());  // resize and add
345  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
346  EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
347
348  // Setting the same layout shouldn't invoke observers.
349  SetSecondaryDisplayLayoutAndOffset(DisplayLayout::BOTTOM, -400);
350  EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
351  EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
352  EXPECT_EQ(0, observer.CountAndReset());  // resize and add
353  EXPECT_EQ("0,0 500x500", GetPrimaryDisplay().bounds().ToString());
354  EXPECT_EQ("-300,500 400x400", GetSecondaryDisplay().bounds().ToString());
355}
356
357TEST_F(DisplayControllerTest, BoundsUpdated) {
358  if (!SupportsMultipleDisplays())
359    return;
360
361  TestObserver observer;
362  SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
363  UpdateDisplay("200x200,300x300");  // layout, resize and add.
364  EXPECT_EQ(1, observer.CountAndReset());
365
366  internal::DisplayManager* display_manager =
367      Shell::GetInstance()->display_manager();
368  gfx::Insets insets(5, 5, 5, 5);
369  display_manager->UpdateWorkAreaOfDisplay(
370      ScreenAsh::GetSecondaryDisplay().id(), insets);
371
372  EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
373  EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
374  EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
375
376  UpdateDisplay("400x400,200x200");
377  EXPECT_EQ(1, observer.CountAndReset());  // two resizes
378  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
379  EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
380
381  UpdateDisplay("400x400,300x300");
382  EXPECT_EQ(1, observer.CountAndReset());
383  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
384  EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
385
386  UpdateDisplay("400x400");
387  EXPECT_EQ(1, observer.CountAndReset());
388  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
389  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
390
391  UpdateDisplay("400x500*2,300x300");
392  EXPECT_EQ(1, observer.CountAndReset());
393  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
394  EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
395  EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
396
397  // No change
398  UpdateDisplay("400x500*2,300x300");
399  EXPECT_EQ(0, observer.CountAndReset());
400
401  // Rotation
402  int64 primary_id = GetPrimaryDisplay().id();
403  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
404  EXPECT_EQ(1, observer.CountAndReset());
405  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
406  EXPECT_EQ(0, observer.CountAndReset());
407
408  // UI scale is eanbled only on internal display.
409  int64 secondary_id = GetSecondaryDisplay().id();
410  gfx::Display::SetInternalDisplayId(secondary_id);
411  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
412  EXPECT_EQ(1, observer.CountAndReset());
413  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
414  EXPECT_EQ(0, observer.CountAndReset());
415  display_manager->SetDisplayUIScale(primary_id, 1.125f);
416  EXPECT_EQ(0, observer.CountAndReset());
417  display_manager->SetDisplayUIScale(primary_id, 1.125f);
418  EXPECT_EQ(0, observer.CountAndReset());
419}
420
421TEST_F(DisplayControllerTest, InvertLayout) {
422  EXPECT_EQ("left, 0",
423            DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString());
424  EXPECT_EQ("left, -100",
425            DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString());
426  EXPECT_EQ("left, 50",
427            DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString());
428
429  EXPECT_EQ("right, 0",
430            DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString());
431  EXPECT_EQ("right, -90",
432            DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString());
433  EXPECT_EQ("right, 60",
434            DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString());
435
436  EXPECT_EQ("bottom, 0",
437            DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString());
438  EXPECT_EQ("bottom, -80",
439            DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString());
440  EXPECT_EQ("bottom, 70",
441            DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString());
442
443  EXPECT_EQ("top, 0",
444            DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString());
445  EXPECT_EQ("top, -70",
446            DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString());
447  EXPECT_EQ("top, 80",
448            DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
449}
450
451TEST_F(DisplayControllerTest, SwapPrimary) {
452  if (!SupportsMultipleDisplays())
453    return;
454
455  DisplayController* display_controller =
456      Shell::GetInstance()->display_controller();
457  internal::DisplayManager* display_manager =
458      Shell::GetInstance()->display_manager();
459
460  UpdateDisplay("200x200,300x300");
461  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
462  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
463
464  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
465  display_controller->SetLayoutForCurrentDisplays(display_layout);
466
467  EXPECT_NE(primary_display.id(), secondary_display.id());
468  aura::RootWindow* primary_root =
469      display_controller->GetRootWindowForDisplayId(primary_display.id());
470  aura::RootWindow* secondary_root =
471      display_controller->GetRootWindowForDisplayId(secondary_display.id());
472  EXPECT_NE(primary_root, secondary_root);
473  aura::Window* launcher_window =
474      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
475  EXPECT_TRUE(primary_root->Contains(launcher_window));
476  EXPECT_FALSE(secondary_root->Contains(launcher_window));
477  EXPECT_EQ(primary_display.id(),
478            Shell::GetScreen()->GetDisplayNearestPoint(
479                gfx::Point(-100, -100)).id());
480  EXPECT_EQ(primary_display.id(),
481            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
482
483  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
484  EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString());
485  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
486  EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString());
487  EXPECT_EQ("right, 50",
488            display_manager->GetCurrentDisplayLayout().ToString());
489
490  // Switch primary and secondary
491  display_controller->SetPrimaryDisplay(secondary_display);
492  const DisplayLayout& inverted_layout =
493      display_manager->GetCurrentDisplayLayout();
494  EXPECT_EQ("left, -50", inverted_layout.ToString());
495
496  EXPECT_EQ(secondary_display.id(),
497            Shell::GetScreen()->GetPrimaryDisplay().id());
498  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
499  EXPECT_EQ(secondary_display.id(),
500            Shell::GetScreen()->GetDisplayNearestPoint(
501                gfx::Point(-100, -100)).id());
502  EXPECT_EQ(secondary_display.id(),
503            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
504
505  EXPECT_EQ(
506      primary_root,
507      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
508  EXPECT_EQ(
509      secondary_root,
510      display_controller->GetRootWindowForDisplayId(primary_display.id()));
511  EXPECT_TRUE(primary_root->Contains(launcher_window));
512  EXPECT_FALSE(secondary_root->Contains(launcher_window));
513
514  // Test if the bounds are correctly swapped.
515  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
516  gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay();
517  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
518  EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString());
519  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
520
521  EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString());
522
523  aura::WindowTracker tracker;
524  tracker.Add(primary_root);
525  tracker.Add(secondary_root);
526
527  // Deleting 2nd display should move the primary to original primary display.
528  UpdateDisplay("200x200");
529  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
530  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
531  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
532  EXPECT_EQ(primary_display.id(),
533            Shell::GetScreen()->GetDisplayNearestPoint(
534                gfx::Point(-100, -100)).id());
535  EXPECT_EQ(primary_display.id(),
536            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
537  EXPECT_TRUE(tracker.Contains(primary_root));
538  EXPECT_FALSE(tracker.Contains(secondary_root));
539  EXPECT_TRUE(primary_root->Contains(launcher_window));
540}
541
542TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) {
543  if (!SupportsMultipleDisplays())
544    return;
545
546  CommandLine::ForCurrentProcess()->AppendSwitch(
547      ash::switches::kAshDisableAlternateShelfLayout);
548
549  DisplayController* display_controller =
550      Shell::GetInstance()->display_controller();
551  internal::DisplayManager* display_manager =
552      Shell::GetInstance()->display_manager();
553
554  UpdateDisplay("200x200,300x300");
555  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
556  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
557
558  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
559  display_controller->SetLayoutForCurrentDisplays(display_layout);
560
561  EXPECT_NE(primary_display.id(), secondary_display.id());
562  aura::RootWindow* primary_root =
563      display_controller->GetRootWindowForDisplayId(primary_display.id());
564  aura::RootWindow* secondary_root =
565      display_controller->GetRootWindowForDisplayId(secondary_display.id());
566  EXPECT_NE(primary_root, secondary_root);
567  aura::Window* launcher_window =
568      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
569  EXPECT_TRUE(primary_root->Contains(launcher_window));
570  EXPECT_FALSE(secondary_root->Contains(launcher_window));
571  EXPECT_EQ(primary_display.id(),
572            Shell::GetScreen()->GetDisplayNearestPoint(
573                gfx::Point(-100, -100)).id());
574  EXPECT_EQ(primary_display.id(),
575            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
576
577  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
578  EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString());
579  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
580  EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString());
581  EXPECT_EQ("right, 50",
582            display_manager->GetCurrentDisplayLayout().ToString());
583
584  // Switch primary and secondary
585  display_controller->SetPrimaryDisplay(secondary_display);
586  const DisplayLayout& inverted_layout =
587      display_manager->GetCurrentDisplayLayout();
588  EXPECT_EQ("left, -50", inverted_layout.ToString());
589
590  EXPECT_EQ(secondary_display.id(),
591            Shell::GetScreen()->GetPrimaryDisplay().id());
592  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
593  EXPECT_EQ(secondary_display.id(),
594            Shell::GetScreen()->GetDisplayNearestPoint(
595                gfx::Point(-100, -100)).id());
596  EXPECT_EQ(secondary_display.id(),
597            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
598
599  EXPECT_EQ(
600      primary_root,
601      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
602  EXPECT_EQ(
603      secondary_root,
604      display_controller->GetRootWindowForDisplayId(primary_display.id()));
605  EXPECT_TRUE(primary_root->Contains(launcher_window));
606  EXPECT_FALSE(secondary_root->Contains(launcher_window));
607
608  // Test if the bounds are correctly swapped.
609  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
610  gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay();
611  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
612  EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString());
613  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
614
615  EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString());
616
617  aura::WindowTracker tracker;
618  tracker.Add(primary_root);
619  tracker.Add(secondary_root);
620
621  // Deleting 2nd display should move the primary to original primary display.
622  UpdateDisplay("200x200");
623  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
624  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
625  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
626  EXPECT_EQ(primary_display.id(),
627            Shell::GetScreen()->GetDisplayNearestPoint(
628                gfx::Point(-100, -100)).id());
629  EXPECT_EQ(primary_display.id(),
630            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
631  EXPECT_TRUE(tracker.Contains(primary_root));
632  EXPECT_FALSE(tracker.Contains(secondary_root));
633  EXPECT_TRUE(primary_root->Contains(launcher_window));
634}
635
636TEST_F(DisplayControllerTest, SwapPrimaryById) {
637  if (!SupportsMultipleDisplays())
638    return;
639
640  DisplayController* display_controller =
641      Shell::GetInstance()->display_controller();
642  internal::DisplayManager* display_manager =
643      Shell::GetInstance()->display_manager();
644
645  UpdateDisplay("200x200,300x300");
646  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
647  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
648
649  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
650  display_controller->SetLayoutForCurrentDisplays(display_layout);
651
652  EXPECT_NE(primary_display.id(), secondary_display.id());
653  aura::RootWindow* primary_root =
654      display_controller->GetRootWindowForDisplayId(primary_display.id());
655  aura::RootWindow* secondary_root =
656      display_controller->GetRootWindowForDisplayId(secondary_display.id());
657  aura::Window* launcher_window =
658      Launcher::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
659  EXPECT_TRUE(primary_root->Contains(launcher_window));
660  EXPECT_FALSE(secondary_root->Contains(launcher_window));
661  EXPECT_NE(primary_root, secondary_root);
662  EXPECT_EQ(primary_display.id(),
663            Shell::GetScreen()->GetDisplayNearestPoint(
664                gfx::Point(-100, -100)).id());
665  EXPECT_EQ(primary_display.id(),
666            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
667
668  // Switch primary and secondary by display ID.
669  TestObserver observer;
670  display_controller->SetPrimaryDisplayId(secondary_display.id());
671  EXPECT_EQ(secondary_display.id(),
672            Shell::GetScreen()->GetPrimaryDisplay().id());
673  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
674  EXPECT_LT(0, observer.CountAndReset());
675
676  EXPECT_EQ(
677      primary_root,
678      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
679  EXPECT_EQ(
680      secondary_root,
681      display_controller->GetRootWindowForDisplayId(primary_display.id()));
682  EXPECT_TRUE(primary_root->Contains(launcher_window));
683  EXPECT_FALSE(secondary_root->Contains(launcher_window));
684
685  const DisplayLayout& inverted_layout =
686      display_manager->GetCurrentDisplayLayout();
687
688  EXPECT_EQ("left, -50", inverted_layout.ToString());
689
690  // Calling the same ID don't do anything.
691  display_controller->SetPrimaryDisplayId(secondary_display.id());
692  EXPECT_EQ(0, observer.CountAndReset());
693
694  aura::WindowTracker tracker;
695  tracker.Add(primary_root);
696  tracker.Add(secondary_root);
697
698  // Deleting 2nd display should move the primary to original primary display.
699  UpdateDisplay("200x200");
700  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
701  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
702  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
703  EXPECT_EQ(primary_display.id(),
704            Shell::GetScreen()->GetDisplayNearestPoint(
705                gfx::Point(-100, -100)).id());
706  EXPECT_EQ(primary_display.id(),
707            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
708  EXPECT_TRUE(tracker.Contains(primary_root));
709  EXPECT_FALSE(tracker.Contains(secondary_root));
710  EXPECT_TRUE(primary_root->Contains(launcher_window));
711
712  // Adding 2nd display with the same ID.  The 2nd display should become primary
713  // since secondary id is still stored as desirable_primary_id.
714  std::vector<internal::DisplayInfo> display_info_list;
715  display_info_list.push_back(
716      display_manager->GetDisplayInfo(primary_display.id()));
717  display_info_list.push_back(
718      display_manager->GetDisplayInfo(secondary_display.id()));
719  display_manager->OnNativeDisplaysChanged(display_info_list);
720
721  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
722  EXPECT_EQ(secondary_display.id(),
723            Shell::GetScreen()->GetPrimaryDisplay().id());
724  EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
725  EXPECT_EQ(
726      primary_root,
727      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
728  EXPECT_NE(
729      primary_root,
730      display_controller->GetRootWindowForDisplayId(primary_display.id()));
731  EXPECT_TRUE(primary_root->Contains(launcher_window));
732
733  // Deleting 2nd display and adding 2nd display with a different ID.  The 2nd
734  // display shouldn't become primary.
735  UpdateDisplay("200x200");
736  internal::DisplayInfo third_display_info(
737      secondary_display.id() + 1, std::string(), false);
738  third_display_info.SetBounds(secondary_display.bounds());
739  ASSERT_NE(primary_display.id(), third_display_info.id());
740
741  const internal::DisplayInfo& primary_display_info =
742      display_manager->GetDisplayInfo(primary_display.id());
743  std::vector<internal::DisplayInfo> display_info_list2;
744  display_info_list2.push_back(primary_display_info);
745  display_info_list2.push_back(third_display_info);
746  display_manager->OnNativeDisplaysChanged(display_info_list2);
747  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
748  EXPECT_EQ(primary_display.id(),
749            Shell::GetScreen()->GetPrimaryDisplay().id());
750  EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id());
751  EXPECT_EQ(
752      primary_root,
753      display_controller->GetRootWindowForDisplayId(primary_display.id()));
754  EXPECT_NE(
755      primary_root,
756      display_controller->GetRootWindowForDisplayId(third_display_info.id()));
757  EXPECT_TRUE(primary_root->Contains(launcher_window));
758}
759
760TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) {
761  if (!SupportsMultipleDisplays())
762    return;
763
764  DisplayController* display_controller =
765      Shell::GetInstance()->display_controller();
766
767  UpdateDisplay("200x200,200x200*2");
768  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
769  gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay();
770
771  aura::RootWindow* primary_root =
772      display_controller->GetRootWindowForDisplayId(primary_display.id());
773  aura::RootWindow* secondary_root =
774      display_controller->GetRootWindowForDisplayId(secondary_display.id());
775  EXPECT_NE(primary_root, secondary_root);
776
777  test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
778
779  EXPECT_EQ(1.0f,
780            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
781  primary_root->MoveCursorTo(gfx::Point(50, 50));
782  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
783  EXPECT_EQ(2.0f,
784            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
785  secondary_root->MoveCursorTo(gfx::Point(50, 50));
786  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
787
788  // Switch primary and secondary
789  display_controller->SetPrimaryDisplay(secondary_display);
790
791  // Cursor's device scale factor should be updated accroding to the swap of
792  // primary and secondary.
793  EXPECT_EQ(1.0f,
794            secondary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
795  secondary_root->MoveCursorTo(gfx::Point(50, 50));
796  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
797  primary_root->MoveCursorTo(gfx::Point(50, 50));
798  EXPECT_EQ(2.0f,
799            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
800  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
801
802  // Deleting 2nd display.
803  UpdateDisplay("200x200");
804  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
805
806  // Cursor's device scale factor should be updated even without moving cursor.
807  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
808
809  primary_root->MoveCursorTo(gfx::Point(50, 50));
810  EXPECT_EQ(1.0f,
811            primary_root->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
812  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
813}
814
815#if defined(OS_WIN)
816// TODO(scottmg): RootWindow doesn't get resized on Windows
817// Ash. http://crbug.com/247916.
818#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin
819#else
820#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin
821#endif
822
823TEST_F(DisplayControllerTest, MAYBE_UpdateDisplayWithHostOrigin) {
824  UpdateDisplay("100x200,300x400");
825  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
826  Shell::RootWindowList root_windows =
827      Shell::GetInstance()->GetAllRootWindows();
828  ASSERT_EQ(2U, root_windows.size());
829  EXPECT_EQ("1,1", root_windows[0]->GetHostOrigin().ToString());
830  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
831  // UpdateDisplay set the origin if it's not set.
832  EXPECT_NE("1,1", root_windows[1]->GetHostOrigin().ToString());
833  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
834
835  UpdateDisplay("100x200,200+300-300x400");
836  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
837  EXPECT_EQ("0,0", root_windows[0]->GetHostOrigin().ToString());
838  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
839  EXPECT_EQ("200,300", root_windows[1]->GetHostOrigin().ToString());
840  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
841
842  UpdateDisplay("400+500-200x300,300x400");
843  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
844  EXPECT_EQ("400,500", root_windows[0]->GetHostOrigin().ToString());
845  EXPECT_EQ("200x300", root_windows[0]->GetHostSize().ToString());
846  EXPECT_EQ("0,0", root_windows[1]->GetHostOrigin().ToString());
847  EXPECT_EQ("300x400", root_windows[1]->GetHostSize().ToString());
848
849  UpdateDisplay("100+200-100x200,300+500-200x300");
850  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
851  EXPECT_EQ("100,200", root_windows[0]->GetHostOrigin().ToString());
852  EXPECT_EQ("100x200", root_windows[0]->GetHostSize().ToString());
853  EXPECT_EQ("300,500", root_windows[1]->GetHostOrigin().ToString());
854  EXPECT_EQ("200x300", root_windows[1]->GetHostSize().ToString());
855}
856
857TEST_F(DisplayControllerTest, OverscanInsets) {
858  if (!SupportsMultipleDisplays())
859    return;
860
861  DisplayController* display_controller =
862      Shell::GetInstance()->display_controller();
863  TestEventHandler event_handler;
864  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
865
866  UpdateDisplay("120x200,300x400*2");
867  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
868  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
869
870  display_controller->SetOverscanInsets(display1.id(),
871                                        gfx::Insets(10, 15, 20, 25));
872  EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
873  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
874  EXPECT_EQ("80,0 150x200",
875            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
876
877  aura::test::EventGenerator generator(root_windows[0]);
878  generator.MoveMouseToInHost(20, 25);
879  EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
880
881  display_controller->SetOverscanInsets(display1.id(), gfx::Insets());
882  EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
883  EXPECT_EQ("120,0 150x200",
884            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
885
886  generator.MoveMouseToInHost(30, 20);
887  EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
888
889  // Make sure the root window transformer uses correct scale
890  // factor when swapping display. Test crbug.com/253690.
891  UpdateDisplay("400x300*2,600x400/o");
892  root_windows = Shell::GetAllRootWindows();
893  gfx::Point point;
894  Shell::GetAllRootWindows()[1]->GetRootTransform().TransformPoint(point);
895  EXPECT_EQ("15,10", point.ToString());
896
897  display_controller->SwapPrimaryDisplay();
898  point.SetPoint(0, 0);
899  Shell::GetAllRootWindows()[1]->GetRootTransform().TransformPoint(point);
900  EXPECT_EQ("15,10", point.ToString());
901
902  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
903}
904
905TEST_F(DisplayControllerTest, Rotate) {
906  if (!SupportsMultipleDisplays())
907    return;
908
909  DisplayController* display_controller =
910      Shell::GetInstance()->display_controller();
911  internal::DisplayManager* display_manager =
912      Shell::GetInstance()->display_manager();
913  TestEventHandler event_handler;
914  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
915
916  UpdateDisplay("120x200,300x400*2");
917  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
918  int64 display2_id = ScreenAsh::GetSecondaryDisplay().id();
919  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
920  aura::test::EventGenerator generator1(root_windows[0]);
921
922  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
923  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
924  EXPECT_EQ("120,0 150x200",
925            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
926  generator1.MoveMouseToInHost(50, 40);
927  EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
928  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
929  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
930
931  display_manager->SetDisplayRotation(display1.id(),
932                                      gfx::Display::ROTATE_90);
933  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
934  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
935  EXPECT_EQ("200,0 150x200",
936            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
937  generator1.MoveMouseToInHost(50, 40);
938  EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
939  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
940  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
941
942  DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
943  display_controller->SetLayoutForCurrentDisplays(display_layout);
944  EXPECT_EQ("50,120 150x200",
945            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
946
947  display_manager->SetDisplayRotation(display2_id,
948                                      gfx::Display::ROTATE_270);
949  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
950  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
951  EXPECT_EQ("50,120 200x150",
952            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
953  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
954  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
955
956#if !defined(OS_WIN)
957  aura::test::EventGenerator generator2(root_windows[1]);
958  generator2.MoveMouseToInHost(50, 40);
959  EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
960  display_manager->SetDisplayRotation(display1.id(),
961                                      gfx::Display::ROTATE_180);
962
963  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
964  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
965  // Dislay must share at least 100, so the x's offset becomes 20.
966  EXPECT_EQ("20,200 200x150",
967            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
968  EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
969  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
970
971  generator1.MoveMouseToInHost(50, 40);
972  EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
973#endif
974
975  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
976}
977
978TEST_F(DisplayControllerTest, ScaleRootWindow) {
979  if (!SupportsMultipleDisplays())
980    return;
981
982  TestEventHandler event_handler;
983  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
984
985  UpdateDisplay("600x400*2@1.5,500x300");
986
987  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
988  gfx::Display::SetInternalDisplayId(display1.id());
989
990  gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
991  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
992  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
993  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
994  EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
995  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
996  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
997
998  aura::test::EventGenerator generator(root_windows[0]);
999  generator.MoveMouseToInHost(599, 200);
1000  EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
1001
1002  internal::DisplayManager* display_manager =
1003      Shell::GetInstance()->display_manager();
1004  display_manager->SetDisplayUIScale(display1.id(), 1.25f);
1005  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1006  display2 = ScreenAsh::GetSecondaryDisplay();
1007  EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
1008  EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
1009  EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
1010  EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
1011  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1012
1013  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1014}
1015
1016TEST_F(DisplayControllerTest, TouchScale) {
1017  if (!SupportsMultipleDisplays())
1018    return;
1019
1020  TestEventHandler event_handler;
1021  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1022
1023  UpdateDisplay("200x200*2");
1024  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
1025  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
1026  aura::RootWindow* root_window = root_windows[0];
1027  aura::test::EventGenerator generator(root_window);
1028
1029  generator.PressMoveAndReleaseTouchTo(50, 50);
1030  // Default test touches have radius_x/y = 1.0, with device scale
1031  // factor = 2, the scaled radius_x/y should be 0.5.
1032  EXPECT_EQ(0.5, event_handler.touch_radius_x());
1033  EXPECT_EQ(0.5, event_handler.touch_radius_y());
1034
1035  generator.ScrollSequence(gfx::Point(0,0),
1036                           base::TimeDelta::FromMilliseconds(100),
1037                           10.0, 1.0, 5, 1);
1038
1039  // With device scale factor = 2, ordinal_offset * 2 = offset.
1040  EXPECT_EQ(event_handler.scroll_x_offset(),
1041            event_handler.scroll_x_offset_ordinal() * 2);
1042  EXPECT_EQ(event_handler.scroll_y_offset(),
1043            event_handler.scroll_y_offset_ordinal() * 2);
1044
1045  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1046}
1047
1048TEST_F(DisplayControllerTest, ConvertHostToRootCoords) {
1049  if (!SupportsMultipleDisplays())
1050    return;
1051
1052  TestEventHandler event_handler;
1053  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1054
1055  UpdateDisplay("600x400*2/r@1.5");
1056
1057  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1058  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
1059  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1060  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1061  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1062
1063  aura::test::EventGenerator generator(root_windows[0]);
1064  generator.MoveMouseToInHost(0, 0);
1065  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1066  generator.MoveMouseToInHost(599, 0);
1067  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1068  generator.MoveMouseToInHost(599, 399);
1069  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1070  generator.MoveMouseToInHost(0, 399);
1071  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1072
1073  UpdateDisplay("600x400*2/u@1.5");
1074  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1075  root_windows = Shell::GetAllRootWindows();
1076  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1077  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1078  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1079
1080  generator.MoveMouseToInHost(0, 0);
1081  EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
1082  generator.MoveMouseToInHost(599, 0);
1083  EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
1084  generator.MoveMouseToInHost(599, 399);
1085  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1086  generator.MoveMouseToInHost(0, 399);
1087  EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
1088
1089  UpdateDisplay("600x400*2/l@1.5");
1090  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1091  root_windows = Shell::GetAllRootWindows();
1092  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1093  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1094  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1095
1096  generator.MoveMouseToInHost(0, 0);
1097  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1098  generator.MoveMouseToInHost(599, 0);
1099  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1100  generator.MoveMouseToInHost(599, 399);
1101  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1102  generator.MoveMouseToInHost(0, 399);
1103  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1104
1105  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1106}
1107
1108#if defined(USE_X11)
1109TEST_F(DisplayControllerTest, XWidowNameForRootWindow) {
1110  EXPECT_EQ("aura_root_0", GetXWindowName(Shell::GetPrimaryRootWindow()));
1111
1112  // Multiple display.
1113  UpdateDisplay("200x200,300x300");
1114  aura::RootWindow* primary, *secondary;
1115  GetPrimaryAndSeconary(&primary, &secondary);
1116  EXPECT_EQ("aura_root_0", GetXWindowName(primary));
1117  EXPECT_EQ("aura_root_x", GetXWindowName(secondary));
1118
1119  // Swap primary.
1120  primary = secondary = NULL;
1121  Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1122  GetPrimaryAndSeconary(&primary, &secondary);
1123  EXPECT_EQ("aura_root_0", GetXWindowName(primary));
1124  EXPECT_EQ("aura_root_x", GetXWindowName(secondary));
1125
1126  // Switching back to single display.
1127  UpdateDisplay("300x400");
1128  EXPECT_EQ("aura_root_0", GetXWindowName(Shell::GetPrimaryRootWindow()));
1129}
1130#endif
1131
1132}  // namespace ash
1133