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/display/display_layout_store.h" 9 #include "ash/screen_util.h" 10 #include "ash/shell.h" 11 #include "ash/test/ash_test_base.h" 12 #include "ash/test/display_manager_test_api.h" 13 #include "ash/test/mirror_window_test_api.h" 14 #include "base/format_macros.h" 15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/stringprintf.h" 17 #include "ui/aura/env.h" 18 #include "ui/aura/test/event_generator.h" 19 #include "ui/aura/window_observer.h" 20 #include "ui/aura/window_tree_host.h" 21 #include "ui/gfx/display_observer.h" 22 #include "ui/gfx/display.h" 23 #include "ui/gfx/screen.h" 24 #include "ui/gfx/screen_type_delegate.h" 25 26 namespace ash { 27 28 using std::vector; 29 using std::string; 30 31 using base::StringPrintf; 32 33 namespace { 34 35 std::string ToDisplayName(int64 id) { 36 return "x-" + base::Int64ToString(id); 37 } 38 39 } // namespace 40 41 class DisplayManagerTest : public test::AshTestBase, 42 public gfx::DisplayObserver, 43 public aura::WindowObserver { 44 public: 45 DisplayManagerTest() 46 : removed_count_(0U), 47 root_window_destroyed_(false) { 48 } 49 virtual ~DisplayManagerTest() {} 50 51 virtual void SetUp() OVERRIDE { 52 AshTestBase::SetUp(); 53 Shell::GetScreen()->AddObserver(this); 54 Shell::GetPrimaryRootWindow()->AddObserver(this); 55 } 56 virtual void TearDown() OVERRIDE { 57 Shell::GetPrimaryRootWindow()->RemoveObserver(this); 58 Shell::GetScreen()->RemoveObserver(this); 59 AshTestBase::TearDown(); 60 } 61 62 DisplayManager* display_manager() { 63 return Shell::GetInstance()->display_manager(); 64 } 65 const vector<gfx::Display>& changed() const { return changed_; } 66 const vector<gfx::Display>& added() const { return added_; } 67 68 string GetCountSummary() const { 69 return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS, 70 changed_.size(), added_.size(), removed_count_); 71 } 72 73 void reset() { 74 changed_.clear(); 75 added_.clear(); 76 removed_count_ = 0U; 77 root_window_destroyed_ = false; 78 } 79 80 bool root_window_destroyed() const { 81 return root_window_destroyed_; 82 } 83 84 const DisplayInfo& GetDisplayInfo(const gfx::Display& display) { 85 return display_manager()->GetDisplayInfo(display.id()); 86 } 87 88 const DisplayInfo& GetDisplayInfoAt(int index) { 89 return GetDisplayInfo(display_manager()->GetDisplayAt(index)); 90 } 91 92 const gfx::Display& GetDisplayForId(int64 id) { 93 return display_manager()->GetDisplayForId(id); 94 } 95 96 const DisplayInfo& GetDisplayInfoForId(int64 id) { 97 return GetDisplayInfo(display_manager()->GetDisplayForId(id)); 98 } 99 100 // aura::DisplayObserver overrides: 101 virtual void OnDisplayMetricsChanged(const gfx::Display& display, 102 uint32_t) OVERRIDE { 103 changed_.push_back(display); 104 } 105 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 106 added_.push_back(new_display); 107 } 108 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 109 ++removed_count_; 110 } 111 112 // aura::WindowObserver overrides: 113 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 114 ASSERT_EQ(Shell::GetPrimaryRootWindow(), window); 115 root_window_destroyed_ = true; 116 } 117 118 private: 119 vector<gfx::Display> changed_; 120 vector<gfx::Display> added_; 121 size_t removed_count_; 122 bool root_window_destroyed_; 123 124 DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest); 125 }; 126 127 TEST_F(DisplayManagerTest, UpdateDisplayTest) { 128 if (!SupportsMultipleDisplays()) 129 return; 130 131 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 132 133 // Update primary and add seconary. 134 UpdateDisplay("100+0-500x500,0+501-400x400"); 135 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 136 EXPECT_EQ("0,0 500x500", 137 display_manager()->GetDisplayAt(0).bounds().ToString()); 138 139 EXPECT_EQ("1 1 0", GetCountSummary()); 140 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); 141 EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id()); 142 EXPECT_EQ("0,0 500x500", changed()[0].bounds().ToString()); 143 // Secondary display is on right. 144 EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString()); 145 EXPECT_EQ("0,501 400x400", 146 GetDisplayInfo(added()[0]).bounds_in_native().ToString()); 147 reset(); 148 149 // Delete secondary. 150 UpdateDisplay("100+0-500x500"); 151 EXPECT_EQ("0 0 1", GetCountSummary()); 152 reset(); 153 154 // Change primary. 155 UpdateDisplay("1+1-1000x600"); 156 EXPECT_EQ("1 0 0", GetCountSummary()); 157 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); 158 EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString()); 159 reset(); 160 161 // Add secondary. 162 UpdateDisplay("1+1-1000x600,1002+0-600x400"); 163 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 164 EXPECT_EQ("0 1 0", GetCountSummary()); 165 EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id()); 166 // Secondary display is on right. 167 EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString()); 168 EXPECT_EQ("1002,0 600x400", 169 GetDisplayInfo(added()[0]).bounds_in_native().ToString()); 170 reset(); 171 172 // Secondary removed, primary changed. 173 UpdateDisplay("1+1-800x300"); 174 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 175 EXPECT_EQ("1 0 1", GetCountSummary()); 176 EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id()); 177 EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString()); 178 reset(); 179 180 // # of display can go to zero when screen is off. 181 const vector<DisplayInfo> empty; 182 display_manager()->OnNativeDisplaysChanged(empty); 183 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 184 EXPECT_EQ("0 0 0", GetCountSummary()); 185 EXPECT_FALSE(root_window_destroyed()); 186 // Display configuration stays the same 187 EXPECT_EQ("0,0 800x300", 188 display_manager()->GetDisplayAt(0).bounds().ToString()); 189 reset(); 190 191 // Connect to display again 192 UpdateDisplay("100+100-500x400"); 193 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 194 EXPECT_EQ("1 0 0", GetCountSummary()); 195 EXPECT_FALSE(root_window_destroyed()); 196 EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString()); 197 EXPECT_EQ("100,100 500x400", 198 GetDisplayInfo(changed()[0]).bounds_in_native().ToString()); 199 reset(); 200 201 // Go back to zero and wake up with multiple displays. 202 display_manager()->OnNativeDisplaysChanged(empty); 203 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 204 EXPECT_FALSE(root_window_destroyed()); 205 reset(); 206 207 // Add secondary. 208 UpdateDisplay("0+0-1000x600,1000+1000-600x400"); 209 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 210 EXPECT_EQ("0,0 1000x600", 211 display_manager()->GetDisplayAt(0).bounds().ToString()); 212 // Secondary display is on right. 213 EXPECT_EQ("1000,0 600x400", 214 display_manager()->GetDisplayAt(1).bounds().ToString()); 215 EXPECT_EQ("1000,1000 600x400", 216 GetDisplayInfoAt(1).bounds_in_native().ToString()); 217 reset(); 218 219 // Changing primary will update secondary as well. 220 UpdateDisplay("0+0-800x600,1000+1000-600x400"); 221 EXPECT_EQ("2 0 0", GetCountSummary()); 222 reset(); 223 EXPECT_EQ("0,0 800x600", 224 display_manager()->GetDisplayAt(0).bounds().ToString()); 225 EXPECT_EQ("800,0 600x400", 226 display_manager()->GetDisplayAt(1).bounds().ToString()); 227 } 228 229 // Test in emulation mode (use_fullscreen_host_window=false) 230 TEST_F(DisplayManagerTest, EmulatorTest) { 231 if (!SupportsMultipleDisplays()) 232 return; 233 234 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 235 236 display_manager()->AddRemoveDisplay(); 237 // Update primary and add seconary. 238 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 239 EXPECT_EQ("0 1 0", GetCountSummary()); 240 reset(); 241 242 display_manager()->AddRemoveDisplay(); 243 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 244 EXPECT_EQ("0 0 1", GetCountSummary()); 245 reset(); 246 247 display_manager()->AddRemoveDisplay(); 248 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 249 EXPECT_EQ("0 1 0", GetCountSummary()); 250 reset(); 251 } 252 253 TEST_F(DisplayManagerTest, OverscanInsetsTest) { 254 if (!SupportsMultipleDisplays()) 255 return; 256 257 UpdateDisplay("0+0-500x500,0+501-400x400"); 258 reset(); 259 ASSERT_EQ(2u, display_manager()->GetNumDisplays()); 260 const DisplayInfo& display_info1 = GetDisplayInfoAt(0); 261 const DisplayInfo& display_info2 = GetDisplayInfoAt(1); 262 display_manager()->SetOverscanInsets( 263 display_info2.id(), gfx::Insets(13, 12, 11, 10)); 264 265 std::vector<gfx::Display> changed_displays = changed(); 266 EXPECT_EQ(1u, changed_displays.size()); 267 EXPECT_EQ(display_info2.id(), changed_displays[0].id()); 268 EXPECT_EQ("0,0 500x500", 269 GetDisplayInfoAt(0).bounds_in_native().ToString()); 270 DisplayInfo updated_display_info2 = GetDisplayInfoAt(1); 271 EXPECT_EQ("0,501 400x400", 272 updated_display_info2.bounds_in_native().ToString()); 273 EXPECT_EQ("378x376", 274 updated_display_info2.size_in_pixel().ToString()); 275 EXPECT_EQ("13,12,11,10", 276 updated_display_info2.overscan_insets_in_dip().ToString()); 277 EXPECT_EQ("500,0 378x376", 278 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 279 280 // Make sure that SetOverscanInsets() is idempotent. 281 display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets()); 282 display_manager()->SetOverscanInsets( 283 display_info2.id(), gfx::Insets(13, 12, 11, 10)); 284 EXPECT_EQ("0,0 500x500", 285 GetDisplayInfoAt(0).bounds_in_native().ToString()); 286 updated_display_info2 = GetDisplayInfoAt(1); 287 EXPECT_EQ("0,501 400x400", 288 updated_display_info2.bounds_in_native().ToString()); 289 EXPECT_EQ("378x376", 290 updated_display_info2.size_in_pixel().ToString()); 291 EXPECT_EQ("13,12,11,10", 292 updated_display_info2.overscan_insets_in_dip().ToString()); 293 294 display_manager()->SetOverscanInsets( 295 display_info2.id(), gfx::Insets(10, 11, 12, 13)); 296 EXPECT_EQ("0,0 500x500", 297 GetDisplayInfoAt(0).bounds_in_native().ToString()); 298 EXPECT_EQ("376x378", 299 GetDisplayInfoAt(1).size_in_pixel().ToString()); 300 EXPECT_EQ("10,11,12,13", 301 GetDisplayInfoAt(1).overscan_insets_in_dip().ToString()); 302 303 // Recreate a new 2nd display. It won't apply the overscan inset because the 304 // new display has a different ID. 305 UpdateDisplay("0+0-500x500"); 306 UpdateDisplay("0+0-500x500,0+501-400x400"); 307 EXPECT_EQ("0,0 500x500", 308 GetDisplayInfoAt(0).bounds_in_native().ToString()); 309 EXPECT_EQ("0,501 400x400", 310 GetDisplayInfoAt(1).bounds_in_native().ToString()); 311 312 // Recreate the displays with the same ID. It should apply the overscan 313 // inset. 314 UpdateDisplay("0+0-500x500"); 315 std::vector<DisplayInfo> display_info_list; 316 display_info_list.push_back(display_info1); 317 display_info_list.push_back(display_info2); 318 display_manager()->OnNativeDisplaysChanged(display_info_list); 319 EXPECT_EQ("1,1 500x500", 320 GetDisplayInfoAt(0).bounds_in_native().ToString()); 321 updated_display_info2 = GetDisplayInfoAt(1); 322 EXPECT_EQ("376x378", 323 updated_display_info2.size_in_pixel().ToString()); 324 EXPECT_EQ("10,11,12,13", 325 updated_display_info2.overscan_insets_in_dip().ToString()); 326 327 // HiDPI but overscan display. The specified insets size should be doubled. 328 UpdateDisplay("0+0-500x500,0+501-400x400*2"); 329 display_manager()->SetOverscanInsets( 330 display_manager()->GetDisplayAt(1).id(), gfx::Insets(4, 5, 6, 7)); 331 EXPECT_EQ("0,0 500x500", 332 GetDisplayInfoAt(0).bounds_in_native().ToString()); 333 updated_display_info2 = GetDisplayInfoAt(1); 334 EXPECT_EQ("0,501 400x400", 335 updated_display_info2.bounds_in_native().ToString()); 336 EXPECT_EQ("376x380", 337 updated_display_info2.size_in_pixel().ToString()); 338 EXPECT_EQ("4,5,6,7", 339 updated_display_info2.overscan_insets_in_dip().ToString()); 340 EXPECT_EQ("8,10,12,14", 341 updated_display_info2.GetOverscanInsetsInPixel().ToString()); 342 343 // Make sure switching primary display applies the overscan offset only once. 344 ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( 345 ScreenUtil::GetSecondaryDisplay()); 346 EXPECT_EQ("-500,0 500x500", 347 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 348 EXPECT_EQ("0,0 500x500", 349 GetDisplayInfo(ScreenUtil::GetSecondaryDisplay()). 350 bounds_in_native().ToString()); 351 EXPECT_EQ("0,501 400x400", 352 GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()). 353 bounds_in_native().ToString()); 354 EXPECT_EQ("0,0 188x190", 355 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); 356 } 357 358 TEST_F(DisplayManagerTest, ZeroOverscanInsets) { 359 if (!SupportsMultipleDisplays()) 360 return; 361 362 // Make sure the display change events is emitted for overscan inset changes. 363 UpdateDisplay("0+0-500x500,0+501-400x400"); 364 ASSERT_EQ(2u, display_manager()->GetNumDisplays()); 365 int64 display2_id = display_manager()->GetDisplayAt(1).id(); 366 367 reset(); 368 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); 369 EXPECT_EQ(0u, changed().size()); 370 371 reset(); 372 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0)); 373 EXPECT_EQ(1u, changed().size()); 374 EXPECT_EQ(display2_id, changed()[0].id()); 375 376 reset(); 377 display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0)); 378 EXPECT_EQ(1u, changed().size()); 379 EXPECT_EQ(display2_id, changed()[0].id()); 380 } 381 382 TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) { 383 if (!SupportsHostWindowResize()) 384 return; 385 386 UpdateDisplay("1000x600"); 387 aura::WindowTreeHost* host = Shell::GetPrimaryRootWindow()->GetHost(); 388 EXPECT_EQ(1, host->compositor()->device_scale_factor()); 389 EXPECT_EQ("1000x600", 390 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 391 EXPECT_EQ("1 0 0", GetCountSummary()); 392 393 UpdateDisplay("1000x600*2"); 394 EXPECT_EQ(2, host->compositor()->device_scale_factor()); 395 EXPECT_EQ("2 0 0", GetCountSummary()); 396 EXPECT_EQ("500x300", 397 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 398 } 399 400 DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { 401 DisplayInfo info(id, ToDisplayName(id), false); 402 info.SetBounds(bounds); 403 return info; 404 } 405 406 TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) { 407 const int64 internal_display_id = 408 test::DisplayManagerTestApi(display_manager()). 409 SetFirstDisplayAsInternalDisplay(); 410 const int external_id = 10; 411 const int mirror_id = 11; 412 const int64 invalid_id = gfx::Display::kInvalidDisplayID; 413 const DisplayInfo internal_display_info = 414 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); 415 const DisplayInfo external_display_info = 416 CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); 417 const DisplayInfo mirrored_display_info = 418 CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500)); 419 420 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 421 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 422 std::string default_bounds = 423 display_manager()->GetDisplayAt(0).bounds().ToString(); 424 425 std::vector<DisplayInfo> display_info_list; 426 // Primary disconnected. 427 display_manager()->OnNativeDisplaysChanged(display_info_list); 428 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 429 EXPECT_EQ(default_bounds, 430 display_manager()->GetDisplayAt(0).bounds().ToString()); 431 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 432 EXPECT_FALSE(display_manager()->IsMirrored()); 433 434 if (!SupportsMultipleDisplays()) 435 return; 436 437 // External connected while primary was disconnected. 438 display_info_list.push_back(external_display_info); 439 display_manager()->OnNativeDisplaysChanged(display_info_list); 440 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 441 442 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); 443 EXPECT_EQ("1,1 100x100", 444 GetDisplayInfoForId(external_id).bounds_in_native().ToString()); 445 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 446 EXPECT_FALSE(display_manager()->IsMirrored()); 447 EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 448 449 EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId()); 450 451 // Primary connected, with different bounds. 452 display_info_list.clear(); 453 display_info_list.push_back(internal_display_info); 454 display_info_list.push_back(external_display_info); 455 display_manager()->OnNativeDisplaysChanged(display_info_list); 456 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 457 EXPECT_EQ(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 458 459 // This combinatino is new, so internal display becomes primary. 460 EXPECT_EQ("0,0 500x500", 461 GetDisplayForId(internal_display_id).bounds().ToString()); 462 EXPECT_EQ("1,1 100x100", 463 GetDisplayInfoForId(10).bounds_in_native().ToString()); 464 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 465 EXPECT_FALSE(display_manager()->IsMirrored()); 466 EXPECT_EQ(ToDisplayName(internal_display_id), 467 display_manager()->GetDisplayNameForId(internal_display_id)); 468 469 // Emulate suspend. 470 display_info_list.clear(); 471 display_manager()->OnNativeDisplaysChanged(display_info_list); 472 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 473 EXPECT_EQ("0,0 500x500", 474 GetDisplayForId(internal_display_id).bounds().ToString()); 475 EXPECT_EQ("1,1 100x100", 476 GetDisplayInfoForId(10).bounds_in_native().ToString()); 477 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 478 EXPECT_FALSE(display_manager()->IsMirrored()); 479 EXPECT_EQ(ToDisplayName(internal_display_id), 480 display_manager()->GetDisplayNameForId(internal_display_id)); 481 482 // External display has disconnected then resumed. 483 display_info_list.push_back(internal_display_info); 484 display_manager()->OnNativeDisplaysChanged(display_info_list); 485 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 486 EXPECT_EQ("0,0 500x500", 487 GetDisplayForId(internal_display_id).bounds().ToString()); 488 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 489 EXPECT_FALSE(display_manager()->IsMirrored()); 490 491 // External display was changed during suspend. 492 display_info_list.push_back(external_display_info); 493 display_manager()->OnNativeDisplaysChanged(display_info_list); 494 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 495 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 496 EXPECT_FALSE(display_manager()->IsMirrored()); 497 498 // suspend... 499 display_info_list.clear(); 500 display_manager()->OnNativeDisplaysChanged(display_info_list); 501 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 502 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 503 EXPECT_FALSE(display_manager()->IsMirrored()); 504 505 // and resume with different external display. 506 display_info_list.push_back(internal_display_info); 507 display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100))); 508 display_manager()->OnNativeDisplaysChanged(display_info_list); 509 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 510 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 511 EXPECT_FALSE(display_manager()->IsMirrored()); 512 EXPECT_FALSE(display_manager()->IsMirrored()); 513 514 // mirrored... 515 display_info_list.clear(); 516 display_info_list.push_back(internal_display_info); 517 display_info_list.push_back(mirrored_display_info); 518 display_manager()->OnNativeDisplaysChanged(display_info_list); 519 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 520 EXPECT_EQ("0,0 500x500", 521 GetDisplayForId(internal_display_id).bounds().ToString()); 522 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 523 EXPECT_EQ(11U, display_manager()->mirrored_display_id()); 524 EXPECT_TRUE(display_manager()->IsMirrored()); 525 526 // Test display name. 527 EXPECT_EQ(ToDisplayName(internal_display_id), 528 display_manager()->GetDisplayNameForId(internal_display_id)); 529 EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10)); 530 EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11)); 531 EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12)); 532 // Default name for the id that doesn't exist. 533 EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100)); 534 535 // and exit mirroring. 536 display_info_list.clear(); 537 display_info_list.push_back(internal_display_info); 538 display_info_list.push_back(external_display_info); 539 display_manager()->OnNativeDisplaysChanged(display_info_list); 540 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 541 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 542 EXPECT_FALSE(display_manager()->IsMirrored()); 543 EXPECT_EQ("0,0 500x500", 544 GetDisplayForId(internal_display_id).bounds().ToString()); 545 EXPECT_EQ("500,0 100x100", 546 GetDisplayForId(10).bounds().ToString()); 547 548 // Turn off internal 549 display_info_list.clear(); 550 display_info_list.push_back(external_display_info); 551 display_manager()->OnNativeDisplaysChanged(display_info_list); 552 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 553 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); 554 EXPECT_EQ("1,1 100x100", 555 GetDisplayInfoForId(external_id).bounds_in_native().ToString()); 556 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 557 EXPECT_FALSE(display_manager()->IsMirrored()); 558 559 // Switched to another display 560 display_info_list.clear(); 561 display_info_list.push_back(internal_display_info); 562 display_manager()->OnNativeDisplaysChanged(display_info_list); 563 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 564 EXPECT_EQ( 565 "0,0 500x500", 566 GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString()); 567 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 568 EXPECT_FALSE(display_manager()->IsMirrored()); 569 } 570 571 #if defined(OS_WIN) 572 // TODO(scottmg): RootWindow doesn't get resized on Windows 573 // Ash. http://crbug.com/247916. 574 #define MAYBE_TestNativeDisplaysChangedNoInternal \ 575 DISABLED_TestNativeDisplaysChangedNoInternal 576 #else 577 #define MAYBE_TestNativeDisplaysChangedNoInternal \ 578 TestNativeDisplaysChangedNoInternal 579 #endif 580 581 TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) { 582 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 583 584 // Don't change the display info if all displays are disconnected. 585 std::vector<DisplayInfo> display_info_list; 586 display_manager()->OnNativeDisplaysChanged(display_info_list); 587 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 588 589 // Connect another display which will become primary. 590 const DisplayInfo external_display_info = 591 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); 592 display_info_list.push_back(external_display_info); 593 display_manager()->OnNativeDisplaysChanged(display_info_list); 594 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 595 EXPECT_EQ("1,1 100x100", 596 GetDisplayInfoForId(10).bounds_in_native().ToString()); 597 EXPECT_EQ("100x100", ash::Shell::GetPrimaryRootWindow()->GetHost()-> 598 GetBounds().size().ToString()); 599 } 600 601 #if defined(OS_WIN) 602 // Tests that rely on the actual host size/location does not work on windows. 603 #define MAYBE_EnsurePointerInDisplays DISABLED_EnsurePointerInDisplays 604 #define MAYBE_EnsurePointerInDisplays_2ndOnLeft DISABLED_EnsurePointerInDisplays_2ndOnLeft 605 #else 606 #define MAYBE_EnsurePointerInDisplays EnsurePointerInDisplays 607 #define MAYBE_EnsurePointerInDisplays_2ndOnLeft EnsurePointerInDisplays_2ndOnLeft 608 #endif 609 610 TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays) { 611 UpdateDisplay("200x200,300x300"); 612 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 613 614 aura::Env* env = aura::Env::GetInstance(); 615 616 aura::test::EventGenerator generator(root_windows[0]); 617 618 // Set the initial position. 619 generator.MoveMouseToInHost(350, 150); 620 EXPECT_EQ("350,150", env->last_mouse_location().ToString()); 621 622 // A mouse pointer will stay in the 2nd display. 623 UpdateDisplay("300x300,200x200"); 624 EXPECT_EQ("450,50", env->last_mouse_location().ToString()); 625 626 // A mouse pointer will be outside of displays and move to the 627 // center of 2nd display. 628 UpdateDisplay("300x300,100x100"); 629 EXPECT_EQ("350,50", env->last_mouse_location().ToString()); 630 631 // 2nd display was disconnected, and the cursor is 632 // now in the 1st display. 633 UpdateDisplay("400x400"); 634 EXPECT_EQ("50,350", env->last_mouse_location().ToString()); 635 636 // 1st display's resolution has changed, and the mouse pointer is 637 // now outside. Move the mouse pointer to the center of 1st display. 638 UpdateDisplay("300x300"); 639 EXPECT_EQ("150,150", env->last_mouse_location().ToString()); 640 641 // Move the mouse pointer to the bottom of 1st display. 642 generator.MoveMouseToInHost(150, 290); 643 EXPECT_EQ("150,290", env->last_mouse_location().ToString()); 644 645 // The mouse pointer is now on 2nd display. 646 UpdateDisplay("300x280,200x200"); 647 EXPECT_EQ("450,10", env->last_mouse_location().ToString()); 648 } 649 650 TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays_2ndOnLeft) { 651 // Set the 2nd display on the left. 652 DisplayLayoutStore* layout_store = 653 Shell::GetInstance()->display_manager()->layout_store(); 654 DisplayLayout layout = layout_store->default_display_layout(); 655 layout.position = DisplayLayout::LEFT; 656 layout_store->SetDefaultDisplayLayout(layout); 657 658 UpdateDisplay("200x200,300x300"); 659 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 660 661 EXPECT_EQ("-300,0 300x300", 662 ScreenUtil::GetSecondaryDisplay().bounds().ToString()); 663 664 aura::Env* env = aura::Env::GetInstance(); 665 666 // Set the initial position. 667 root_windows[0]->MoveCursorTo(gfx::Point(-150, 250)); 668 EXPECT_EQ("-150,250", env->last_mouse_location().ToString()); 669 670 // A mouse pointer will stay in 2nd display. 671 UpdateDisplay("300x300,200x300"); 672 EXPECT_EQ("-50,150", env->last_mouse_location().ToString()); 673 674 // A mouse pointer will be outside of displays and move to the 675 // center of 2nd display. 676 UpdateDisplay("300x300,200x100"); 677 EXPECT_EQ("-100,50", env->last_mouse_location().ToString()); 678 679 // 2nd display was disconnected. Mouse pointer should move to 680 // 1st display. 681 UpdateDisplay("300x300"); 682 EXPECT_EQ("150,150", env->last_mouse_location().ToString()); 683 } 684 685 TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) { 686 if (!SupportsMultipleDisplays()) 687 return; 688 689 const int64 internal_display_id = 690 test::DisplayManagerTestApi(display_manager()). 691 SetFirstDisplayAsInternalDisplay(); 692 const DisplayInfo native_display_info = 693 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); 694 const DisplayInfo secondary_display_info = 695 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); 696 697 std::vector<DisplayInfo> display_info_list; 698 display_info_list.push_back(native_display_info); 699 display_info_list.push_back(secondary_display_info); 700 display_manager()->OnNativeDisplaysChanged(display_info_list); 701 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 702 EXPECT_EQ("0,0 500x500", 703 GetDisplayForId(internal_display_id).bounds().ToString()); 704 EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString()); 705 706 ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( 707 GetDisplayForId(secondary_display_info.id())); 708 EXPECT_EQ("-500,0 500x500", 709 GetDisplayForId(internal_display_id).bounds().ToString()); 710 EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString()); 711 712 // OnNativeDisplaysChanged may change the display bounds. Here makes sure 713 // nothing changed if the exactly same displays are specified. 714 display_manager()->OnNativeDisplaysChanged(display_info_list); 715 EXPECT_EQ("-500,0 500x500", 716 GetDisplayForId(internal_display_id).bounds().ToString()); 717 EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString()); 718 } 719 720 TEST_F(DisplayManagerTest, DontRememberBestResolution) { 721 int display_id = 1000; 722 DisplayInfo native_display_info = 723 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 724 std::vector<DisplayMode> display_modes; 725 display_modes.push_back( 726 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true)); 727 display_modes.push_back( 728 DisplayMode(gfx::Size(800, 300), 59.0f, false, false)); 729 display_modes.push_back( 730 DisplayMode(gfx::Size(400, 500), 60.0f, false, false)); 731 732 native_display_info.set_display_modes(display_modes); 733 734 std::vector<DisplayInfo> display_info_list; 735 display_info_list.push_back(native_display_info); 736 display_manager()->OnNativeDisplaysChanged(display_info_list); 737 738 DisplayMode mode; 739 EXPECT_FALSE( 740 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 741 742 // Unsupported resolution. 743 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 4000)); 744 EXPECT_FALSE( 745 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 746 747 // Supported resolution. 748 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 749 EXPECT_TRUE( 750 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 751 EXPECT_EQ("800x300", mode.size.ToString()); 752 EXPECT_EQ(59.0f, mode.refresh_rate); 753 EXPECT_FALSE(mode.native); 754 755 // Best resolution. 756 display_manager()->SetDisplayResolution(display_id, gfx::Size(1000, 500)); 757 EXPECT_TRUE( 758 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 759 EXPECT_EQ("1000x500", mode.size.ToString()); 760 EXPECT_EQ(58.0f, mode.refresh_rate); 761 EXPECT_TRUE(mode.native); 762 } 763 764 TEST_F(DisplayManagerTest, ResolutionFallback) { 765 int display_id = 1000; 766 DisplayInfo native_display_info = 767 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 768 std::vector<DisplayMode> display_modes; 769 display_modes.push_back( 770 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true)); 771 display_modes.push_back( 772 DisplayMode(gfx::Size(800, 300), 59.0f, false, false)); 773 display_modes.push_back( 774 DisplayMode(gfx::Size(400, 500), 60.0f, false, false)); 775 776 std::vector<DisplayMode> copy = display_modes; 777 native_display_info.set_display_modes(copy); 778 779 std::vector<DisplayInfo> display_info_list; 780 display_info_list.push_back(native_display_info); 781 display_manager()->OnNativeDisplaysChanged(display_info_list); 782 { 783 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 784 DisplayInfo new_native_display_info = 785 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 400, 500)); 786 copy = display_modes; 787 new_native_display_info.set_display_modes(copy); 788 std::vector<DisplayInfo> new_display_info_list; 789 new_display_info_list.push_back(new_native_display_info); 790 display_manager()->OnNativeDisplaysChanged(new_display_info_list); 791 792 DisplayMode mode; 793 EXPECT_TRUE( 794 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 795 EXPECT_EQ("400x500", mode.size.ToString()); 796 EXPECT_EQ(60.0f, mode.refresh_rate); 797 EXPECT_FALSE(mode.native); 798 } 799 { 800 // Best resolution should find itself on the resolutions list. 801 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 802 DisplayInfo new_native_display_info = 803 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 804 std::vector<DisplayMode> copy = display_modes; 805 new_native_display_info.set_display_modes(copy); 806 std::vector<DisplayInfo> new_display_info_list; 807 new_display_info_list.push_back(new_native_display_info); 808 display_manager()->OnNativeDisplaysChanged(new_display_info_list); 809 810 DisplayMode mode; 811 EXPECT_TRUE( 812 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 813 EXPECT_EQ("1000x500", mode.size.ToString()); 814 EXPECT_EQ(58.0f, mode.refresh_rate); 815 EXPECT_TRUE(mode.native); 816 } 817 } 818 819 TEST_F(DisplayManagerTest, Rotate) { 820 if (!SupportsMultipleDisplays()) 821 return; 822 823 UpdateDisplay("100x200/r,300x400/l"); 824 EXPECT_EQ("1,1 100x200", 825 GetDisplayInfoAt(0).bounds_in_native().ToString()); 826 EXPECT_EQ("200x100", 827 GetDisplayInfoAt(0).size_in_pixel().ToString()); 828 829 EXPECT_EQ("1,201 300x400", 830 GetDisplayInfoAt(1).bounds_in_native().ToString()); 831 EXPECT_EQ("400x300", 832 GetDisplayInfoAt(1).size_in_pixel().ToString()); 833 reset(); 834 UpdateDisplay("100x200/b,300x400"); 835 EXPECT_EQ("2 0 0", GetCountSummary()); 836 reset(); 837 838 EXPECT_EQ("1,1 100x200", 839 GetDisplayInfoAt(0).bounds_in_native().ToString()); 840 EXPECT_EQ("100x200", 841 GetDisplayInfoAt(0).size_in_pixel().ToString()); 842 843 EXPECT_EQ("1,201 300x400", 844 GetDisplayInfoAt(1).bounds_in_native().ToString()); 845 EXPECT_EQ("300x400", 846 GetDisplayInfoAt(1).size_in_pixel().ToString()); 847 848 // Just Rotating display will change the bounds on both display. 849 UpdateDisplay("100x200/l,300x400"); 850 EXPECT_EQ("2 0 0", GetCountSummary()); 851 reset(); 852 853 // Updating to the same configuration should report no changes. 854 UpdateDisplay("100x200/l,300x400"); 855 EXPECT_EQ("0 0 0", GetCountSummary()); 856 reset(); 857 858 // Rotating 180 degrees should report one change. 859 UpdateDisplay("100x200/r,300x400"); 860 EXPECT_EQ("1 0 0", GetCountSummary()); 861 reset(); 862 863 UpdateDisplay("200x200"); 864 EXPECT_EQ("1 0 1", GetCountSummary()); 865 reset(); 866 867 // Rotating 180 degrees should report one change. 868 UpdateDisplay("200x200/u"); 869 EXPECT_EQ("1 0 0", GetCountSummary()); 870 reset(); 871 872 UpdateDisplay("200x200/l"); 873 EXPECT_EQ("1 0 0", GetCountSummary()); 874 } 875 876 TEST_F(DisplayManagerTest, UIScale) { 877 UpdateDisplay("1280x800"); 878 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id(); 879 display_manager()->SetDisplayUIScale(display_id, 1.125f); 880 EXPECT_EQ(1.0, GetDisplayInfoAt(0).configured_ui_scale()); 881 display_manager()->SetDisplayUIScale(display_id, 0.8f); 882 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 883 display_manager()->SetDisplayUIScale(display_id, 0.75f); 884 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 885 display_manager()->SetDisplayUIScale(display_id, 0.625f); 886 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 887 888 gfx::Display::SetInternalDisplayId(display_id); 889 890 display_manager()->SetDisplayUIScale(display_id, 1.5f); 891 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 892 display_manager()->SetDisplayUIScale(display_id, 1.25f); 893 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 894 display_manager()->SetDisplayUIScale(display_id, 1.125f); 895 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 896 display_manager()->SetDisplayUIScale(display_id, 0.8f); 897 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 898 display_manager()->SetDisplayUIScale(display_id, 0.75f); 899 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 900 display_manager()->SetDisplayUIScale(display_id, 0.625f); 901 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 902 display_manager()->SetDisplayUIScale(display_id, 0.6f); 903 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 904 display_manager()->SetDisplayUIScale(display_id, 0.5f); 905 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 906 907 UpdateDisplay("1366x768"); 908 display_manager()->SetDisplayUIScale(display_id, 1.5f); 909 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 910 display_manager()->SetDisplayUIScale(display_id, 1.25f); 911 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 912 display_manager()->SetDisplayUIScale(display_id, 1.125f); 913 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 914 display_manager()->SetDisplayUIScale(display_id, 0.8f); 915 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 916 display_manager()->SetDisplayUIScale(display_id, 0.75f); 917 EXPECT_EQ(0.75f, GetDisplayInfoAt(0).configured_ui_scale()); 918 display_manager()->SetDisplayUIScale(display_id, 0.6f); 919 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); 920 display_manager()->SetDisplayUIScale(display_id, 0.625f); 921 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); 922 display_manager()->SetDisplayUIScale(display_id, 0.5f); 923 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 924 925 UpdateDisplay("1280x850*2"); 926 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 927 display_manager()->SetDisplayUIScale(display_id, 1.5f); 928 EXPECT_EQ(1.5f, GetDisplayInfoAt(0).configured_ui_scale()); 929 display_manager()->SetDisplayUIScale(display_id, 1.25f); 930 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).configured_ui_scale()); 931 display_manager()->SetDisplayUIScale(display_id, 1.125f); 932 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 933 display_manager()->SetDisplayUIScale(display_id, 1.0f); 934 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 935 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); 936 EXPECT_EQ(2.0f, display.device_scale_factor()); 937 EXPECT_EQ("640x425", display.bounds().size().ToString()); 938 939 display_manager()->SetDisplayUIScale(display_id, 0.8f); 940 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 941 display_manager()->SetDisplayUIScale(display_id, 0.75f); 942 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 943 display_manager()->SetDisplayUIScale(display_id, 0.625f); 944 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 945 display_manager()->SetDisplayUIScale(display_id, 0.6f); 946 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 947 display_manager()->SetDisplayUIScale(display_id, 0.5f); 948 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 949 950 display_manager()->SetDisplayUIScale(display_id, 2.0f); 951 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).configured_ui_scale()); 952 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 953 display = Shell::GetScreen()->GetPrimaryDisplay(); 954 EXPECT_EQ(1.0f, display.device_scale_factor()); 955 EXPECT_EQ("1280x850", display.bounds().size().ToString()); 956 } 957 958 TEST_F(DisplayManagerTest, UIScaleUpgradeToHighDPI) { 959 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id(); 960 gfx::Display::SetInternalDisplayId(display_id); 961 UpdateDisplay("1920x1080"); 962 963 DisplayInfo::SetAllowUpgradeToHighDPI(false); 964 display_manager()->SetDisplayUIScale(display_id, 1.125f); 965 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 966 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 967 EXPECT_EQ("2160x1215", GetDisplayForId(display_id).size().ToString()); 968 969 display_manager()->SetDisplayUIScale(display_id, 0.5f); 970 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 971 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 972 EXPECT_EQ("960x540", GetDisplayForId(display_id).size().ToString()); 973 974 DisplayInfo::SetAllowUpgradeToHighDPI(true); 975 display_manager()->SetDisplayUIScale(display_id, 1.125f); 976 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 977 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 978 EXPECT_EQ("2160x1215", GetDisplayForId(display_id).size().ToString()); 979 980 display_manager()->SetDisplayUIScale(display_id, 0.5f); 981 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 982 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 983 EXPECT_EQ("960x540", GetDisplayForId(display_id).size().ToString()); 984 985 // Upgrade only works on 1.0f DSF. 986 UpdateDisplay("1920x1080*2"); 987 display_manager()->SetDisplayUIScale(display_id, 1.125f); 988 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 989 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 990 EXPECT_EQ("1080x607", GetDisplayForId(display_id).size().ToString()); 991 992 display_manager()->SetDisplayUIScale(display_id, 0.5f); 993 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor()); 994 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 995 EXPECT_EQ("480x270", GetDisplayForId(display_id).size().ToString()); 996 } 997 998 #if defined(OS_WIN) 999 // TODO(scottmg): RootWindow doesn't get resized on Windows 1000 // Ash. http://crbug.com/247916. 1001 #define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom 1002 #else 1003 #define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom 1004 #endif 1005 1006 TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) { 1007 // Make sure just rotating will not change native location. 1008 UpdateDisplay("300x200,200x150"); 1009 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 1010 aura::Env* env = aura::Env::GetInstance(); 1011 1012 aura::test::EventGenerator generator1(root_windows[0]); 1013 aura::test::EventGenerator generator2(root_windows[1]); 1014 1015 // Test on 1st display. 1016 generator1.MoveMouseToInHost(150, 50); 1017 EXPECT_EQ("150,50", env->last_mouse_location().ToString()); 1018 UpdateDisplay("300x200/r,200x150"); 1019 EXPECT_EQ("50,149", env->last_mouse_location().ToString()); 1020 1021 // Test on 2nd display. 1022 generator2.MoveMouseToInHost(50, 100); 1023 EXPECT_EQ("250,100", env->last_mouse_location().ToString()); 1024 UpdateDisplay("300x200/r,200x150/l"); 1025 EXPECT_EQ("249,50", env->last_mouse_location().ToString()); 1026 1027 // The native location is now outside, so move to the center 1028 // of closest display. 1029 UpdateDisplay("300x200/r,100x50/l"); 1030 EXPECT_EQ("225,50", env->last_mouse_location().ToString()); 1031 1032 // Make sure just zooming will not change native location. 1033 UpdateDisplay("600x400*2,400x300"); 1034 1035 // Test on 1st display. 1036 generator1.MoveMouseToInHost(200, 300); 1037 EXPECT_EQ("100,150", env->last_mouse_location().ToString()); 1038 UpdateDisplay("600x400*2 (at) 1.5,400x300"); 1039 EXPECT_EQ("150,225", env->last_mouse_location().ToString()); 1040 1041 // Test on 2nd display. 1042 UpdateDisplay("600x400,400x300*2"); 1043 generator2.MoveMouseToInHost(200, 250); 1044 EXPECT_EQ("700,125", env->last_mouse_location().ToString()); 1045 UpdateDisplay("600x400,400x300*2 (at) 1.5"); 1046 EXPECT_EQ("750,187", env->last_mouse_location().ToString()); 1047 1048 // The native location is now outside, so move to the 1049 // center of closest display. 1050 UpdateDisplay("600x400,400x200*2 (at) 1.5"); 1051 EXPECT_EQ("750,75", env->last_mouse_location().ToString()); 1052 } 1053 1054 class TestDisplayObserver : public gfx::DisplayObserver { 1055 public: 1056 TestDisplayObserver() : changed_(false) {} 1057 virtual ~TestDisplayObserver() {} 1058 1059 // gfx::DisplayObserver overrides: 1060 virtual void OnDisplayMetricsChanged(const gfx::Display&,uint32_t) OVERRIDE {} 1061 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 1062 // Mirror window should already be delete before restoring 1063 // the external display. 1064 EXPECT_FALSE(test_api.GetHost()); 1065 changed_ = true; 1066 } 1067 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 1068 // Mirror window should not be created until the external display 1069 // is removed. 1070 EXPECT_FALSE(test_api.GetHost()); 1071 changed_ = true; 1072 } 1073 1074 bool changed_and_reset() { 1075 bool changed = changed_; 1076 changed_ = false; 1077 return changed; 1078 } 1079 1080 private: 1081 test::MirrorWindowTestApi test_api; 1082 bool changed_; 1083 1084 DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver); 1085 }; 1086 1087 TEST_F(DisplayManagerTest, SoftwareMirroring) { 1088 if (!SupportsMultipleDisplays()) 1089 return; 1090 1091 UpdateDisplay("300x400,400x500"); 1092 1093 test::MirrorWindowTestApi test_api; 1094 EXPECT_EQ(NULL, test_api.GetHost()); 1095 1096 TestDisplayObserver display_observer; 1097 Shell::GetScreen()->AddObserver(&display_observer); 1098 1099 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 1100 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 1101 display_manager->UpdateDisplays(); 1102 EXPECT_TRUE(display_observer.changed_and_reset()); 1103 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 1104 EXPECT_EQ("0,0 300x400", 1105 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); 1106 EXPECT_EQ("400x500", test_api.GetHost()->GetBounds().size().ToString()); 1107 EXPECT_EQ("300x400", 1108 test_api.GetHost()->window()->bounds().size().ToString()); 1109 EXPECT_TRUE(display_manager->IsMirrored()); 1110 1111 display_manager->SetMirrorMode(false); 1112 EXPECT_TRUE(display_observer.changed_and_reset()); 1113 EXPECT_EQ(NULL, test_api.GetHost()); 1114 EXPECT_EQ(2U, display_manager->GetNumDisplays()); 1115 EXPECT_FALSE(display_manager->IsMirrored()); 1116 1117 // Make sure the mirror window has the pixel size of the 1118 // source display. 1119 display_manager->SetMirrorMode(true); 1120 EXPECT_TRUE(display_observer.changed_and_reset()); 1121 1122 UpdateDisplay("300x400 (at) 0.5,400x500"); 1123 EXPECT_FALSE(display_observer.changed_and_reset()); 1124 EXPECT_EQ("300x400", 1125 test_api.GetHost()->window()->bounds().size().ToString()); 1126 1127 UpdateDisplay("310x410*2,400x500"); 1128 EXPECT_FALSE(display_observer.changed_and_reset()); 1129 EXPECT_EQ("310x410", 1130 test_api.GetHost()->window()->bounds().size().ToString()); 1131 1132 UpdateDisplay("320x420/r,400x500"); 1133 EXPECT_FALSE(display_observer.changed_and_reset()); 1134 EXPECT_EQ("320x420", 1135 test_api.GetHost()->window()->bounds().size().ToString()); 1136 1137 UpdateDisplay("330x440/r,400x500"); 1138 EXPECT_FALSE(display_observer.changed_and_reset()); 1139 EXPECT_EQ("330x440", 1140 test_api.GetHost()->window()->bounds().size().ToString()); 1141 1142 // Overscan insets are ignored. 1143 UpdateDisplay("400x600/o,600x800/o"); 1144 EXPECT_FALSE(display_observer.changed_and_reset()); 1145 EXPECT_EQ("400x600", 1146 test_api.GetHost()->window()->bounds().size().ToString()); 1147 1148 Shell::GetScreen()->RemoveObserver(&display_observer); 1149 } 1150 1151 TEST_F(DisplayManagerTest, MirroredLayout) { 1152 if (!SupportsMultipleDisplays()) 1153 return; 1154 1155 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 1156 UpdateDisplay("500x500,400x400"); 1157 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); 1158 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1159 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1160 1161 UpdateDisplay("1+0-500x500,1+0-500x500"); 1162 EXPECT_TRUE(display_manager->GetCurrentDisplayLayout().mirrored); 1163 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 1164 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1165 1166 UpdateDisplay("500x500,500x500"); 1167 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); 1168 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1169 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1170 } 1171 1172 TEST_F(DisplayManagerTest, InvertLayout) { 1173 EXPECT_EQ("left, 0", 1174 DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString()); 1175 EXPECT_EQ("left, -100", 1176 DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString()); 1177 EXPECT_EQ("left, 50", 1178 DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString()); 1179 1180 EXPECT_EQ("right, 0", 1181 DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString()); 1182 EXPECT_EQ("right, -90", 1183 DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString()); 1184 EXPECT_EQ("right, 60", 1185 DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString()); 1186 1187 EXPECT_EQ("bottom, 0", 1188 DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString()); 1189 EXPECT_EQ("bottom, -80", 1190 DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString()); 1191 EXPECT_EQ("bottom, 70", 1192 DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString()); 1193 1194 EXPECT_EQ("top, 0", 1195 DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString()); 1196 EXPECT_EQ("top, -70", 1197 DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString()); 1198 EXPECT_EQ("top, 80", 1199 DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString()); 1200 } 1201 1202 #if defined(OS_WIN) 1203 // TODO(scottmg): RootWindow doesn't get resized on Windows 1204 // Ash. http://crbug.com/247916. 1205 #define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin 1206 #else 1207 #define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin 1208 #endif 1209 1210 TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) { 1211 UpdateDisplay("100x200,300x400"); 1212 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1213 aura::Window::Windows root_windows = 1214 Shell::GetInstance()->GetAllRootWindows(); 1215 ASSERT_EQ(2U, root_windows.size()); 1216 aura::WindowTreeHost* host0 = root_windows[0]->GetHost(); 1217 aura::WindowTreeHost* host1 = root_windows[1]->GetHost(); 1218 1219 EXPECT_EQ("1,1", host0->GetBounds().origin().ToString()); 1220 EXPECT_EQ("100x200", host0->GetBounds().size().ToString()); 1221 // UpdateDisplay set the origin if it's not set. 1222 EXPECT_NE("1,1", host1->GetBounds().origin().ToString()); 1223 EXPECT_EQ("300x400", host1->GetBounds().size().ToString()); 1224 1225 UpdateDisplay("100x200,200+300-300x400"); 1226 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1227 EXPECT_EQ("0,0", host0->GetBounds().origin().ToString()); 1228 EXPECT_EQ("100x200", host0->GetBounds().size().ToString()); 1229 EXPECT_EQ("200,300", host1->GetBounds().origin().ToString()); 1230 EXPECT_EQ("300x400", host1->GetBounds().size().ToString()); 1231 1232 UpdateDisplay("400+500-200x300,300x400"); 1233 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1234 EXPECT_EQ("400,500", host0->GetBounds().origin().ToString()); 1235 EXPECT_EQ("200x300", host0->GetBounds().size().ToString()); 1236 EXPECT_EQ("0,0", host1->GetBounds().origin().ToString()); 1237 EXPECT_EQ("300x400", host1->GetBounds().size().ToString()); 1238 1239 UpdateDisplay("100+200-100x200,300+500-200x300"); 1240 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1241 EXPECT_EQ("100,200", host0->GetBounds().origin().ToString()); 1242 EXPECT_EQ("100x200", host0->GetBounds().size().ToString()); 1243 EXPECT_EQ("300,500", host1->GetBounds().origin().ToString()); 1244 EXPECT_EQ("200x300", host1->GetBounds().size().ToString()); 1245 } 1246 1247 1248 class ScreenShutdownTest : public test::AshTestBase { 1249 public: 1250 ScreenShutdownTest() { 1251 } 1252 virtual ~ScreenShutdownTest() {} 1253 1254 virtual void TearDown() OVERRIDE { 1255 gfx::Screen* orig_screen = 1256 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 1257 AshTestBase::TearDown(); 1258 if (!SupportsMultipleDisplays()) 1259 return; 1260 gfx::Screen* screen = 1261 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 1262 EXPECT_NE(orig_screen, screen); 1263 EXPECT_EQ(2, screen->GetNumDisplays()); 1264 EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString()); 1265 std::vector<gfx::Display> all = screen->GetAllDisplays(); 1266 EXPECT_EQ("500x300", all[0].size().ToString()); 1267 EXPECT_EQ("800x400", all[1].size().ToString()); 1268 } 1269 1270 private: 1271 DISALLOW_COPY_AND_ASSIGN(ScreenShutdownTest); 1272 }; 1273 1274 TEST_F(ScreenShutdownTest, ScreenAfterShutdown) { 1275 if (!SupportsMultipleDisplays()) 1276 return; 1277 UpdateDisplay("500x300,800x400"); 1278 } 1279 1280 } // namespace ash 1281