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