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