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