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