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