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