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