display_manager_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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_manager.h" 6 7#include "ash/display/display_controller.h" 8#include "ash/screen_ash.h" 9#include "ash/shell.h" 10#include "ash/test/ash_test_base.h" 11#include "ash/test/display_manager_test_api.h" 12#include "ash/test/mirror_window_test_api.h" 13#include "base/format_macros.h" 14#include "base/strings/string_number_conversions.h" 15#include "base/strings/stringprintf.h" 16#include "ui/aura/env.h" 17#include "ui/aura/root_window.h" 18#include "ui/aura/test/event_generator.h" 19#include "ui/aura/window_observer.h" 20#include "ui/gfx/display_observer.h" 21#include "ui/gfx/display.h" 22 23namespace ash { 24namespace internal { 25 26using std::vector; 27using std::string; 28 29using base::StringPrintf; 30 31namespace { 32 33std::string ToDisplayName(int64 id) { 34 return "x-" + base::Int64ToString(id); 35} 36 37} // namespace 38 39class DisplayManagerTest : public test::AshTestBase, 40 public gfx::DisplayObserver, 41 public aura::WindowObserver { 42 public: 43 DisplayManagerTest() 44 : removed_count_(0U), 45 root_window_destroyed_(false) { 46 } 47 virtual ~DisplayManagerTest() {} 48 49 virtual void SetUp() OVERRIDE { 50 AshTestBase::SetUp(); 51 Shell::GetScreen()->AddObserver(this); 52 Shell::GetPrimaryRootWindow()->AddObserver(this); 53 } 54 virtual void TearDown() OVERRIDE { 55 Shell::GetPrimaryRootWindow()->RemoveObserver(this); 56 Shell::GetScreen()->RemoveObserver(this); 57 AshTestBase::TearDown(); 58 } 59 60 DisplayManager* display_manager() { 61 return Shell::GetInstance()->display_manager(); 62 } 63 const vector<gfx::Display>& changed() const { return changed_; } 64 const vector<gfx::Display>& added() const { return added_; } 65 66 string GetCountSummary() const { 67 return StringPrintf("%"PRIuS" %"PRIuS" %"PRIuS, 68 changed_.size(), added_.size(), removed_count_); 69 } 70 71 void reset() { 72 changed_.clear(); 73 added_.clear(); 74 removed_count_ = 0U; 75 root_window_destroyed_ = false; 76 } 77 78 bool root_window_destroyed() const { 79 return root_window_destroyed_; 80 } 81 82 const DisplayInfo& GetDisplayInfo(const gfx::Display& display) { 83 return display_manager()->GetDisplayInfo(display.id()); 84 } 85 86 const DisplayInfo& GetDisplayInfoAt(int index) { 87 return GetDisplayInfo(*display_manager()->GetDisplayAt(index)); 88 } 89 90 const gfx::Display& FindDisplayForId(int64 id) { 91 return display_manager()->FindDisplayForId(id); 92 } 93 94 const DisplayInfo& FindDisplayInfoForId(int64 id) { 95 return GetDisplayInfo(display_manager()->FindDisplayForId(id)); 96 } 97 98 const gfx::Display GetMirroredDisplay() { 99 test::MirrorWindowTestApi test_api; 100 return Shell::GetInstance()->display_manager()-> 101 FindDisplayForRootWindow(test_api.GetRootWindow()); 102 } 103 104 // aura::DisplayObserver overrides: 105 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { 106 changed_.push_back(display); 107 } 108 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 109 added_.push_back(new_display); 110 } 111 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 112 ++removed_count_; 113 } 114 115 // aura::WindowObserver overrides: 116 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 117 ASSERT_EQ(Shell::GetPrimaryRootWindow(), window); 118 root_window_destroyed_ = true; 119 } 120 121 private: 122 vector<gfx::Display> changed_; 123 vector<gfx::Display> added_; 124 size_t removed_count_; 125 bool root_window_destroyed_; 126 127 DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest); 128}; 129 130TEST_F(DisplayManagerTest, UpdateDisplayTest) { 131 if (!SupportsMultipleDisplays()) 132 return; 133 134 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 135 136 // Update primary and add seconary. 137 UpdateDisplay("100+0-500x500,0+501-400x400"); 138 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 139 EXPECT_EQ("0,0 500x500", 140 display_manager()->GetDisplayAt(0)->bounds().ToString()); 141 142 EXPECT_EQ("1 1 0", GetCountSummary()); 143 EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id()); 144 EXPECT_EQ(display_manager()->GetDisplayAt(1)->id(), added()[0].id()); 145 EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString()); 146 // Secondary display is on right. 147 EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString()); 148 EXPECT_EQ("0,501 400x400", 149 GetDisplayInfo(added()[0]).bounds_in_pixel().ToString()); 150 reset(); 151 152 // Delete secondary. 153 UpdateDisplay("100+0-500x500"); 154 EXPECT_EQ("0 0 1", GetCountSummary()); 155 reset(); 156 157 // Change primary. 158 UpdateDisplay("1+1-1000x600"); 159 EXPECT_EQ("1 0 0", GetCountSummary()); 160 EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id()); 161 EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString()); 162 reset(); 163 164 // Add secondary. 165 UpdateDisplay("1+1-1000x600,1002+0-600x400"); 166 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 167 EXPECT_EQ("0 1 0", GetCountSummary()); 168 EXPECT_EQ(display_manager()->GetDisplayAt(1)->id(), added()[0].id()); 169 // Secondary display is on right. 170 EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString()); 171 EXPECT_EQ("1002,0 600x400", 172 GetDisplayInfo(added()[0]).bounds_in_pixel().ToString()); 173 reset(); 174 175 // Secondary removed, primary changed. 176 UpdateDisplay("1+1-800x300"); 177 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 178 EXPECT_EQ("1 0 1", GetCountSummary()); 179 EXPECT_EQ(display_manager()->GetDisplayAt(0)->id(), changed()[0].id()); 180 EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString()); 181 reset(); 182 183 // # of display can go to zero when screen is off. 184 const vector<DisplayInfo> empty; 185 display_manager()->OnNativeDisplaysChanged(empty); 186 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 187 EXPECT_EQ("0 0 0", GetCountSummary()); 188 EXPECT_FALSE(root_window_destroyed()); 189 // Display configuration stays the same 190 EXPECT_EQ("0,0 800x300", 191 display_manager()->GetDisplayAt(0)->bounds().ToString()); 192 reset(); 193 194 // Connect to display again 195 UpdateDisplay("100+100-500x400"); 196 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 197 EXPECT_EQ("1 0 0", GetCountSummary()); 198 EXPECT_FALSE(root_window_destroyed()); 199 EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString()); 200 EXPECT_EQ("100,100 500x400", 201 GetDisplayInfo(changed()[0]).bounds_in_pixel().ToString()); 202 reset(); 203 204 // Go back to zero and wake up with multiple displays. 205 display_manager()->OnNativeDisplaysChanged(empty); 206 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 207 EXPECT_FALSE(root_window_destroyed()); 208 reset(); 209 210 // Add secondary. 211 UpdateDisplay("0+0-1000x600,1000+1000-600x400"); 212 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 213 EXPECT_EQ("0,0 1000x600", 214 display_manager()->GetDisplayAt(0)->bounds().ToString()); 215 // Secondary display is on right. 216 EXPECT_EQ("1000,0 600x400", 217 display_manager()->GetDisplayAt(1)->bounds().ToString()); 218 EXPECT_EQ("1000,1000 600x400", 219 GetDisplayInfoAt(1).bounds_in_pixel().ToString()); 220 reset(); 221 222 // Changing primary will update secondary as well. 223 UpdateDisplay("0+0-800x600,1000+1000-600x400"); 224 EXPECT_EQ("2 0 0", GetCountSummary()); 225 reset(); 226 EXPECT_EQ("0,0 800x600", 227 display_manager()->GetDisplayAt(0)->bounds().ToString()); 228 EXPECT_EQ("800,0 600x400", 229 display_manager()->GetDisplayAt(1)->bounds().ToString()); 230} 231 232// Test in emulation mode (use_fullscreen_host_window=false) 233TEST_F(DisplayManagerTest, EmulatorTest) { 234 if (!SupportsMultipleDisplays()) 235 return; 236 237 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 238 239 display_manager()->AddRemoveDisplay(); 240 // Update primary and add seconary. 241 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 242 EXPECT_EQ("0 1 0", GetCountSummary()); 243 reset(); 244 245 display_manager()->AddRemoveDisplay(); 246 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 247 EXPECT_EQ("0 0 1", GetCountSummary()); 248 reset(); 249 250 display_manager()->AddRemoveDisplay(); 251 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 252 EXPECT_EQ("0 1 0", GetCountSummary()); 253 reset(); 254} 255 256TEST_F(DisplayManagerTest, OverscanInsetsTest) { 257 if (!SupportsMultipleDisplays()) 258 return; 259 260 UpdateDisplay("0+0-500x500,0+501-400x400"); 261 reset(); 262 ASSERT_EQ(2u, display_manager()->GetNumDisplays()); 263 const DisplayInfo& display_info1 = GetDisplayInfoAt(0); 264 const DisplayInfo& display_info2 = GetDisplayInfoAt(1); 265 display_manager()->SetOverscanInsets( 266 display_info2.id(), gfx::Insets(13, 12, 11, 10)); 267 268 std::vector<gfx::Display> changed_displays = changed(); 269 EXPECT_EQ(1u, changed_displays.size()); 270 EXPECT_EQ(display_info2.id(), changed_displays[0].id()); 271 EXPECT_EQ("0,0 500x500", 272 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 273 DisplayInfo updated_display_info2 = GetDisplayInfoAt(1); 274 EXPECT_EQ("0,501 400x400", 275 updated_display_info2.bounds_in_pixel().ToString()); 276 EXPECT_EQ("378x376", 277 updated_display_info2.size_in_pixel().ToString()); 278 EXPECT_EQ("13,12,11,10", 279 updated_display_info2.overscan_insets_in_dip().ToString()); 280 EXPECT_EQ("500,0 378x376", 281 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 282 283 // Make sure that SetOverscanInsets() is idempotent. 284 display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets()); 285 display_manager()->SetOverscanInsets( 286 display_info2.id(), gfx::Insets(13, 12, 11, 10)); 287 EXPECT_EQ("0,0 500x500", 288 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 289 updated_display_info2 = GetDisplayInfoAt(1); 290 EXPECT_EQ("0,501 400x400", 291 updated_display_info2.bounds_in_pixel().ToString()); 292 EXPECT_EQ("378x376", 293 updated_display_info2.size_in_pixel().ToString()); 294 EXPECT_EQ("13,12,11,10", 295 updated_display_info2.overscan_insets_in_dip().ToString()); 296 297 display_manager()->SetOverscanInsets( 298 display_info2.id(), gfx::Insets(10, 11, 12, 13)); 299 EXPECT_EQ("0,0 500x500", 300 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 301 EXPECT_EQ("376x378", 302 GetDisplayInfoAt(1).size_in_pixel().ToString()); 303 EXPECT_EQ("10,11,12,13", 304 GetDisplayInfoAt(1).overscan_insets_in_dip().ToString()); 305 306 // Recreate a new 2nd display. It won't apply the overscan inset because the 307 // new display has a different ID. 308 UpdateDisplay("0+0-500x500"); 309 UpdateDisplay("0+0-500x500,0+501-400x400"); 310 EXPECT_EQ("0,0 500x500", 311 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 312 EXPECT_EQ("0,501 400x400", 313 GetDisplayInfoAt(1).bounds_in_pixel().ToString()); 314 315 // Recreate the displays with the same ID. It should apply the overscan 316 // inset. 317 UpdateDisplay("0+0-500x500"); 318 std::vector<DisplayInfo> display_info_list; 319 display_info_list.push_back(display_info1); 320 display_info_list.push_back(display_info2); 321 display_manager()->OnNativeDisplaysChanged(display_info_list); 322 EXPECT_EQ("1,1 500x500", 323 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 324 updated_display_info2 = GetDisplayInfoAt(1); 325 EXPECT_EQ("376x378", 326 updated_display_info2.size_in_pixel().ToString()); 327 EXPECT_EQ("10,11,12,13", 328 updated_display_info2.overscan_insets_in_dip().ToString()); 329 330 // HiDPI but overscan display. The specified insets size should be doubled. 331 UpdateDisplay("0+0-500x500,0+501-400x400*2"); 332 display_manager()->SetOverscanInsets( 333 display_manager()->GetDisplayAt(1)->id(), gfx::Insets(4, 5, 6, 7)); 334 EXPECT_EQ("0,0 500x500", 335 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 336 updated_display_info2 = GetDisplayInfoAt(1); 337 EXPECT_EQ("0,501 400x400", 338 updated_display_info2.bounds_in_pixel().ToString()); 339 EXPECT_EQ("376x380", 340 updated_display_info2.size_in_pixel().ToString()); 341 EXPECT_EQ("4,5,6,7", 342 updated_display_info2.overscan_insets_in_dip().ToString()); 343 EXPECT_EQ("8,10,12,14", 344 updated_display_info2.GetOverscanInsetsInPixel().ToString()); 345 346 // Make sure switching primary display applies the overscan offset only once. 347 ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( 348 ScreenAsh::GetSecondaryDisplay()); 349 EXPECT_EQ("-500,0 500x500", 350 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 351 EXPECT_EQ("0,0 500x500", 352 GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()). 353 bounds_in_pixel().ToString()); 354 EXPECT_EQ("0,501 400x400", 355 GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()). 356 bounds_in_pixel().ToString()); 357 EXPECT_EQ("0,0 188x190", 358 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); 359} 360 361TEST_F(DisplayManagerTest, ZeroOverscanInsets) { 362 if (!SupportsMultipleDisplays()) 363 return; 364 365 // Make sure the display change events is emitted for overscan inset changes. 366 UpdateDisplay("0+0-500x500,0+501-400x400"); 367 ASSERT_EQ(2u, display_manager()->GetNumDisplays()); 368 int64 display2_id = display_manager()->GetDisplayAt(1)->id(); 369 370 reset(); 371 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); 372 EXPECT_EQ(0u, changed().size()); 373 374 reset(); 375 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0)); 376 EXPECT_EQ(1u, changed().size()); 377 EXPECT_EQ(display2_id, changed()[0].id()); 378 379 reset(); 380 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); 381 EXPECT_EQ(1u, changed().size()); 382 EXPECT_EQ(display2_id, changed()[0].id()); 383} 384 385TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) { 386 if (!SupportsHostWindowResize()) 387 return; 388 389 UpdateDisplay("1000x600"); 390 EXPECT_EQ(1, 391 Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); 392 EXPECT_EQ("1000x600", 393 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 394 UpdateDisplay("1000x600*2"); 395 EXPECT_EQ(2, 396 Shell::GetPrimaryRootWindow()->compositor()->device_scale_factor()); 397 EXPECT_EQ("500x300", 398 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 399} 400 401DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { 402 DisplayInfo info(id, ToDisplayName(id), false); 403 info.SetBounds(bounds); 404 return info; 405} 406 407TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) { 408 const int64 internal_display_id = 409 test::DisplayManagerTestApi(display_manager()). 410 SetFirstDisplayAsInternalDisplay(); 411 const int external_id = 10; 412 const int mirror_id = 11; 413 const int64 invalid_id = gfx::Display::kInvalidDisplayID; 414 const DisplayInfo internal_display_info = 415 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); 416 const DisplayInfo external_display_info = 417 CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); 418 const DisplayInfo mirrored_display_info = 419 CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500)); 420 421 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 422 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 423 std::string default_bounds = 424 display_manager()->GetDisplayAt(0)->bounds().ToString(); 425 426 std::vector<DisplayInfo> display_info_list; 427 // Primary disconnected. 428 display_manager()->OnNativeDisplaysChanged(display_info_list); 429 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 430 EXPECT_EQ(default_bounds, 431 display_manager()->GetDisplayAt(0)->bounds().ToString()); 432 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 433 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 434 435 if (!SupportsMultipleDisplays()) 436 return; 437 438 // External connected while primary was disconnected. 439 display_info_list.push_back(external_display_info); 440 display_manager()->OnNativeDisplaysChanged(display_info_list); 441 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 442 443 EXPECT_EQ(invalid_id, FindDisplayForId(internal_display_id).id()); 444 EXPECT_EQ("1,1 100x100", 445 FindDisplayInfoForId(external_id).bounds_in_pixel().ToString()); 446 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 447 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 448 EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 449 450 EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId()); 451 452 // Primary connected, with different bounds. 453 display_info_list.clear(); 454 display_info_list.push_back(internal_display_info); 455 display_info_list.push_back(external_display_info); 456 display_manager()->OnNativeDisplaysChanged(display_info_list); 457 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 458 EXPECT_EQ(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 459 460 // This combinatino is new, so internal display becomes primary. 461 EXPECT_EQ("0,0 500x500", 462 FindDisplayForId(internal_display_id).bounds().ToString()); 463 EXPECT_EQ("1,1 100x100", 464 FindDisplayInfoForId(10).bounds_in_pixel().ToString()); 465 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 466 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 467 EXPECT_EQ(ToDisplayName(internal_display_id), 468 display_manager()->GetDisplayNameForId(internal_display_id)); 469 470 // Emulate suspend. 471 display_info_list.clear(); 472 display_manager()->OnNativeDisplaysChanged(display_info_list); 473 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 474 EXPECT_EQ("0,0 500x500", 475 FindDisplayForId(internal_display_id).bounds().ToString()); 476 EXPECT_EQ("1,1 100x100", 477 FindDisplayInfoForId(10).bounds_in_pixel().ToString()); 478 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 479 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 480 EXPECT_EQ(ToDisplayName(internal_display_id), 481 display_manager()->GetDisplayNameForId(internal_display_id)); 482 483 // External display has disconnected then resumed. 484 display_info_list.push_back(internal_display_info); 485 display_manager()->OnNativeDisplaysChanged(display_info_list); 486 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 487 EXPECT_EQ("0,0 500x500", 488 FindDisplayForId(internal_display_id).bounds().ToString()); 489 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 490 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 491 492 // External display was changed during suspend. 493 display_info_list.push_back(external_display_info); 494 display_manager()->OnNativeDisplaysChanged(display_info_list); 495 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 496 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 497 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 498 499 // suspend... 500 display_info_list.clear(); 501 display_manager()->OnNativeDisplaysChanged(display_info_list); 502 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 503 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 504 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 505 506 // and resume with different external display. 507 display_info_list.push_back(internal_display_info); 508 display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100))); 509 display_manager()->OnNativeDisplaysChanged(display_info_list); 510 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 511 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 512 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 513 EXPECT_FALSE(display_manager()->IsMirrored()); 514 515 // mirrored... 516 display_info_list.clear(); 517 display_info_list.push_back(internal_display_info); 518 display_info_list.push_back(mirrored_display_info); 519 display_manager()->OnNativeDisplaysChanged(display_info_list); 520 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 521 EXPECT_EQ("0,0 500x500", 522 FindDisplayForId(internal_display_id).bounds().ToString()); 523 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 524 EXPECT_EQ(11U, display_manager()->mirrored_display().id()); 525 EXPECT_TRUE(display_manager()->IsMirrored()); 526 527 // Test display name. 528 EXPECT_EQ(ToDisplayName(internal_display_id), 529 display_manager()->GetDisplayNameForId(internal_display_id)); 530 EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10)); 531 EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11)); 532 EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12)); 533 // Default name for the id that doesn't exist. 534 EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100)); 535 536 // and exit mirroring. 537 display_info_list.clear(); 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 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 542 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 543 EXPECT_FALSE(display_manager()->IsMirrored()); 544 EXPECT_EQ("0,0 500x500", 545 FindDisplayForId(internal_display_id).bounds().ToString()); 546 EXPECT_EQ("500,0 100x100", 547 FindDisplayForId(10).bounds().ToString()); 548 549 // Turn off internal 550 display_info_list.clear(); 551 display_info_list.push_back(external_display_info); 552 display_manager()->OnNativeDisplaysChanged(display_info_list); 553 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 554 EXPECT_EQ(invalid_id, FindDisplayForId(internal_display_id).id()); 555 EXPECT_EQ("1,1 100x100", 556 FindDisplayInfoForId(external_id).bounds_in_pixel().ToString()); 557 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 558 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 559 560 // Switched to another display 561 display_info_list.clear(); 562 display_info_list.push_back(internal_display_info); 563 display_manager()->OnNativeDisplaysChanged(display_info_list); 564 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 565 EXPECT_EQ( 566 "0,0 500x500", 567 FindDisplayInfoForId(internal_display_id).bounds_in_pixel().ToString()); 568 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 569 EXPECT_FALSE(display_manager()->mirrored_display().is_valid()); 570} 571 572#if defined(OS_WIN) 573// TODO(scottmg): RootWindow doesn't get resized on Windows 574// Ash. http://crbug.com/247916. 575#define MAYBE_TestNativeDisplaysChangedNoInternal \ 576 DISABLED_TestNativeDisplaysChangedNoInternal 577#else 578#define MAYBE_TestNativeDisplaysChangedNoInternal \ 579 TestNativeDisplaysChangedNoInternal 580#endif 581 582TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) { 583 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 584 585 // Don't change the display info if all displays are disconnected. 586 std::vector<DisplayInfo> display_info_list; 587 display_manager()->OnNativeDisplaysChanged(display_info_list); 588 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 589 590 // Connect another display which will become primary. 591 const DisplayInfo external_display_info = 592 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); 593 display_info_list.push_back(external_display_info); 594 display_manager()->OnNativeDisplaysChanged(display_info_list); 595 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 596 EXPECT_EQ("1,1 100x100", 597 FindDisplayInfoForId(10).bounds_in_pixel().ToString()); 598 EXPECT_EQ("100x100", 599 ash::Shell::GetPrimaryRootWindow()->GetHostSize().ToString()); 600} 601 602TEST_F(DisplayManagerTest, EnsurePointerInDisplays) { 603 if (!SupportsMultipleDisplays()) 604 return; 605 606 UpdateDisplay("200x200,300x300"); 607 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 608 609 aura::Env* env = aura::Env::GetInstance(); 610 611 aura::test::EventGenerator generator(root_windows[0]); 612 613 // Set the initial position. 614 generator.MoveMouseToInHost(350, 150); 615 EXPECT_EQ("350,150", env->last_mouse_location().ToString()); 616 617 // A mouse pointer will be inside 2nd display. 618 UpdateDisplay("300x300,200x200"); 619 EXPECT_EQ("350,150", env->last_mouse_location().ToString()); 620 621 // A mouse pointer will be outside of displays and move to the 622 // center of 2nd display. 623 UpdateDisplay("300x300,100x100"); 624 EXPECT_EQ("350,50", env->last_mouse_location().ToString()); 625 626 // 2nd display was disconnected, but the mouse pointer says in the 627 // 1st display. 628 UpdateDisplay("400x400"); 629 EXPECT_EQ("350,50", env->last_mouse_location().ToString()); 630 631 // 1st display's resolution has changed, and the mouse pointer is 632 // now outside. Move the mouse pointer to the center of 1st display. 633 UpdateDisplay("300x300"); 634 EXPECT_EQ("150,150", env->last_mouse_location().ToString()); 635 636 // Move the mouse pointer to the bottom of 1st display. 637 generator.MoveMouseToInHost(150, 290); 638 EXPECT_EQ("150,290", env->last_mouse_location().ToString()); 639 640 // The mouse pointer is outside and closest display is 1st one. 641 UpdateDisplay("300x280,200x200"); 642 EXPECT_EQ("150,140", env->last_mouse_location().ToString()); 643} 644 645TEST_F(DisplayManagerTest, EnsurePointerInDisplays_2ndOnLeft) { 646 if (!SupportsMultipleDisplays()) 647 return; 648 649 // Set the 2nd display on the left. 650 DisplayController* display_controller = 651 Shell::GetInstance()->display_controller(); 652 DisplayLayout layout = display_controller->default_display_layout(); 653 layout.position = DisplayLayout::LEFT; 654 display_controller->SetDefaultDisplayLayout(layout); 655 656 UpdateDisplay("200x200,300x300"); 657 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 658 659 EXPECT_EQ("-300,0 300x300", 660 ScreenAsh::GetSecondaryDisplay().bounds().ToString()); 661 662 aura::Env* env = aura::Env::GetInstance(); 663 664 // Set the initial position. 665 root_windows[0]->MoveCursorTo(gfx::Point(-150, 150)); 666 EXPECT_EQ("-150,150", env->last_mouse_location().ToString()); 667 668 // A mouse pointer will be in 2nd display. 669 UpdateDisplay("300x300,200x200"); 670 EXPECT_EQ("-150,150", env->last_mouse_location().ToString()); 671 672 // A mouse pointer will be outside of displays and move to the 673 // center of 2nd display. 674 UpdateDisplay("300x300,200x100"); 675 EXPECT_EQ("-100,50", env->last_mouse_location().ToString()); 676 677 // 2nd display was disconnected. Mouse pointer should move to 678 // 1st display. 679 UpdateDisplay("300x300"); 680 EXPECT_EQ("150,150", env->last_mouse_location().ToString()); 681} 682 683TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) { 684 if (!SupportsMultipleDisplays()) 685 return; 686 687 const int64 internal_display_id = 688 test::DisplayManagerTestApi(display_manager()). 689 SetFirstDisplayAsInternalDisplay(); 690 const DisplayInfo native_display_info = 691 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); 692 const DisplayInfo secondary_display_info = 693 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); 694 695 std::vector<DisplayInfo> display_info_list; 696 display_info_list.push_back(native_display_info); 697 display_info_list.push_back(secondary_display_info); 698 display_manager()->OnNativeDisplaysChanged(display_info_list); 699 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 700 EXPECT_EQ("0,0 500x500", 701 FindDisplayForId(internal_display_id).bounds().ToString()); 702 EXPECT_EQ("500,0 100x100", FindDisplayForId(10).bounds().ToString()); 703 704 ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( 705 FindDisplayForId(secondary_display_info.id())); 706 EXPECT_EQ("-500,0 500x500", 707 FindDisplayForId(internal_display_id).bounds().ToString()); 708 EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString()); 709 710 // OnNativeDisplaysChanged may change the display bounds. Here makes sure 711 // nothing changed if the exactly same displays are specified. 712 display_manager()->OnNativeDisplaysChanged(display_info_list); 713 EXPECT_EQ("-500,0 500x500", 714 FindDisplayForId(internal_display_id).bounds().ToString()); 715 EXPECT_EQ("0,0 100x100", FindDisplayForId(10).bounds().ToString()); 716} 717 718TEST_F(DisplayManagerTest, Rotate) { 719 if (!SupportsMultipleDisplays()) 720 return; 721 722 UpdateDisplay("100x200/r,300x400/l"); 723 EXPECT_EQ("1,1 100x200", 724 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 725 EXPECT_EQ("200x100", 726 GetDisplayInfoAt(0).size_in_pixel().ToString()); 727 728 EXPECT_EQ("1,201 300x400", 729 GetDisplayInfoAt(1).bounds_in_pixel().ToString()); 730 EXPECT_EQ("400x300", 731 GetDisplayInfoAt(1).size_in_pixel().ToString()); 732 reset(); 733 UpdateDisplay("100x200/b,300x400"); 734 EXPECT_EQ("2 0 0", GetCountSummary()); 735 reset(); 736 737 EXPECT_EQ("1,1 100x200", 738 GetDisplayInfoAt(0).bounds_in_pixel().ToString()); 739 EXPECT_EQ("100x200", 740 GetDisplayInfoAt(0).size_in_pixel().ToString()); 741 742 EXPECT_EQ("1,201 300x400", 743 GetDisplayInfoAt(1).bounds_in_pixel().ToString()); 744 EXPECT_EQ("300x400", 745 GetDisplayInfoAt(1).size_in_pixel().ToString()); 746 747 // Just Rotating display will change the bounds on both display. 748 UpdateDisplay("100x200/l,300x400"); 749 EXPECT_EQ("2 0 0", GetCountSummary()); 750 reset(); 751 752 // Updating tothe same configuration should report no changes. 753 UpdateDisplay("100x200/l,300x400"); 754 EXPECT_EQ("0 0 0", GetCountSummary()); 755 reset(); 756 757 UpdateDisplay("100x200/l,300x400"); 758 EXPECT_EQ("0 0 0", GetCountSummary()); 759 reset(); 760 761 UpdateDisplay("200x200"); 762 EXPECT_EQ("1 0 1", GetCountSummary()); 763 reset(); 764 765 UpdateDisplay("200x200/l"); 766 EXPECT_EQ("1 0 0", GetCountSummary()); 767} 768 769TEST_F(DisplayManagerTest, UIScale) { 770 UpdateDisplay("1280x800"); 771 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id(); 772 display_manager()->SetDisplayUIScale(display_id, 1.125f); 773 EXPECT_EQ(1.0, GetDisplayInfoAt(0).ui_scale()); 774 display_manager()->SetDisplayUIScale(display_id, 0.8f); 775 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 776 display_manager()->SetDisplayUIScale(display_id, 0.75f); 777 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 778 display_manager()->SetDisplayUIScale(display_id, 0.625f); 779 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 780 781 gfx::Display::SetInternalDisplayId(display_id); 782 783 display_manager()->SetDisplayUIScale(display_id, 1.5f); 784 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 785 display_manager()->SetDisplayUIScale(display_id, 1.25f); 786 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 787 display_manager()->SetDisplayUIScale(display_id, 1.125f); 788 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale()); 789 display_manager()->SetDisplayUIScale(display_id, 0.8f); 790 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale()); 791 display_manager()->SetDisplayUIScale(display_id, 0.75f); 792 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale()); 793 display_manager()->SetDisplayUIScale(display_id, 0.625f); 794 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale()); 795 display_manager()->SetDisplayUIScale(display_id, 0.6f); 796 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale()); 797 display_manager()->SetDisplayUIScale(display_id, 0.5f); 798 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale()); 799 800 UpdateDisplay("1366x768"); 801 display_manager()->SetDisplayUIScale(display_id, 1.5f); 802 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 803 display_manager()->SetDisplayUIScale(display_id, 1.25f); 804 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 805 display_manager()->SetDisplayUIScale(display_id, 1.125f); 806 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale()); 807 display_manager()->SetDisplayUIScale(display_id, 0.8f); 808 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale()); 809 display_manager()->SetDisplayUIScale(display_id, 0.75f); 810 EXPECT_EQ(0.75f, GetDisplayInfoAt(0).ui_scale()); 811 display_manager()->SetDisplayUIScale(display_id, 0.6f); 812 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale()); 813 display_manager()->SetDisplayUIScale(display_id, 0.625f); 814 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale()); 815 display_manager()->SetDisplayUIScale(display_id, 0.5f); 816 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale()); 817 818 UpdateDisplay("1280x850*2"); 819 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale()); 820 display_manager()->SetDisplayUIScale(display_id, 1.5f); 821 EXPECT_EQ(1.5f, GetDisplayInfoAt(0).ui_scale()); 822 display_manager()->SetDisplayUIScale(display_id, 1.25f); 823 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).ui_scale()); 824 display_manager()->SetDisplayUIScale(display_id, 1.125f); 825 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale()); 826 display_manager()->SetDisplayUIScale(display_id, 0.8f); 827 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale()); 828 display_manager()->SetDisplayUIScale(display_id, 0.75f); 829 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale()); 830 display_manager()->SetDisplayUIScale(display_id, 0.625f); 831 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale()); 832 display_manager()->SetDisplayUIScale(display_id, 0.6f); 833 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale()); 834 display_manager()->SetDisplayUIScale(display_id, 0.5f); 835 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale()); 836} 837 838 839#if defined(OS_WIN) 840// TODO(scottmg): RootWindow doesn't get resized on Windows 841// Ash. http://crbug.com/247916. 842#define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom 843#else 844#define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom 845#endif 846 847TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) { 848 // Make sure just rotating will not change native location. 849 UpdateDisplay("300x200,200x150"); 850 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 851 aura::Env* env = aura::Env::GetInstance(); 852 853 aura::test::EventGenerator generator1(root_windows[0]); 854 aura::test::EventGenerator generator2(root_windows[1]); 855 856 // Test on 1st display. 857 generator1.MoveMouseToInHost(150, 50); 858 EXPECT_EQ("150,50", env->last_mouse_location().ToString()); 859 UpdateDisplay("300x200/r,200x150"); 860 EXPECT_EQ("50,149", env->last_mouse_location().ToString()); 861 862 // Test on 2nd display. 863 generator2.MoveMouseToInHost(50, 100); 864 EXPECT_EQ("250,100", env->last_mouse_location().ToString()); 865 UpdateDisplay("300x200/r,200x150/l"); 866 EXPECT_EQ("249,50", env->last_mouse_location().ToString()); 867 868 // Make sure just zooming will not change native location. 869 UpdateDisplay("600x400*2,400x300"); 870 871 // Test on 1st display. 872 generator1.MoveMouseToInHost(200, 300); 873 EXPECT_EQ("100,150", env->last_mouse_location().ToString()); 874 UpdateDisplay("600x400*2@1.5,400x300"); 875 EXPECT_EQ("150,225", env->last_mouse_location().ToString()); 876 877 // Test on 2nd display. 878 UpdateDisplay("600x400,400x300*2"); 879 generator2.MoveMouseToInHost(200, 100); 880 EXPECT_EQ("700,50", env->last_mouse_location().ToString()); 881 UpdateDisplay("600x400,400x300*2@1.5"); 882 EXPECT_EQ("750,75", env->last_mouse_location().ToString()); 883} 884 885class TestDisplayObserver : public gfx::DisplayObserver { 886 public: 887 TestDisplayObserver() : changed_(false) {} 888 virtual ~TestDisplayObserver() {} 889 890 // gfx::DisplayObserver overrides: 891 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { 892 } 893 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 894 // Mirror window should already be delete before restoring 895 // the external dispay. 896 EXPECT_FALSE(test_api.GetRootWindow()); 897 changed_ = true; 898 } 899 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 900 // Mirror window should not be created until the external display 901 // is removed. 902 EXPECT_FALSE(test_api.GetRootWindow()); 903 changed_ = true; 904 } 905 906 bool changed_and_reset() { 907 bool changed = changed_; 908 changed_ = false; 909 return changed; 910 } 911 912 private: 913 test::MirrorWindowTestApi test_api; 914 bool changed_; 915 916 DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver); 917}; 918 919TEST_F(DisplayManagerTest, SoftwareMirroring) { 920 if (!SupportsMultipleDisplays()) 921 return; 922 923 UpdateDisplay("300x400,400x500"); 924 925 test::MirrorWindowTestApi test_api; 926 EXPECT_EQ(NULL, test_api.GetRootWindow()); 927 928 TestDisplayObserver display_observer; 929 Shell::GetScreen()->AddObserver(&display_observer); 930 931 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 932 display_manager->SetSoftwareMirroring(true); 933 display_manager->UpdateDisplays(); 934 EXPECT_TRUE(display_observer.changed_and_reset()); 935 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 936 EXPECT_EQ("0,0 300x400", 937 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); 938 EXPECT_EQ("400x500", test_api.GetRootWindow()->GetHostSize().ToString()); 939 EXPECT_EQ("300x400", test_api.GetRootWindow()->bounds().size().ToString()); 940 EXPECT_TRUE(display_manager->IsMirrored()); 941 942 display_manager->SetMirrorMode(false); 943 EXPECT_TRUE(display_observer.changed_and_reset()); 944 EXPECT_EQ(NULL, test_api.GetRootWindow()); 945 EXPECT_EQ(2U, display_manager->GetNumDisplays()); 946 EXPECT_FALSE(display_manager->IsMirrored()); 947 948 // Make sure the mirror window has the pixel size of the 949 // source display. 950 display_manager->SetMirrorMode(true); 951 EXPECT_TRUE(display_observer.changed_and_reset()); 952 953 UpdateDisplay("300x400@0.5,400x500"); 954 EXPECT_FALSE(display_observer.changed_and_reset()); 955 EXPECT_EQ("300x400", test_api.GetRootWindow()->bounds().size().ToString()); 956 EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString()); 957 958 UpdateDisplay("310x410*2,400x500"); 959 EXPECT_FALSE(display_observer.changed_and_reset()); 960 EXPECT_EQ("310x410", test_api.GetRootWindow()->bounds().size().ToString()); 961 EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString()); 962 963 UpdateDisplay("320x420/r,400x500"); 964 EXPECT_FALSE(display_observer.changed_and_reset()); 965 EXPECT_EQ("320x420", test_api.GetRootWindow()->bounds().size().ToString()); 966 EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString()); 967 968 UpdateDisplay("330x440/r,400x500"); 969 EXPECT_FALSE(display_observer.changed_and_reset()); 970 EXPECT_EQ("330x440", test_api.GetRootWindow()->bounds().size().ToString()); 971 EXPECT_EQ("400x500", GetMirroredDisplay().size().ToString()); 972 973 // Overscan insets are ignored. 974 UpdateDisplay("400x600/o,600x800/o"); 975 EXPECT_FALSE(display_observer.changed_and_reset()); 976 EXPECT_EQ("400x600", test_api.GetRootWindow()->bounds().size().ToString()); 977 EXPECT_EQ("600x800", GetMirroredDisplay().size().ToString()); 978 979 Shell::GetScreen()->RemoveObserver(&display_observer); 980} 981 982} // namespace internal 983} // namespace ash 984