display_controller_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/activation_change_observer.h" 24#include "ui/aura/client/activation_client.h" 25#include "ui/aura/client/focus_change_observer.h" 26#include "ui/aura/client/focus_client.h" 27#include "ui/aura/env.h" 28#include "ui/aura/test/event_generator.h" 29#include "ui/aura/window_event_dispatcher.h" 30#include "ui/aura/window_tracker.h" 31#include "ui/events/event_handler.h" 32#include "ui/gfx/display.h" 33#include "ui/gfx/screen.h" 34#include "ui/views/widget/widget.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 512internal::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); 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 internal::DisplayManager* display_manager = 530 Shell::GetInstance()->display_manager(); 531 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); 536 537 std::vector<internal::DisplayInfo> display_info_list; 538 // Mirror. 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()); 548 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()); 554 // Dock mode. 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()); 566 567 EXPECT_TRUE(window_state->IsFullscreen()); 568 EXPECT_EQ("0,0 500x500", w1->bounds().ToString()); 569} 570 571TEST_F(DisplayControllerTest, BoundsUpdated) { 572 if (!SupportsMultipleDisplays()) 573 return; 574 575 // Creates windows to catch activation change event. 576 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1)); 577 w1->Focus(); 578 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()); 585 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); 591 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()); 595 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()); 602 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()); 609 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()); 616 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()); 624 625 // No change 626 UpdateDisplay("400x500*2,300x300"); 627 EXPECT_EQ(0, observer.CountAndReset()); 628 EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); 629 EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); 630 631 // Rotation 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()); 641 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()); 661} 662 663TEST_F(DisplayControllerTest, SwapPrimary) { 664 if (!SupportsMultipleDisplays()) 665 return; 666 667 DisplayController* display_controller = 668 Shell::GetInstance()->display_controller(); 669 internal::DisplayManager* display_manager = 670 Shell::GetInstance()->display_manager(); 671 672 UpdateDisplay("200x200,300x300"); 673 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 674 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); 675 676 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 677 display_manager->SetLayoutForCurrentDisplays(display_layout); 678 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()); 694 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()); 701 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()); 707 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()); 716 717 EXPECT_EQ( 718 primary_root, 719 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 720 EXPECT_EQ( 721 secondary_root, 722 display_controller->GetRootWindowForDisplayId(primary_display.id())); 723 EXPECT_TRUE(primary_root->Contains(shelf_window)); 724 EXPECT_FALSE(secondary_root->Contains(shelf_window)); 725 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()); 732 733 EXPECT_EQ("-200,-50 200x153", swapped_secondary.work_area().ToString()); 734 735 aura::WindowTracker tracker; 736 tracker.Add(primary_root); 737 tracker.Add(secondary_root); 738 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)); 752} 753 754TEST_F(DisplayControllerTest, FindNearestDisplay) { 755 if (!SupportsMultipleDisplays()) 756 return; 757 758 DisplayController* display_controller = 759 Shell::GetInstance()->display_controller(); 760 internal::DisplayManager* display_manager = 761 Shell::GetInstance()->display_manager(); 762 763 UpdateDisplay("200x200,300x300"); 764 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 765 display_manager->SetLayoutForCurrentDisplays(display_layout); 766 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); 775 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()); 795} 796 797TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { 798 if (!SupportsMultipleDisplays()) 799 return; 800 801 CommandLine::ForCurrentProcess()->AppendSwitch( 802 switches::kAshDisableAlternateShelfLayout); 803 804 DisplayController* display_controller = 805 Shell::GetInstance()->display_controller(); 806 internal::DisplayManager* display_manager = 807 Shell::GetInstance()->display_manager(); 808 809 UpdateDisplay("200x200,300x300"); 810 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 811 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); 812 813 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 814 display_manager->SetLayoutForCurrentDisplays(display_layout); 815 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()); 831 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()); 838 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()); 844 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()); 853 854 EXPECT_EQ( 855 primary_root, 856 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 857 EXPECT_EQ( 858 secondary_root, 859 display_controller->GetRootWindowForDisplayId(primary_display.id())); 860 EXPECT_TRUE(primary_root->Contains(shelf_window)); 861 EXPECT_FALSE(secondary_root->Contains(shelf_window)); 862 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()); 869 870 EXPECT_EQ("-200,-50 200x152", swapped_secondary.work_area().ToString()); 871 872 aura::WindowTracker tracker; 873 tracker.Add(primary_root); 874 tracker.Add(secondary_root); 875 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)); 889} 890 891TEST_F(DisplayControllerTest, SwapPrimaryById) { 892 if (!SupportsMultipleDisplays()) 893 return; 894 895 DisplayController* display_controller = 896 Shell::GetInstance()->display_controller(); 897 internal::DisplayManager* display_manager = 898 Shell::GetInstance()->display_manager(); 899 900 UpdateDisplay("200x200,300x300"); 901 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 902 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); 903 904 DisplayLayout display_layout(DisplayLayout::RIGHT, 50); 905 display_manager->SetLayoutForCurrentDisplays(display_layout); 906 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()); 922 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()); 930 931 EXPECT_EQ( 932 primary_root, 933 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 934 EXPECT_EQ( 935 secondary_root, 936 display_controller->GetRootWindowForDisplayId(primary_display.id())); 937 EXPECT_TRUE(primary_root->Contains(shelf_window)); 938 EXPECT_FALSE(secondary_root->Contains(shelf_window)); 939 940 const DisplayLayout& inverted_layout = 941 display_manager->GetCurrentDisplayLayout(); 942 943 EXPECT_EQ("left, -50", inverted_layout.ToString()); 944 945 // Calling the same ID don't do anything. 946 display_controller->SetPrimaryDisplayId(secondary_display.id()); 947 EXPECT_EQ(0, observer.CountAndReset()); 948 949 aura::WindowTracker tracker; 950 tracker.Add(primary_root); 951 tracker.Add(secondary_root); 952 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)); 966 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); 975 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()); 980 EXPECT_EQ( 981 primary_root, 982 display_controller->GetRootWindowForDisplayId(secondary_display.id())); 983 EXPECT_NE( 984 primary_root, 985 display_controller->GetRootWindowForDisplayId(primary_display.id())); 986 EXPECT_TRUE(primary_root->Contains(shelf_window)); 987 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()); 995 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()); 1006 EXPECT_EQ( 1007 primary_root, 1008 display_controller->GetRootWindowForDisplayId(primary_display.id())); 1009 EXPECT_NE( 1010 primary_root, 1011 display_controller->GetRootWindowForDisplayId(third_display_info.id())); 1012 EXPECT_TRUE(primary_root->Contains(shelf_window)); 1013} 1014 1015TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) { 1016 if (!SupportsMultipleDisplays()) 1017 return; 1018 1019 DisplayController* display_controller = 1020 Shell::GetInstance()->display_controller(); 1021 1022 UpdateDisplay("200x200,200x200*2"); 1023 gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 1024 gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); 1025 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); 1031 1032 test::CursorManagerTestApi test_api(Shell::GetInstance()->cursor_manager()); 1033 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()); 1042 1043 // Switch primary and secondary 1044 display_controller->SetPrimaryDisplay(secondary_display); 1045 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()); 1056 1057 // Deleting 2nd display. 1058 UpdateDisplay("200x200"); 1059 RunAllPendingInMessageLoop(); // RootWindow is deleted in a posted task. 1060 1061 // Cursor's device scale factor should be updated even without moving cursor. 1062 EXPECT_EQ(1.0f, test_api.GetDisplay().device_scale_factor()); 1063 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()); 1068} 1069 1070TEST_F(DisplayControllerTest, OverscanInsets) { 1071 if (!SupportsMultipleDisplays()) 1072 return; 1073 1074 DisplayController* display_controller = 1075 Shell::GetInstance()->display_controller(); 1076 TestEventHandler event_handler; 1077 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1078 1079 UpdateDisplay("120x200,300x400*2"); 1080 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1081 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1082 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()); 1089 1090 aura::test::EventGenerator generator(root_windows[0]); 1091 generator.MoveMouseToInHost(20, 25); 1092 EXPECT_EQ("5,15", event_handler.GetLocationAndReset()); 1093 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()); 1098 1099 generator.MoveMouseToInHost(30, 20); 1100 EXPECT_EQ("30,20", event_handler.GetLocationAndReset()); 1101 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(); 1106 gfx::Point point; 1107 Shell::GetAllRootWindows()[1]->GetHost()-> 1108 GetRootTransform().TransformPoint(&point); 1109 EXPECT_EQ("15,10", point.ToString()); 1110 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()); 1116 1117 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1118} 1119 1120TEST_F(DisplayControllerTest, Rotate) { 1121 if (!SupportsMultipleDisplays()) 1122 return; 1123 1124 internal::DisplayManager* display_manager = 1125 Shell::GetInstance()->display_manager(); 1126 TestEventHandler event_handler; 1127 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1128 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]); 1134 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)); 1143 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)); 1154 1155 DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); 1156 display_manager->SetLayoutForCurrentDisplays(display_layout); 1157 EXPECT_EQ("50,120 150x200", 1158 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 1159 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)); 1168 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); 1175 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)); 1183 1184 generator1.MoveMouseToInHost(50, 40); 1185 EXPECT_EQ("69,159", event_handler.GetLocationAndReset()); 1186#endif 1187 1188 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1189} 1190 1191TEST_F(DisplayControllerTest, ScaleRootWindow) { 1192 if (!SupportsMultipleDisplays()) 1193 return; 1194 1195 TestEventHandler event_handler; 1196 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1197 1198 UpdateDisplay("600x400*2@1.5,500x300"); 1199 1200 gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); 1201 gfx::Display::SetInternalDisplayId(display1.id()); 1202 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())); 1210 1211 aura::test::EventGenerator generator(root_windows[0]); 1212 generator.MoveMouseToInHost(599, 200); 1213 EXPECT_EQ("449,150", event_handler.GetLocationAndReset()); 1214 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())); 1225 1226 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1227} 1228 1229TEST_F(DisplayControllerTest, TouchScale) { 1230 if (!SupportsMultipleDisplays()) 1231 return; 1232 1233 TestEventHandler event_handler; 1234 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1235 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); 1241 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()); 1247 1248 generator.ScrollSequence(gfx::Point(0,0), 1249 base::TimeDelta::FromMilliseconds(100), 1250 10.0, 1.0, 5, 1); 1251 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()); 1257 1258 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1259} 1260 1261TEST_F(DisplayControllerTest, ConvertHostToRootCoords) { 1262 if (!SupportsMultipleDisplays()) 1263 return; 1264 1265 TestEventHandler event_handler; 1266 Shell::GetInstance()->AddPreTargetHandler(&event_handler); 1267 1268 UpdateDisplay("600x400*2/r@1.5"); 1269 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())); 1275 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()); 1285 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())); 1292 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()); 1301 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())); 1308 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()); 1317 1318 Shell::GetInstance()->RemovePreTargetHandler(&event_handler); 1319} 1320 1321namespace { 1322 1323internal::DisplayInfo CreateDisplayInfo(int64 id, 1324 int y, 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); 1329 return info; 1330} 1331 1332} // namespace 1333 1334// Make sure that the compositor based mirroring can switch 1335// from/to dock mode. 1336TEST_F(DisplayControllerTest, DockToSingle) { 1337 if (!SupportsMultipleDisplays()) 1338 return; 1339 1340 internal::DisplayManager* display_manager = 1341 Shell::GetInstance()->display_manager(); 1342 1343 const int64 internal_id = 1; 1344 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); 1349 1350 std::vector<internal::DisplayInfo> display_info_list; 1351 // Extended 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()); 1360 1361 // Dock mode. 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()); 1368 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()); 1376} 1377 1378#if defined(USE_X11) 1379TEST_F(DisplayControllerTest, XWidowNameForRootWindow) { 1380 EXPECT_EQ("aura_root_0", GetXWindowName( 1381 Shell::GetPrimaryRootWindow()->GetHost())); 1382 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())); 1389 1390 // Swap primary. 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())); 1396 1397 // Switching back to single display. 1398 UpdateDisplay("300x400"); 1399 EXPECT_EQ("aura_root_0", GetXWindowName( 1400 Shell::GetPrimaryRootWindow()->GetHost())); 1401} 1402#endif 1403 1404} // namespace ash 1405