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