display_controller_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/activation_change_observer.h"
24#include "ui/aura/client/activation_client.h"
25#include "ui/aura/client/focus_change_observer.h"
26#include "ui/aura/client/focus_client.h"
27#include "ui/aura/env.h"
28#include "ui/aura/test/event_generator.h"
29#include "ui/aura/window_event_dispatcher.h"
30#include "ui/aura/window_tracker.h"
31#include "ui/events/event_handler.h"
32#include "ui/gfx/display.h"
33#include "ui/gfx/screen.h"
34#include "ui/views/widget/widget.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
512internal::DisplayInfo CreateDisplayInfo(int64 id,
513                                        const gfx::Rect& bounds,
514                                        float device_scale_factor) {
515  internal::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  internal::DisplayManager* display_manager =
530      Shell::GetInstance()->display_manager();
531
532  const internal::DisplayInfo internal_display_info =
533      CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f);
534  const internal::DisplayInfo external_display_info =
535      CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f);
536
537  std::vector<internal::DisplayInfo> display_info_list;
538  // Mirror.
539  display_info_list.push_back(internal_display_info);
540  display_info_list.push_back(external_display_info);
541  display_manager->OnNativeDisplaysChanged(display_info_list);
542  const int64 internal_display_id =
543      test::DisplayManagerTestApi(display_manager).
544      SetFirstDisplayAsInternalDisplay();
545  EXPECT_EQ(1, internal_display_id);
546  EXPECT_EQ(2U, display_manager->num_connected_displays());
547  EXPECT_EQ(1U, display_manager->GetNumDisplays());
548
549  wm::WindowState* window_state = wm::GetWindowState(w1.get());
550  const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
551  window_state->OnWMEvent(&toggle_fullscreen_event);
552  EXPECT_TRUE(window_state->IsFullscreen());
553  EXPECT_EQ("0,0 250x250", w1->bounds().ToString());
554  // Dock mode.
555  TestObserver observer;
556  display_info_list.clear();
557  display_info_list.push_back(external_display_info);
558  display_manager->OnNativeDisplaysChanged(display_info_list);
559  EXPECT_EQ(1U, display_manager->GetNumDisplays());
560  EXPECT_EQ(1U, display_manager->num_connected_displays());
561  EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
562  EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
563  EXPECT_EQ(1, observer.CountAndReset());
564  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
565  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
566
567  EXPECT_TRUE(window_state->IsFullscreen());
568  EXPECT_EQ("0,0 500x500", w1->bounds().ToString());
569}
570
571TEST_F(DisplayControllerTest, BoundsUpdated) {
572  if (!SupportsMultipleDisplays())
573    return;
574
575  // Creates windows to catch activation change event.
576  scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
577  w1->Focus();
578
579  TestObserver observer;
580  SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
581  UpdateDisplay("200x200,300x300");  // layout, resize and add.
582  EXPECT_EQ(1, observer.CountAndReset());
583  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
584  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
585
586  internal::DisplayManager* display_manager =
587      Shell::GetInstance()->display_manager();
588  gfx::Insets insets(5, 5, 5, 5);
589  display_manager->UpdateWorkAreaOfDisplay(
590      ScreenUtil::GetSecondaryDisplay().id(), insets);
591
592  EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
593  EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
594  EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
595
596  UpdateDisplay("400x400,200x200");
597  EXPECT_EQ(1, observer.CountAndReset());  // two resizes
598  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
599  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
600  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
601  EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
602
603  UpdateDisplay("400x400,300x300");
604  EXPECT_EQ(1, observer.CountAndReset());
605  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
606  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
607  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
608  EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
609
610  UpdateDisplay("400x400");
611  EXPECT_EQ(1, observer.CountAndReset());
612  EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
613  EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
614  EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
615  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
616
617  UpdateDisplay("400x500*2,300x300");
618  EXPECT_EQ(1, observer.CountAndReset());
619  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
620  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
621  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
622  EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
623  EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
624
625  // No change
626  UpdateDisplay("400x500*2,300x300");
627  EXPECT_EQ(0, observer.CountAndReset());
628  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
629  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
630
631  // Rotation
632  int64 primary_id = GetPrimaryDisplay().id();
633  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
634  EXPECT_EQ(1, observer.CountAndReset());
635  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
636  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
637  display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
638  EXPECT_EQ(0, observer.CountAndReset());
639  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
640  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
641
642  // UI scale is eanbled only on internal display.
643  int64 secondary_id = GetSecondaryDisplay().id();
644  gfx::Display::SetInternalDisplayId(secondary_id);
645  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
646  EXPECT_EQ(1, observer.CountAndReset());
647  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
648  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
649  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
650  EXPECT_EQ(0, observer.CountAndReset());
651  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
652  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
653  display_manager->SetDisplayUIScale(primary_id, 1.125f);
654  EXPECT_EQ(0, observer.CountAndReset());
655  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
656  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
657  display_manager->SetDisplayUIScale(primary_id, 1.125f);
658  EXPECT_EQ(0, observer.CountAndReset());
659  EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
660  EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
661}
662
663TEST_F(DisplayControllerTest, SwapPrimary) {
664  if (!SupportsMultipleDisplays())
665    return;
666
667  DisplayController* display_controller =
668      Shell::GetInstance()->display_controller();
669  internal::DisplayManager* display_manager =
670      Shell::GetInstance()->display_manager();
671
672  UpdateDisplay("200x200,300x300");
673  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
674  gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
675
676  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
677  display_manager->SetLayoutForCurrentDisplays(display_layout);
678
679  EXPECT_NE(primary_display.id(), secondary_display.id());
680  aura::Window* primary_root =
681      display_controller->GetRootWindowForDisplayId(primary_display.id());
682  aura::Window* secondary_root =
683      display_controller->GetRootWindowForDisplayId(secondary_display.id());
684  EXPECT_NE(primary_root, secondary_root);
685  aura::Window* shelf_window =
686      Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
687  EXPECT_TRUE(primary_root->Contains(shelf_window));
688  EXPECT_FALSE(secondary_root->Contains(shelf_window));
689  EXPECT_EQ(primary_display.id(),
690            Shell::GetScreen()->GetDisplayNearestPoint(
691                gfx::Point(-100, -100)).id());
692  EXPECT_EQ(primary_display.id(),
693            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
694
695  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
696  EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString());
697  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
698  EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString());
699  EXPECT_EQ("right, 50",
700            display_manager->GetCurrentDisplayLayout().ToString());
701
702  // Switch primary and secondary
703  display_controller->SetPrimaryDisplay(secondary_display);
704  const DisplayLayout& inverted_layout =
705      display_manager->GetCurrentDisplayLayout();
706  EXPECT_EQ("left, -50", inverted_layout.ToString());
707
708  EXPECT_EQ(secondary_display.id(),
709            Shell::GetScreen()->GetPrimaryDisplay().id());
710  EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
711  EXPECT_EQ(primary_display.id(),
712            Shell::GetScreen()->GetDisplayNearestPoint(
713                gfx::Point(-100, -100)).id());
714  EXPECT_EQ(secondary_display.id(),
715            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
716
717  EXPECT_EQ(
718      primary_root,
719      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
720  EXPECT_EQ(
721      secondary_root,
722      display_controller->GetRootWindowForDisplayId(primary_display.id()));
723  EXPECT_TRUE(primary_root->Contains(shelf_window));
724  EXPECT_FALSE(secondary_root->Contains(shelf_window));
725
726  // Test if the bounds are correctly swapped.
727  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
728  gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay();
729  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
730  EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString());
731  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
732
733  EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString());
734
735  aura::WindowTracker tracker;
736  tracker.Add(primary_root);
737  tracker.Add(secondary_root);
738
739  // Deleting 2nd display should move the primary to original primary display.
740  UpdateDisplay("200x200");
741  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
742  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
743  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
744  EXPECT_EQ(primary_display.id(),
745            Shell::GetScreen()->GetDisplayNearestPoint(
746                gfx::Point(-100, -100)).id());
747  EXPECT_EQ(primary_display.id(),
748            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
749  EXPECT_TRUE(tracker.Contains(primary_root));
750  EXPECT_FALSE(tracker.Contains(secondary_root));
751  EXPECT_TRUE(primary_root->Contains(shelf_window));
752}
753
754TEST_F(DisplayControllerTest, FindNearestDisplay) {
755  if (!SupportsMultipleDisplays())
756    return;
757
758  DisplayController* display_controller =
759      Shell::GetInstance()->display_controller();
760  internal::DisplayManager* display_manager =
761      Shell::GetInstance()->display_manager();
762
763  UpdateDisplay("200x200,300x300");
764  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
765  display_manager->SetLayoutForCurrentDisplays(display_layout);
766
767  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
768  gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
769  EXPECT_NE(primary_display.id(), secondary_display.id());
770  aura::Window* primary_root =
771      display_controller->GetRootWindowForDisplayId(primary_display.id());
772  aura::Window* secondary_root =
773      display_controller->GetRootWindowForDisplayId(secondary_display.id());
774  EXPECT_NE(primary_root, secondary_root);
775
776  // Test that points outside of any display return the nearest display.
777  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
778      gfx::Point(-100, 0)).id());
779  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
780      gfx::Point(0, -100)).id());
781  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
782      gfx::Point(100, 100)).id());
783  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
784      gfx::Point(224, 25)).id());
785  EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
786      gfx::Point(226, 25)).id());
787  EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
788      gfx::Point(600, 100)).id());
789  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
790      gfx::Point(174, 225)).id());
791  EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
792      gfx::Point(176, 225)).id());
793  EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
794      gfx::Point(300, 400)).id());
795}
796
797TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) {
798  if (!SupportsMultipleDisplays())
799    return;
800
801  CommandLine::ForCurrentProcess()->AppendSwitch(
802      switches::kAshDisableAlternateShelfLayout);
803
804  DisplayController* display_controller =
805      Shell::GetInstance()->display_controller();
806  internal::DisplayManager* display_manager =
807      Shell::GetInstance()->display_manager();
808
809  UpdateDisplay("200x200,300x300");
810  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
811  gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
812
813  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
814  display_manager->SetLayoutForCurrentDisplays(display_layout);
815
816  EXPECT_NE(primary_display.id(), secondary_display.id());
817  aura::Window* primary_root =
818      display_controller->GetRootWindowForDisplayId(primary_display.id());
819  aura::Window* secondary_root =
820      display_controller->GetRootWindowForDisplayId(secondary_display.id());
821  EXPECT_NE(primary_root, secondary_root);
822  aura::Window* shelf_window =
823      Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
824  EXPECT_TRUE(primary_root->Contains(shelf_window));
825  EXPECT_FALSE(secondary_root->Contains(shelf_window));
826  EXPECT_EQ(primary_display.id(),
827            Shell::GetScreen()->GetDisplayNearestPoint(
828                gfx::Point(-100, -100)).id());
829  EXPECT_EQ(primary_display.id(),
830            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
831
832  EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
833  EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString());
834  EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
835  EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString());
836  EXPECT_EQ("right, 50",
837            display_manager->GetCurrentDisplayLayout().ToString());
838
839  // Switch primary and secondary
840  display_controller->SetPrimaryDisplay(secondary_display);
841  const DisplayLayout& inverted_layout =
842      display_manager->GetCurrentDisplayLayout();
843  EXPECT_EQ("left, -50", inverted_layout.ToString());
844
845  EXPECT_EQ(secondary_display.id(),
846            Shell::GetScreen()->GetPrimaryDisplay().id());
847  EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
848  EXPECT_EQ(primary_display.id(),
849            Shell::GetScreen()->GetDisplayNearestPoint(
850                gfx::Point(-100, -100)).id());
851  EXPECT_EQ(secondary_display.id(),
852            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
853
854  EXPECT_EQ(
855      primary_root,
856      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
857  EXPECT_EQ(
858      secondary_root,
859      display_controller->GetRootWindowForDisplayId(primary_display.id()));
860  EXPECT_TRUE(primary_root->Contains(shelf_window));
861  EXPECT_FALSE(secondary_root->Contains(shelf_window));
862
863  // Test if the bounds are correctly swapped.
864  gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
865  gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay();
866  EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
867  EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString());
868  EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
869
870  EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString());
871
872  aura::WindowTracker tracker;
873  tracker.Add(primary_root);
874  tracker.Add(secondary_root);
875
876  // Deleting 2nd display should move the primary to original primary display.
877  UpdateDisplay("200x200");
878  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
879  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
880  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
881  EXPECT_EQ(primary_display.id(),
882            Shell::GetScreen()->GetDisplayNearestPoint(
883                gfx::Point(-100, -100)).id());
884  EXPECT_EQ(primary_display.id(),
885            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
886  EXPECT_TRUE(tracker.Contains(primary_root));
887  EXPECT_FALSE(tracker.Contains(secondary_root));
888  EXPECT_TRUE(primary_root->Contains(shelf_window));
889}
890
891TEST_F(DisplayControllerTest, SwapPrimaryById) {
892  if (!SupportsMultipleDisplays())
893    return;
894
895  DisplayController* display_controller =
896      Shell::GetInstance()->display_controller();
897  internal::DisplayManager* display_manager =
898      Shell::GetInstance()->display_manager();
899
900  UpdateDisplay("200x200,300x300");
901  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
902  gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
903
904  DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
905  display_manager->SetLayoutForCurrentDisplays(display_layout);
906
907  EXPECT_NE(primary_display.id(), secondary_display.id());
908  aura::Window* primary_root =
909      display_controller->GetRootWindowForDisplayId(primary_display.id());
910  aura::Window* secondary_root =
911      display_controller->GetRootWindowForDisplayId(secondary_display.id());
912  aura::Window* shelf_window =
913      Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
914  EXPECT_TRUE(primary_root->Contains(shelf_window));
915  EXPECT_FALSE(secondary_root->Contains(shelf_window));
916  EXPECT_NE(primary_root, secondary_root);
917  EXPECT_EQ(primary_display.id(),
918            Shell::GetScreen()->GetDisplayNearestPoint(
919                gfx::Point(-100, -100)).id());
920  EXPECT_EQ(primary_display.id(),
921            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
922
923  // Switch primary and secondary by display ID.
924  TestObserver observer;
925  display_controller->SetPrimaryDisplayId(secondary_display.id());
926  EXPECT_EQ(secondary_display.id(),
927            Shell::GetScreen()->GetPrimaryDisplay().id());
928  EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
929  EXPECT_LT(0, observer.CountAndReset());
930
931  EXPECT_EQ(
932      primary_root,
933      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
934  EXPECT_EQ(
935      secondary_root,
936      display_controller->GetRootWindowForDisplayId(primary_display.id()));
937  EXPECT_TRUE(primary_root->Contains(shelf_window));
938  EXPECT_FALSE(secondary_root->Contains(shelf_window));
939
940  const DisplayLayout& inverted_layout =
941      display_manager->GetCurrentDisplayLayout();
942
943  EXPECT_EQ("left, -50", inverted_layout.ToString());
944
945  // Calling the same ID don't do anything.
946  display_controller->SetPrimaryDisplayId(secondary_display.id());
947  EXPECT_EQ(0, observer.CountAndReset());
948
949  aura::WindowTracker tracker;
950  tracker.Add(primary_root);
951  tracker.Add(secondary_root);
952
953  // Deleting 2nd display should move the primary to original primary display.
954  UpdateDisplay("200x200");
955  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
956  EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
957  EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
958  EXPECT_EQ(primary_display.id(),
959            Shell::GetScreen()->GetDisplayNearestPoint(
960                gfx::Point(-100, -100)).id());
961  EXPECT_EQ(primary_display.id(),
962            Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
963  EXPECT_TRUE(tracker.Contains(primary_root));
964  EXPECT_FALSE(tracker.Contains(secondary_root));
965  EXPECT_TRUE(primary_root->Contains(shelf_window));
966
967  // Adding 2nd display with the same ID.  The 2nd display should become primary
968  // since secondary id is still stored as desirable_primary_id.
969  std::vector<internal::DisplayInfo> display_info_list;
970  display_info_list.push_back(
971      display_manager->GetDisplayInfo(primary_display.id()));
972  display_info_list.push_back(
973      display_manager->GetDisplayInfo(secondary_display.id()));
974  display_manager->OnNativeDisplaysChanged(display_info_list);
975
976  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
977  EXPECT_EQ(secondary_display.id(),
978            Shell::GetScreen()->GetPrimaryDisplay().id());
979  EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
980  EXPECT_EQ(
981      primary_root,
982      display_controller->GetRootWindowForDisplayId(secondary_display.id()));
983  EXPECT_NE(
984      primary_root,
985      display_controller->GetRootWindowForDisplayId(primary_display.id()));
986  EXPECT_TRUE(primary_root->Contains(shelf_window));
987
988  // Deleting 2nd display and adding 2nd display with a different ID.  The 2nd
989  // display shouldn't become primary.
990  UpdateDisplay("200x200");
991  internal::DisplayInfo third_display_info(
992      secondary_display.id() + 1, std::string(), false);
993  third_display_info.SetBounds(secondary_display.bounds());
994  ASSERT_NE(primary_display.id(), third_display_info.id());
995
996  const internal::DisplayInfo& primary_display_info =
997      display_manager->GetDisplayInfo(primary_display.id());
998  std::vector<internal::DisplayInfo> display_info_list2;
999  display_info_list2.push_back(primary_display_info);
1000  display_info_list2.push_back(third_display_info);
1001  display_manager->OnNativeDisplaysChanged(display_info_list2);
1002  EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1003  EXPECT_EQ(primary_display.id(),
1004            Shell::GetScreen()->GetPrimaryDisplay().id());
1005  EXPECT_EQ(third_display_info.id(), ScreenUtil::GetSecondaryDisplay().id());
1006  EXPECT_EQ(
1007      primary_root,
1008      display_controller->GetRootWindowForDisplayId(primary_display.id()));
1009  EXPECT_NE(
1010      primary_root,
1011      display_controller->GetRootWindowForDisplayId(third_display_info.id()));
1012  EXPECT_TRUE(primary_root->Contains(shelf_window));
1013}
1014
1015TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) {
1016  if (!SupportsMultipleDisplays())
1017    return;
1018
1019  DisplayController* display_controller =
1020      Shell::GetInstance()->display_controller();
1021
1022  UpdateDisplay("200x200,200x200*2");
1023  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
1024  gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
1025
1026  aura::Window* primary_root =
1027      display_controller->GetRootWindowForDisplayId(primary_display.id());
1028  aura::Window* secondary_root =
1029      display_controller->GetRootWindowForDisplayId(secondary_display.id());
1030  EXPECT_NE(primary_root, secondary_root);
1031
1032  test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
1033
1034  EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
1035      device_scale_factor());
1036  primary_root->MoveCursorTo(gfx::Point(50, 50));
1037  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1038  EXPECT_EQ(2.0f, secondary_root->GetHost()->compositor()->
1039      device_scale_factor());
1040  secondary_root->MoveCursorTo(gfx::Point(50, 50));
1041  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
1042
1043  // Switch primary and secondary
1044  display_controller->SetPrimaryDisplay(secondary_display);
1045
1046  // Cursor's device scale factor should be updated accroding to the swap of
1047  // primary and secondary.
1048  EXPECT_EQ(1.0f, secondary_root->GetHost()->compositor()->
1049      device_scale_factor());
1050  secondary_root->MoveCursorTo(gfx::Point(50, 50));
1051  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1052  primary_root->MoveCursorTo(gfx::Point(50, 50));
1053  EXPECT_EQ(2.0f, primary_root->GetHost()->compositor()->
1054      device_scale_factor());
1055  EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
1056
1057  // Deleting 2nd display.
1058  UpdateDisplay("200x200");
1059  RunAllPendingInMessageLoop();  // RootWindow is deleted in a posted task.
1060
1061  // Cursor's device scale factor should be updated even without moving cursor.
1062  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1063
1064  primary_root->MoveCursorTo(gfx::Point(50, 50));
1065  EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
1066      device_scale_factor());
1067  EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1068}
1069
1070TEST_F(DisplayControllerTest, OverscanInsets) {
1071  if (!SupportsMultipleDisplays())
1072    return;
1073
1074  DisplayController* display_controller =
1075      Shell::GetInstance()->display_controller();
1076  TestEventHandler event_handler;
1077  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1078
1079  UpdateDisplay("120x200,300x400*2");
1080  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1081  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1082
1083  display_controller->SetOverscanInsets(display1.id(),
1084                                        gfx::Insets(10, 15, 20, 25));
1085  EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
1086  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1087  EXPECT_EQ("80,0 150x200",
1088            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1089
1090  aura::test::EventGenerator generator(root_windows[0]);
1091  generator.MoveMouseToInHost(20, 25);
1092  EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
1093
1094  display_controller->SetOverscanInsets(display1.id(), gfx::Insets());
1095  EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
1096  EXPECT_EQ("120,0 150x200",
1097            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1098
1099  generator.MoveMouseToInHost(30, 20);
1100  EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
1101
1102  // Make sure the root window transformer uses correct scale
1103  // factor when swapping display. Test crbug.com/253690.
1104  UpdateDisplay("400x300*2,600x400/o");
1105  root_windows = Shell::GetAllRootWindows();
1106  gfx::Point point;
1107  Shell::GetAllRootWindows()[1]->GetHost()->
1108      GetRootTransform().TransformPoint(&point);
1109  EXPECT_EQ("15,10", point.ToString());
1110
1111  display_controller->SwapPrimaryDisplay();
1112  point.SetPoint(0, 0);
1113  Shell::GetAllRootWindows()[1]->GetHost()->
1114      GetRootTransform().TransformPoint(&point);
1115  EXPECT_EQ("15,10", point.ToString());
1116
1117  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1118}
1119
1120TEST_F(DisplayControllerTest, Rotate) {
1121  if (!SupportsMultipleDisplays())
1122    return;
1123
1124  internal::DisplayManager* display_manager =
1125      Shell::GetInstance()->display_manager();
1126  TestEventHandler event_handler;
1127  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1128
1129  UpdateDisplay("120x200,300x400*2");
1130  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1131  int64 display2_id = ScreenUtil::GetSecondaryDisplay().id();
1132  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1133  aura::test::EventGenerator generator1(root_windows[0]);
1134
1135  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1136  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1137  EXPECT_EQ("120,0 150x200",
1138            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1139  generator1.MoveMouseToInHost(50, 40);
1140  EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
1141  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
1142  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1143
1144  display_manager->SetDisplayRotation(display1.id(),
1145                                      gfx::Display::ROTATE_90);
1146  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1147  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1148  EXPECT_EQ("200,0 150x200",
1149            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1150  generator1.MoveMouseToInHost(50, 40);
1151  EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
1152  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1153  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1154
1155  DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
1156  display_manager->SetLayoutForCurrentDisplays(display_layout);
1157  EXPECT_EQ("50,120 150x200",
1158            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1159
1160  display_manager->SetDisplayRotation(display2_id,
1161                                      gfx::Display::ROTATE_270);
1162  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1163  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1164  EXPECT_EQ("50,120 200x150",
1165            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1166  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1167  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1168
1169#if !defined(OS_WIN)
1170  aura::test::EventGenerator generator2(root_windows[1]);
1171  generator2.MoveMouseToInHost(50, 40);
1172  EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
1173  display_manager->SetDisplayRotation(display1.id(),
1174                                      gfx::Display::ROTATE_180);
1175
1176  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1177  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1178  // Dislay must share at least 100, so the x's offset becomes 20.
1179  EXPECT_EQ("20,200 200x150",
1180            ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1181  EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
1182  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1183
1184  generator1.MoveMouseToInHost(50, 40);
1185  EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
1186#endif
1187
1188  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1189}
1190
1191TEST_F(DisplayControllerTest, ScaleRootWindow) {
1192  if (!SupportsMultipleDisplays())
1193    return;
1194
1195  TestEventHandler event_handler;
1196  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1197
1198  UpdateDisplay("600x400*2@1.5,500x300");
1199
1200  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1201  gfx::Display::SetInternalDisplayId(display1.id());
1202
1203  gfx::Display display2 = ScreenUtil::GetSecondaryDisplay();
1204  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1205  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1206  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1207  EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
1208  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1209  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1210
1211  aura::test::EventGenerator generator(root_windows[0]);
1212  generator.MoveMouseToInHost(599, 200);
1213  EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
1214
1215  internal::DisplayManager* display_manager =
1216      Shell::GetInstance()->display_manager();
1217  display_manager->SetDisplayUIScale(display1.id(), 1.25f);
1218  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1219  display2 = ScreenUtil::GetSecondaryDisplay();
1220  EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
1221  EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
1222  EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
1223  EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
1224  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1225
1226  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1227}
1228
1229TEST_F(DisplayControllerTest, TouchScale) {
1230  if (!SupportsMultipleDisplays())
1231    return;
1232
1233  TestEventHandler event_handler;
1234  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1235
1236  UpdateDisplay("200x200*2");
1237  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
1238  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1239  aura::Window* root_window = root_windows[0];
1240  aura::test::EventGenerator generator(root_window);
1241
1242  generator.PressMoveAndReleaseTouchTo(50, 50);
1243  // Default test touches have radius_x/y = 1.0, with device scale
1244  // factor = 2, the scaled radius_x/y should be 0.5.
1245  EXPECT_EQ(0.5, event_handler.touch_radius_x());
1246  EXPECT_EQ(0.5, event_handler.touch_radius_y());
1247
1248  generator.ScrollSequence(gfx::Point(0,0),
1249                           base::TimeDelta::FromMilliseconds(100),
1250                           10.0, 1.0, 5, 1);
1251
1252  // ordinal_offset is invariant to the device scale factor.
1253  EXPECT_EQ(event_handler.scroll_x_offset(),
1254            event_handler.scroll_x_offset_ordinal());
1255  EXPECT_EQ(event_handler.scroll_y_offset(),
1256            event_handler.scroll_y_offset_ordinal());
1257
1258  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1259}
1260
1261TEST_F(DisplayControllerTest, ConvertHostToRootCoords) {
1262  if (!SupportsMultipleDisplays())
1263    return;
1264
1265  TestEventHandler event_handler;
1266  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1267
1268  UpdateDisplay("600x400*2/r@1.5");
1269
1270  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1271  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1272  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1273  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1274  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1275
1276  aura::test::EventGenerator generator(root_windows[0]);
1277  generator.MoveMouseToInHost(0, 0);
1278  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1279  generator.MoveMouseToInHost(599, 0);
1280  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1281  generator.MoveMouseToInHost(599, 399);
1282  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1283  generator.MoveMouseToInHost(0, 399);
1284  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1285
1286  UpdateDisplay("600x400*2/u@1.5");
1287  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1288  root_windows = Shell::GetAllRootWindows();
1289  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1290  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1291  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1292
1293  generator.MoveMouseToInHost(0, 0);
1294  EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
1295  generator.MoveMouseToInHost(599, 0);
1296  EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
1297  generator.MoveMouseToInHost(599, 399);
1298  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1299  generator.MoveMouseToInHost(0, 399);
1300  EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
1301
1302  UpdateDisplay("600x400*2/l@1.5");
1303  display1 = Shell::GetScreen()->GetPrimaryDisplay();
1304  root_windows = Shell::GetAllRootWindows();
1305  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1306  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1307  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1308
1309  generator.MoveMouseToInHost(0, 0);
1310  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1311  generator.MoveMouseToInHost(599, 0);
1312  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1313  generator.MoveMouseToInHost(599, 399);
1314  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1315  generator.MoveMouseToInHost(0, 399);
1316  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1317
1318  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1319}
1320
1321namespace {
1322
1323internal::DisplayInfo CreateDisplayInfo(int64 id,
1324                                        int y,
1325                                        gfx::Display::Rotation rotation) {
1326  internal::DisplayInfo info(id, "", false);
1327  info.SetBounds(gfx::Rect(0, y, 500, 500));
1328  info.set_rotation(rotation);
1329  return info;
1330}
1331
1332}  // namespace
1333
1334// Make sure that the compositor based mirroring can switch
1335// from/to dock mode.
1336TEST_F(DisplayControllerTest, DockToSingle) {
1337  if (!SupportsMultipleDisplays())
1338    return;
1339
1340  internal::DisplayManager* display_manager =
1341      Shell::GetInstance()->display_manager();
1342
1343  const int64 internal_id = 1;
1344
1345  const internal::DisplayInfo internal_display_info =
1346      CreateDisplayInfo(internal_id, 0, gfx::Display::ROTATE_0);
1347  const internal::DisplayInfo external_display_info =
1348      CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90);
1349
1350  std::vector<internal::DisplayInfo> display_info_list;
1351  // Extended
1352  display_info_list.push_back(internal_display_info);
1353  display_info_list.push_back(external_display_info);
1354  display_manager->OnNativeDisplaysChanged(display_info_list);
1355  const int64 internal_display_id =
1356      test::DisplayManagerTestApi(display_manager).
1357      SetFirstDisplayAsInternalDisplay();
1358  EXPECT_EQ(internal_id, internal_display_id);
1359  EXPECT_EQ(2U, display_manager->GetNumDisplays());
1360
1361  // Dock mode.
1362  display_info_list.clear();
1363  display_info_list.push_back(external_display_info);
1364  display_manager->OnNativeDisplaysChanged(display_info_list);
1365  EXPECT_EQ(1U, display_manager->GetNumDisplays());
1366  EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1367               GetRootTransform().IsIdentityOrIntegerTranslation());
1368
1369  // Switch to single mode and make sure the transform is the one
1370  // for the internal display.
1371  display_info_list.clear();
1372  display_info_list.push_back(internal_display_info);
1373  display_manager->OnNativeDisplaysChanged(display_info_list);
1374  EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1375              GetRootTransform().IsIdentityOrIntegerTranslation());
1376}
1377
1378#if defined(USE_X11)
1379TEST_F(DisplayControllerTest, XWidowNameForRootWindow) {
1380  EXPECT_EQ("aura_root_0", GetXWindowName(
1381      Shell::GetPrimaryRootWindow()->GetHost()));
1382
1383  // Multiple display.
1384  UpdateDisplay("200x200,300x300");
1385  aura::Window* primary, *secondary;
1386  GetPrimaryAndSeconary(&primary, &secondary);
1387  EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1388  EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1389
1390  // Swap primary.
1391  primary = secondary = NULL;
1392  Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1393  GetPrimaryAndSeconary(&primary, &secondary);
1394  EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1395  EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1396
1397  // Switching back to single display.
1398  UpdateDisplay("300x400");
1399  EXPECT_EQ("aura_root_0", GetXWindowName(
1400      Shell::GetPrimaryRootWindow()->GetHost()));
1401}
1402#endif
1403
1404}  // namespace ash
1405