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.
5 #include "ash/display/display_controller.h"
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"
38 #include "ui/gfx/x/x11_types.h"
45 const char kDesktopBackgroundView[] = "DesktopBackgroundView";
50 explicit Resetter(T* value) : value_(*value) {
54 T value() { return value_; }
58 DISALLOW_COPY_AND_ASSIGN(Resetter);
61 class TestObserver : public DisplayController::Observer,
62 public gfx::DisplayObserver,
63 public aura::client::FocusChangeObserver,
64 public aura::client::ActivationChangeObserver {
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())->
77 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
81 virtual ~TestObserver() {
82 Shell::GetInstance()->display_controller()->RemoveObserver(this);
83 Shell::GetScreen()->RemoveObserver(this);
84 aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())->
86 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
90 // Overridden from DisplayController::Observer
91 virtual void OnDisplayConfigurationChanging() OVERRIDE {
94 virtual void OnDisplayConfigurationChanged() OVERRIDE {
98 // Overrideen from gfx::DisplayObserver
99 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
100 changed_display_id_ = display.id();
101 bounds_changed_count_ ++;
103 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
105 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
108 // Overridden from aura::client::FocusChangeObserver
109 virtual void OnWindowFocused(aura::Window* gained_focus,
110 aura::Window* lost_focus) OVERRIDE {
111 focus_changed_count_++;
114 // Overridden from aura::client::ActivationChangeObserver
115 virtual void OnWindowActivated(aura::Window* gained_active,
116 aura::Window* lost_active) OVERRIDE {
117 activation_changed_count_++;
119 virtual void OnAttemptToReactivateWindow(
120 aura::Window* request_active,
121 aura::Window* actual_active) OVERRIDE {
124 int CountAndReset() {
125 EXPECT_EQ(changing_count_, changed_count_);
127 return Resetter<int>(&changing_count_).value();
130 int64 GetBoundsChangedCountAndReset() {
131 return Resetter<int>(&bounds_changed_count_).value();
134 int64 GetChangedDisplayIdAndReset() {
135 return Resetter<int64>(&changed_display_id_).value();
138 int GetFocusChangedCountAndReset() {
139 return Resetter<int>(&focus_changed_count_).value();
142 int GetActivationChangedCountAndReset() {
143 return Resetter<int>(&activation_changed_count_).value();
150 int bounds_changed_count_;
151 int64 changed_display_id_;
153 int focus_changed_count_;
154 int activation_changed_count_;
156 DISALLOW_COPY_AND_ASSIGN(TestObserver);
159 gfx::Display GetPrimaryDisplay() {
160 return Shell::GetScreen()->GetDisplayNearestWindow(
161 Shell::GetAllRootWindows()[0]);
164 gfx::Display GetSecondaryDisplay() {
165 return Shell::GetScreen()->GetDisplayNearestWindow(
166 Shell::GetAllRootWindows()[1]);
169 void SetSecondaryDisplayLayoutAndOffset(DisplayLayout::Position position,
171 DisplayLayout layout(position, offset);
172 ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
173 Shell::GetInstance()->display_manager()->
174 SetLayoutForCurrentDisplays(layout);
177 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
178 SetSecondaryDisplayLayoutAndOffset(position, 0);
181 void SetDefaultDisplayLayout(DisplayLayout::Position position) {
182 Shell::GetInstance()->display_manager()->layout_store()->
183 SetDefaultDisplayLayout(DisplayLayout(position, 0));
186 class DisplayControllerShutdownTest : public test::AshTestBase {
188 DisplayControllerShutdownTest() {}
189 virtual ~DisplayControllerShutdownTest() {}
191 virtual void TearDown() OVERRIDE {
192 test::AshTestBase::TearDown();
193 if (!SupportsMultipleDisplays())
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());
203 DISALLOW_COPY_AND_ASSIGN(DisplayControllerShutdownTest);
206 class StartupHelper : public test::TestShellDelegate,
207 public DisplayController::Observer {
209 StartupHelper() : displays_initialized_(false) {}
210 virtual ~StartupHelper() {}
212 // ash::ShellSelegate:
213 virtual void PreInit() OVERRIDE {
214 Shell::GetInstance()->display_controller()->AddObserver(this);
217 // ash::DisplayController::Observer:
218 virtual void OnDisplaysInitialized() OVERRIDE {
219 DCHECK(!displays_initialized_);
220 displays_initialized_ = true;
223 const bool displays_initialized() const {
224 return displays_initialized_;
228 bool displays_initialized_;
230 DISALLOW_COPY_AND_ASSIGN(StartupHelper);
233 class DisplayControllerStartupTest : public test::AshTestBase {
235 DisplayControllerStartupTest() : startup_helper_(new StartupHelper) {}
236 virtual ~DisplayControllerStartupTest() {}
238 // ash::test::AshTestBase:
239 virtual void SetUp() OVERRIDE {
240 ash_test_helper()->set_test_shell_delegate(startup_helper_);
241 test::AshTestBase::SetUp();
243 virtual void TearDown() OVERRIDE {
244 Shell::GetInstance()->display_controller()->RemoveObserver(startup_helper_);
245 test::AshTestBase::TearDown();
248 const StartupHelper* startup_helper() const { return startup_helper_; }
251 StartupHelper* startup_helper_; // Owned by ash::Shell.
253 DISALLOW_COPY_AND_ASSIGN(DisplayControllerStartupTest);
256 class TestEventHandler : public ui::EventHandler {
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() {}
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) {
273 aura::Window* target = static_cast<aura::Window*>(event->target());
274 mouse_location_ = event->root_location();
275 target_root_ = target->GetRootWindow();
276 event->StopPropagation();
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)
285 touch_radius_x_ = event->radius_x();
286 touch_radius_y_ = event->radius_y();
287 event->StopPropagation();
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)
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();
303 event->StopPropagation();
306 std::string GetLocationAndReset() {
307 std::string result = mouse_location_.ToString();
308 mouse_location_.SetPoint(0, 0);
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_; }
321 gfx::Point mouse_location_;
322 aura::Window* target_root_;
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_;
331 DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
334 gfx::Display::Rotation GetStoredRotation(int64 id) {
335 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
338 float GetStoredUIScale(int64 id) {
339 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).
340 GetEffectiveUIScale();
344 void 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];
351 std::string GetXWindowName(aura::WindowTreeHost* host) {
353 XFetchName(gfx::GetXDisplay(), host->GetAcceleratedWidget(), &name);
354 std::string ret(name);
362 typedef test::AshTestBase DisplayControllerTest;
364 TEST_F(DisplayControllerShutdownTest, Shutdown) {
365 if (!SupportsMultipleDisplays())
368 UpdateDisplay("444x333, 200x200");
371 TEST_F(DisplayControllerStartupTest, Startup) {
372 if (!SupportsMultipleDisplays())
375 EXPECT_TRUE(startup_helper()->displays_initialized());
378 TEST_F(DisplayControllerTest, SecondaryDisplayLayout) {
379 if (!SupportsMultipleDisplays())
382 // Creates windows to catch activation change event.
383 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
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);
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
505 UpdateDisplay("500x500");
506 EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
507 EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
512 internal::DisplayInfo CreateDisplayInfo(int64 id,
513 const gfx::Rect& bounds,
514 float device_scale_factor) {
515 internal::DisplayInfo info(id, "", false);
516 info.SetBounds(bounds);
517 info.set_device_scale_factor(device_scale_factor);
523 TEST_F(DisplayControllerTest, MirrorToDockedWithFullscreen) {
524 // Creates windows to catch activation change event.
525 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
529 internal::DisplayManager* display_manager =
530 Shell::GetInstance()->display_manager();
532 const internal::DisplayInfo internal_display_info =
533 CreateDisplayInfo(1, gfx::Rect(0, 0, 500, 500), 2.0f);
534 const internal::DisplayInfo external_display_info =
535 CreateDisplayInfo(2, gfx::Rect(0, 0, 500, 500), 1.0f);
537 std::vector<internal::DisplayInfo> display_info_list;
539 display_info_list.push_back(internal_display_info);
540 display_info_list.push_back(external_display_info);
541 display_manager->OnNativeDisplaysChanged(display_info_list);
542 const int64 internal_display_id =
543 test::DisplayManagerTestApi(display_manager).
544 SetFirstDisplayAsInternalDisplay();
545 EXPECT_EQ(1, internal_display_id);
546 EXPECT_EQ(2U, display_manager->num_connected_displays());
547 EXPECT_EQ(1U, display_manager->GetNumDisplays());
549 wm::WindowState* window_state = wm::GetWindowState(w1.get());
550 const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
551 window_state->OnWMEvent(&toggle_fullscreen_event);
552 EXPECT_TRUE(window_state->IsFullscreen());
553 EXPECT_EQ("0,0 250x250", w1->bounds().ToString());
555 TestObserver observer;
556 display_info_list.clear();
557 display_info_list.push_back(external_display_info);
558 display_manager->OnNativeDisplaysChanged(display_info_list);
559 EXPECT_EQ(1U, display_manager->GetNumDisplays());
560 EXPECT_EQ(1U, display_manager->num_connected_displays());
561 EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
562 EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
563 EXPECT_EQ(1, observer.CountAndReset());
564 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
565 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
567 EXPECT_TRUE(window_state->IsFullscreen());
568 EXPECT_EQ("0,0 500x500", w1->bounds().ToString());
571 TEST_F(DisplayControllerTest, BoundsUpdated) {
572 if (!SupportsMultipleDisplays())
575 // Creates windows to catch activation change event.
576 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
579 TestObserver observer;
580 SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
581 UpdateDisplay("200x200,300x300"); // layout, resize and add.
582 EXPECT_EQ(1, observer.CountAndReset());
583 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
584 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
586 internal::DisplayManager* display_manager =
587 Shell::GetInstance()->display_manager();
588 gfx::Insets insets(5, 5, 5, 5);
589 display_manager->UpdateWorkAreaOfDisplay(
590 ScreenUtil::GetSecondaryDisplay().id(), insets);
592 EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString());
593 EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString());
594 EXPECT_EQ("5,205 290x290", GetSecondaryDisplay().work_area().ToString());
596 UpdateDisplay("400x400,200x200");
597 EXPECT_EQ(1, observer.CountAndReset()); // two resizes
598 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
599 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
600 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
601 EXPECT_EQ("0,400 200x200", GetSecondaryDisplay().bounds().ToString());
603 UpdateDisplay("400x400,300x300");
604 EXPECT_EQ(1, observer.CountAndReset());
605 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
606 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
607 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
608 EXPECT_EQ("0,400 300x300", GetSecondaryDisplay().bounds().ToString());
610 UpdateDisplay("400x400");
611 EXPECT_EQ(1, observer.CountAndReset());
612 EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
613 EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
614 EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
615 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
617 UpdateDisplay("400x500*2,300x300");
618 EXPECT_EQ(1, observer.CountAndReset());
619 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
620 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
621 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
622 EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
623 EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
626 UpdateDisplay("400x500*2,300x300");
627 EXPECT_EQ(0, observer.CountAndReset());
628 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
629 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
632 int64 primary_id = GetPrimaryDisplay().id();
633 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
634 EXPECT_EQ(1, observer.CountAndReset());
635 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
636 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
637 display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
638 EXPECT_EQ(0, observer.CountAndReset());
639 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
640 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
642 // UI scale is eanbled only on internal display.
643 int64 secondary_id = GetSecondaryDisplay().id();
644 gfx::Display::SetInternalDisplayId(secondary_id);
645 display_manager->SetDisplayUIScale(secondary_id, 1.125f);
646 EXPECT_EQ(1, observer.CountAndReset());
647 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
648 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
649 display_manager->SetDisplayUIScale(secondary_id, 1.125f);
650 EXPECT_EQ(0, observer.CountAndReset());
651 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
652 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
653 display_manager->SetDisplayUIScale(primary_id, 1.125f);
654 EXPECT_EQ(0, observer.CountAndReset());
655 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
656 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
657 display_manager->SetDisplayUIScale(primary_id, 1.125f);
658 EXPECT_EQ(0, observer.CountAndReset());
659 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
660 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
663 TEST_F(DisplayControllerTest, SwapPrimary) {
664 if (!SupportsMultipleDisplays())
667 DisplayController* display_controller =
668 Shell::GetInstance()->display_controller();
669 internal::DisplayManager* display_manager =
670 Shell::GetInstance()->display_manager();
672 UpdateDisplay("200x200,300x300");
673 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
674 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
676 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
677 display_manager->SetLayoutForCurrentDisplays(display_layout);
679 EXPECT_NE(primary_display.id(), secondary_display.id());
680 aura::Window* primary_root =
681 display_controller->GetRootWindowForDisplayId(primary_display.id());
682 aura::Window* secondary_root =
683 display_controller->GetRootWindowForDisplayId(secondary_display.id());
684 EXPECT_NE(primary_root, secondary_root);
685 aura::Window* shelf_window =
686 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
687 EXPECT_TRUE(primary_root->Contains(shelf_window));
688 EXPECT_FALSE(secondary_root->Contains(shelf_window));
689 EXPECT_EQ(primary_display.id(),
690 Shell::GetScreen()->GetDisplayNearestPoint(
691 gfx::Point(-100, -100)).id());
692 EXPECT_EQ(primary_display.id(),
693 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
695 EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
696 EXPECT_EQ("0,0 200x153", primary_display.work_area().ToString());
697 EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
698 EXPECT_EQ("200,0 300x253", secondary_display.work_area().ToString());
699 EXPECT_EQ("right, 50",
700 display_manager->GetCurrentDisplayLayout().ToString());
702 // Switch primary and secondary
703 display_controller->SetPrimaryDisplay(secondary_display);
704 const DisplayLayout& inverted_layout =
705 display_manager->GetCurrentDisplayLayout();
706 EXPECT_EQ("left, -50", inverted_layout.ToString());
708 EXPECT_EQ(secondary_display.id(),
709 Shell::GetScreen()->GetPrimaryDisplay().id());
710 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
711 EXPECT_EQ(primary_display.id(),
712 Shell::GetScreen()->GetDisplayNearestPoint(
713 gfx::Point(-100, -100)).id());
714 EXPECT_EQ(secondary_display.id(),
715 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
719 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
722 display_controller->GetRootWindowForDisplayId(primary_display.id()));
723 EXPECT_TRUE(primary_root->Contains(shelf_window));
724 EXPECT_FALSE(secondary_root->Contains(shelf_window));
726 // Test if the bounds are correctly swapped.
727 gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
728 gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay();
729 EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
730 EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString());
731 EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
733 EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString());
735 aura::WindowTracker tracker;
736 tracker.Add(primary_root);
737 tracker.Add(secondary_root);
739 // Deleting 2nd display should move the primary to original primary display.
740 UpdateDisplay("200x200");
741 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
742 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
743 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
744 EXPECT_EQ(primary_display.id(),
745 Shell::GetScreen()->GetDisplayNearestPoint(
746 gfx::Point(-100, -100)).id());
747 EXPECT_EQ(primary_display.id(),
748 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
749 EXPECT_TRUE(tracker.Contains(primary_root));
750 EXPECT_FALSE(tracker.Contains(secondary_root));
751 EXPECT_TRUE(primary_root->Contains(shelf_window));
754 TEST_F(DisplayControllerTest, FindNearestDisplay) {
755 if (!SupportsMultipleDisplays())
758 DisplayController* display_controller =
759 Shell::GetInstance()->display_controller();
760 internal::DisplayManager* display_manager =
761 Shell::GetInstance()->display_manager();
763 UpdateDisplay("200x200,300x300");
764 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
765 display_manager->SetLayoutForCurrentDisplays(display_layout);
767 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
768 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
769 EXPECT_NE(primary_display.id(), secondary_display.id());
770 aura::Window* primary_root =
771 display_controller->GetRootWindowForDisplayId(primary_display.id());
772 aura::Window* secondary_root =
773 display_controller->GetRootWindowForDisplayId(secondary_display.id());
774 EXPECT_NE(primary_root, secondary_root);
776 // Test that points outside of any display return the nearest display.
777 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
778 gfx::Point(-100, 0)).id());
779 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
780 gfx::Point(0, -100)).id());
781 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
782 gfx::Point(100, 100)).id());
783 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
784 gfx::Point(224, 25)).id());
785 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
786 gfx::Point(226, 25)).id());
787 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
788 gfx::Point(600, 100)).id());
789 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
790 gfx::Point(174, 225)).id());
791 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
792 gfx::Point(176, 225)).id());
793 EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint(
794 gfx::Point(300, 400)).id());
797 TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) {
798 if (!SupportsMultipleDisplays())
801 CommandLine::ForCurrentProcess()->AppendSwitch(
802 switches::kAshDisableAlternateShelfLayout);
804 DisplayController* display_controller =
805 Shell::GetInstance()->display_controller();
806 internal::DisplayManager* display_manager =
807 Shell::GetInstance()->display_manager();
809 UpdateDisplay("200x200,300x300");
810 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
811 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
813 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
814 display_manager->SetLayoutForCurrentDisplays(display_layout);
816 EXPECT_NE(primary_display.id(), secondary_display.id());
817 aura::Window* primary_root =
818 display_controller->GetRootWindowForDisplayId(primary_display.id());
819 aura::Window* secondary_root =
820 display_controller->GetRootWindowForDisplayId(secondary_display.id());
821 EXPECT_NE(primary_root, secondary_root);
822 aura::Window* shelf_window =
823 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
824 EXPECT_TRUE(primary_root->Contains(shelf_window));
825 EXPECT_FALSE(secondary_root->Contains(shelf_window));
826 EXPECT_EQ(primary_display.id(),
827 Shell::GetScreen()->GetDisplayNearestPoint(
828 gfx::Point(-100, -100)).id());
829 EXPECT_EQ(primary_display.id(),
830 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
832 EXPECT_EQ("0,0 200x200", primary_display.bounds().ToString());
833 EXPECT_EQ("0,0 200x152", primary_display.work_area().ToString());
834 EXPECT_EQ("200,0 300x300", secondary_display.bounds().ToString());
835 EXPECT_EQ("200,0 300x252", secondary_display.work_area().ToString());
836 EXPECT_EQ("right, 50",
837 display_manager->GetCurrentDisplayLayout().ToString());
839 // Switch primary and secondary
840 display_controller->SetPrimaryDisplay(secondary_display);
841 const DisplayLayout& inverted_layout =
842 display_manager->GetCurrentDisplayLayout();
843 EXPECT_EQ("left, -50", inverted_layout.ToString());
845 EXPECT_EQ(secondary_display.id(),
846 Shell::GetScreen()->GetPrimaryDisplay().id());
847 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
848 EXPECT_EQ(primary_display.id(),
849 Shell::GetScreen()->GetDisplayNearestPoint(
850 gfx::Point(-100, -100)).id());
851 EXPECT_EQ(secondary_display.id(),
852 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
856 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
859 display_controller->GetRootWindowForDisplayId(primary_display.id()));
860 EXPECT_TRUE(primary_root->Contains(shelf_window));
861 EXPECT_FALSE(secondary_root->Contains(shelf_window));
863 // Test if the bounds are correctly swapped.
864 gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay();
865 gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay();
866 EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString());
867 EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString());
868 EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString());
870 EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString());
872 aura::WindowTracker tracker;
873 tracker.Add(primary_root);
874 tracker.Add(secondary_root);
876 // Deleting 2nd display should move the primary to original primary display.
877 UpdateDisplay("200x200");
878 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
879 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
880 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
881 EXPECT_EQ(primary_display.id(),
882 Shell::GetScreen()->GetDisplayNearestPoint(
883 gfx::Point(-100, -100)).id());
884 EXPECT_EQ(primary_display.id(),
885 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
886 EXPECT_TRUE(tracker.Contains(primary_root));
887 EXPECT_FALSE(tracker.Contains(secondary_root));
888 EXPECT_TRUE(primary_root->Contains(shelf_window));
891 TEST_F(DisplayControllerTest, SwapPrimaryById) {
892 if (!SupportsMultipleDisplays())
895 DisplayController* display_controller =
896 Shell::GetInstance()->display_controller();
897 internal::DisplayManager* display_manager =
898 Shell::GetInstance()->display_manager();
900 UpdateDisplay("200x200,300x300");
901 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
902 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
904 DisplayLayout display_layout(DisplayLayout::RIGHT, 50);
905 display_manager->SetLayoutForCurrentDisplays(display_layout);
907 EXPECT_NE(primary_display.id(), secondary_display.id());
908 aura::Window* primary_root =
909 display_controller->GetRootWindowForDisplayId(primary_display.id());
910 aura::Window* secondary_root =
911 display_controller->GetRootWindowForDisplayId(secondary_display.id());
912 aura::Window* shelf_window =
913 Shelf::ForPrimaryDisplay()->shelf_widget()->GetNativeView();
914 EXPECT_TRUE(primary_root->Contains(shelf_window));
915 EXPECT_FALSE(secondary_root->Contains(shelf_window));
916 EXPECT_NE(primary_root, secondary_root);
917 EXPECT_EQ(primary_display.id(),
918 Shell::GetScreen()->GetDisplayNearestPoint(
919 gfx::Point(-100, -100)).id());
920 EXPECT_EQ(primary_display.id(),
921 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
923 // Switch primary and secondary by display ID.
924 TestObserver observer;
925 display_controller->SetPrimaryDisplayId(secondary_display.id());
926 EXPECT_EQ(secondary_display.id(),
927 Shell::GetScreen()->GetPrimaryDisplay().id());
928 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
929 EXPECT_LT(0, observer.CountAndReset());
933 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
936 display_controller->GetRootWindowForDisplayId(primary_display.id()));
937 EXPECT_TRUE(primary_root->Contains(shelf_window));
938 EXPECT_FALSE(secondary_root->Contains(shelf_window));
940 const DisplayLayout& inverted_layout =
941 display_manager->GetCurrentDisplayLayout();
943 EXPECT_EQ("left, -50", inverted_layout.ToString());
945 // Calling the same ID don't do anything.
946 display_controller->SetPrimaryDisplayId(secondary_display.id());
947 EXPECT_EQ(0, observer.CountAndReset());
949 aura::WindowTracker tracker;
950 tracker.Add(primary_root);
951 tracker.Add(secondary_root);
953 // Deleting 2nd display should move the primary to original primary display.
954 UpdateDisplay("200x200");
955 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
956 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
957 EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id());
958 EXPECT_EQ(primary_display.id(),
959 Shell::GetScreen()->GetDisplayNearestPoint(
960 gfx::Point(-100, -100)).id());
961 EXPECT_EQ(primary_display.id(),
962 Shell::GetScreen()->GetDisplayNearestWindow(NULL).id());
963 EXPECT_TRUE(tracker.Contains(primary_root));
964 EXPECT_FALSE(tracker.Contains(secondary_root));
965 EXPECT_TRUE(primary_root->Contains(shelf_window));
967 // Adding 2nd display with the same ID. The 2nd display should become primary
968 // since secondary id is still stored as desirable_primary_id.
969 std::vector<internal::DisplayInfo> display_info_list;
970 display_info_list.push_back(
971 display_manager->GetDisplayInfo(primary_display.id()));
972 display_info_list.push_back(
973 display_manager->GetDisplayInfo(secondary_display.id()));
974 display_manager->OnNativeDisplaysChanged(display_info_list);
976 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
977 EXPECT_EQ(secondary_display.id(),
978 Shell::GetScreen()->GetPrimaryDisplay().id());
979 EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id());
982 display_controller->GetRootWindowForDisplayId(secondary_display.id()));
985 display_controller->GetRootWindowForDisplayId(primary_display.id()));
986 EXPECT_TRUE(primary_root->Contains(shelf_window));
988 // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
989 // display shouldn't become primary.
990 UpdateDisplay("200x200");
991 internal::DisplayInfo third_display_info(
992 secondary_display.id() + 1, std::string(), false);
993 third_display_info.SetBounds(secondary_display.bounds());
994 ASSERT_NE(primary_display.id(), third_display_info.id());
996 const internal::DisplayInfo& primary_display_info =
997 display_manager->GetDisplayInfo(primary_display.id());
998 std::vector<internal::DisplayInfo> display_info_list2;
999 display_info_list2.push_back(primary_display_info);
1000 display_info_list2.push_back(third_display_info);
1001 display_manager->OnNativeDisplaysChanged(display_info_list2);
1002 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays());
1003 EXPECT_EQ(primary_display.id(),
1004 Shell::GetScreen()->GetPrimaryDisplay().id());
1005 EXPECT_EQ(third_display_info.id(), ScreenUtil::GetSecondaryDisplay().id());
1008 display_controller->GetRootWindowForDisplayId(primary_display.id()));
1011 display_controller->GetRootWindowForDisplayId(third_display_info.id()));
1012 EXPECT_TRUE(primary_root->Contains(shelf_window));
1015 TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) {
1016 if (!SupportsMultipleDisplays())
1019 DisplayController* display_controller =
1020 Shell::GetInstance()->display_controller();
1022 UpdateDisplay("200x200,200x200*2");
1023 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
1024 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay();
1026 aura::Window* primary_root =
1027 display_controller->GetRootWindowForDisplayId(primary_display.id());
1028 aura::Window* secondary_root =
1029 display_controller->GetRootWindowForDisplayId(secondary_display.id());
1030 EXPECT_NE(primary_root, secondary_root);
1032 test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager());
1034 EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
1035 device_scale_factor());
1036 primary_root->MoveCursorTo(gfx::Point(50, 50));
1037 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1038 EXPECT_EQ(2.0f, secondary_root->GetHost()->compositor()->
1039 device_scale_factor());
1040 secondary_root->MoveCursorTo(gfx::Point(50, 50));
1041 EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
1043 // Switch primary and secondary
1044 display_controller->SetPrimaryDisplay(secondary_display);
1046 // Cursor's device scale factor should be updated accroding to the swap of
1047 // primary and secondary.
1048 EXPECT_EQ(1.0f, secondary_root->GetHost()->compositor()->
1049 device_scale_factor());
1050 secondary_root->MoveCursorTo(gfx::Point(50, 50));
1051 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1052 primary_root->MoveCursorTo(gfx::Point(50, 50));
1053 EXPECT_EQ(2.0f, primary_root->GetHost()->compositor()->
1054 device_scale_factor());
1055 EXPECT_EQ(2.0f, test_api.GetDisplay().device_scale_factor());
1057 // Deleting 2nd display.
1058 UpdateDisplay("200x200");
1059 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task.
1061 // Cursor's device scale factor should be updated even without moving cursor.
1062 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1064 primary_root->MoveCursorTo(gfx::Point(50, 50));
1065 EXPECT_EQ(1.0f, primary_root->GetHost()->compositor()->
1066 device_scale_factor());
1067 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor());
1070 TEST_F(DisplayControllerTest, OverscanInsets) {
1071 if (!SupportsMultipleDisplays())
1074 DisplayController* display_controller =
1075 Shell::GetInstance()->display_controller();
1076 TestEventHandler event_handler;
1077 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1079 UpdateDisplay("120x200,300x400*2");
1080 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1081 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1083 display_controller->SetOverscanInsets(display1.id(),
1084 gfx::Insets(10, 15, 20, 25));
1085 EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString());
1086 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1087 EXPECT_EQ("80,0 150x200",
1088 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1090 aura::test::EventGenerator generator(root_windows[0]);
1091 generator.MoveMouseToInHost(20, 25);
1092 EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
1094 display_controller->SetOverscanInsets(display1.id(), gfx::Insets());
1095 EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString());
1096 EXPECT_EQ("120,0 150x200",
1097 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1099 generator.MoveMouseToInHost(30, 20);
1100 EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
1102 // Make sure the root window transformer uses correct scale
1103 // factor when swapping display. Test crbug.com/253690.
1104 UpdateDisplay("400x300*2,600x400/o");
1105 root_windows = Shell::GetAllRootWindows();
1107 Shell::GetAllRootWindows()[1]->GetHost()->
1108 GetRootTransform().TransformPoint(&point);
1109 EXPECT_EQ("15,10", point.ToString());
1111 display_controller->SwapPrimaryDisplay();
1112 point.SetPoint(0, 0);
1113 Shell::GetAllRootWindows()[1]->GetHost()->
1114 GetRootTransform().TransformPoint(&point);
1115 EXPECT_EQ("15,10", point.ToString());
1117 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1120 TEST_F(DisplayControllerTest, Rotate) {
1121 if (!SupportsMultipleDisplays())
1124 internal::DisplayManager* display_manager =
1125 Shell::GetInstance()->display_manager();
1126 TestEventHandler event_handler;
1127 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1129 UpdateDisplay("120x200,300x400*2");
1130 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1131 int64 display2_id = ScreenUtil::GetSecondaryDisplay().id();
1132 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1133 aura::test::EventGenerator generator1(root_windows[0]);
1135 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1136 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1137 EXPECT_EQ("120,0 150x200",
1138 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1139 generator1.MoveMouseToInHost(50, 40);
1140 EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
1141 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
1142 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1144 display_manager->SetDisplayRotation(display1.id(),
1145 gfx::Display::ROTATE_90);
1146 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1147 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
1148 EXPECT_EQ("200,0 150x200",
1149 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1150 generator1.MoveMouseToInHost(50, 40);
1151 EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
1152 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1153 EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
1155 DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
1156 display_manager->SetLayoutForCurrentDisplays(display_layout);
1157 EXPECT_EQ("50,120 150x200",
1158 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1160 display_manager->SetDisplayRotation(display2_id,
1161 gfx::Display::ROTATE_270);
1162 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
1163 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1164 EXPECT_EQ("50,120 200x150",
1165 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1166 EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
1167 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1169 #if !defined(OS_WIN)
1170 aura::test::EventGenerator generator2(root_windows[1]);
1171 generator2.MoveMouseToInHost(50, 40);
1172 EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
1173 display_manager->SetDisplayRotation(display1.id(),
1174 gfx::Display::ROTATE_180);
1176 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
1177 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
1178 // Dislay must share at least 100, so the x's offset becomes 20.
1179 EXPECT_EQ("20,200 200x150",
1180 ScreenUtil::GetSecondaryDisplay().bounds().ToString());
1181 EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
1182 EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
1184 generator1.MoveMouseToInHost(50, 40);
1185 EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
1188 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1191 TEST_F(DisplayControllerTest, ScaleRootWindow) {
1192 if (!SupportsMultipleDisplays())
1195 TestEventHandler event_handler;
1196 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1198 UpdateDisplay("600x400*2@1.5,500x300");
1200 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1201 gfx::Display::SetInternalDisplayId(display1.id());
1203 gfx::Display display2 = ScreenUtil::GetSecondaryDisplay();
1204 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1205 EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1206 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1207 EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
1208 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1209 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1211 aura::test::EventGenerator generator(root_windows[0]);
1212 generator.MoveMouseToInHost(599, 200);
1213 EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
1215 internal::DisplayManager* display_manager =
1216 Shell::GetInstance()->display_manager();
1217 display_manager->SetDisplayUIScale(display1.id(), 1.25f);
1218 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1219 display2 = ScreenUtil::GetSecondaryDisplay();
1220 EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
1221 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
1222 EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
1223 EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
1224 EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
1226 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1229 TEST_F(DisplayControllerTest, TouchScale) {
1230 if (!SupportsMultipleDisplays())
1233 TestEventHandler event_handler;
1234 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1236 UpdateDisplay("200x200*2");
1237 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
1238 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1239 aura::Window* root_window = root_windows[0];
1240 aura::test::EventGenerator generator(root_window);
1242 generator.PressMoveAndReleaseTouchTo(50, 50);
1243 // Default test touches have radius_x/y = 1.0, with device scale
1244 // factor = 2, the scaled radius_x/y should be 0.5.
1245 EXPECT_EQ(0.5, event_handler.touch_radius_x());
1246 EXPECT_EQ(0.5, event_handler.touch_radius_y());
1248 generator.ScrollSequence(gfx::Point(0,0),
1249 base::TimeDelta::FromMilliseconds(100),
1252 // ordinal_offset is invariant to the device scale factor.
1253 EXPECT_EQ(event_handler.scroll_x_offset(),
1254 event_handler.scroll_x_offset_ordinal());
1255 EXPECT_EQ(event_handler.scroll_y_offset(),
1256 event_handler.scroll_y_offset_ordinal());
1258 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1261 TEST_F(DisplayControllerTest, ConvertHostToRootCoords) {
1262 if (!SupportsMultipleDisplays())
1265 TestEventHandler event_handler;
1266 Shell::GetInstance()->AddPreTargetHandler(&event_handler);
1268 UpdateDisplay("600x400*2/r@1.5");
1270 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
1271 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1272 EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1273 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1274 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1276 aura::test::EventGenerator generator(root_windows[0]);
1277 generator.MoveMouseToInHost(0, 0);
1278 EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1279 generator.MoveMouseToInHost(599, 0);
1280 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1281 generator.MoveMouseToInHost(599, 399);
1282 EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1283 generator.MoveMouseToInHost(0, 399);
1284 EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1286 UpdateDisplay("600x400*2/u@1.5");
1287 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1288 root_windows = Shell::GetAllRootWindows();
1289 EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
1290 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
1291 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1293 generator.MoveMouseToInHost(0, 0);
1294 EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
1295 generator.MoveMouseToInHost(599, 0);
1296 EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
1297 generator.MoveMouseToInHost(599, 399);
1298 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1299 generator.MoveMouseToInHost(0, 399);
1300 EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
1302 UpdateDisplay("600x400*2/l@1.5");
1303 display1 = Shell::GetScreen()->GetPrimaryDisplay();
1304 root_windows = Shell::GetAllRootWindows();
1305 EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
1306 EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
1307 EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
1309 generator.MoveMouseToInHost(0, 0);
1310 EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
1311 generator.MoveMouseToInHost(599, 0);
1312 EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
1313 generator.MoveMouseToInHost(599, 399);
1314 EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
1315 generator.MoveMouseToInHost(0, 399);
1316 EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
1318 Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
1323 internal::DisplayInfo CreateDisplayInfo(int64 id,
1325 gfx::Display::Rotation rotation) {
1326 internal::DisplayInfo info(id, "", false);
1327 info.SetBounds(gfx::Rect(0, y, 500, 500));
1328 info.set_rotation(rotation);
1334 // Make sure that the compositor based mirroring can switch
1335 // from/to dock mode.
1336 TEST_F(DisplayControllerTest, DockToSingle) {
1337 if (!SupportsMultipleDisplays())
1340 internal::DisplayManager* display_manager =
1341 Shell::GetInstance()->display_manager();
1343 const int64 internal_id = 1;
1345 const internal::DisplayInfo internal_display_info =
1346 CreateDisplayInfo(internal_id, 0, gfx::Display::ROTATE_0);
1347 const internal::DisplayInfo external_display_info =
1348 CreateDisplayInfo(2, 1, gfx::Display::ROTATE_90);
1350 std::vector<internal::DisplayInfo> display_info_list;
1352 display_info_list.push_back(internal_display_info);
1353 display_info_list.push_back(external_display_info);
1354 display_manager->OnNativeDisplaysChanged(display_info_list);
1355 const int64 internal_display_id =
1356 test::DisplayManagerTestApi(display_manager).
1357 SetFirstDisplayAsInternalDisplay();
1358 EXPECT_EQ(internal_id, internal_display_id);
1359 EXPECT_EQ(2U, display_manager->GetNumDisplays());
1362 display_info_list.clear();
1363 display_info_list.push_back(external_display_info);
1364 display_manager->OnNativeDisplaysChanged(display_info_list);
1365 EXPECT_EQ(1U, display_manager->GetNumDisplays());
1366 EXPECT_FALSE(Shell::GetPrimaryRootWindow()->GetHost()->
1367 GetRootTransform().IsIdentityOrIntegerTranslation());
1369 // Switch to single mode and make sure the transform is the one
1370 // for the internal display.
1371 display_info_list.clear();
1372 display_info_list.push_back(internal_display_info);
1373 display_manager->OnNativeDisplaysChanged(display_info_list);
1374 EXPECT_TRUE(Shell::GetPrimaryRootWindow()->GetHost()->
1375 GetRootTransform().IsIdentityOrIntegerTranslation());
1378 #if defined(USE_X11)
1379 TEST_F(DisplayControllerTest, XWidowNameForRootWindow) {
1380 EXPECT_EQ("aura_root_0", GetXWindowName(
1381 Shell::GetPrimaryRootWindow()->GetHost()));
1383 // Multiple display.
1384 UpdateDisplay("200x200,300x300");
1385 aura::Window* primary, *secondary;
1386 GetPrimaryAndSeconary(&primary, &secondary);
1387 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1388 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1391 primary = secondary = NULL;
1392 Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
1393 GetPrimaryAndSeconary(&primary, &secondary);
1394 EXPECT_EQ("aura_root_0", GetXWindowName(primary->GetHost()));
1395 EXPECT_EQ("aura_root_x", GetXWindowName(secondary->GetHost()));
1397 // Switching back to single display.
1398 UpdateDisplay("300x400");
1399 EXPECT_EQ("aura_root_0", GetXWindowName(
1400 Shell::GetPrimaryRootWindow()->GetHost()));