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