display_manager_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/root_window.h" 19#include "ui/aura/test/event_generator.h" 20#include "ui/aura/window_observer.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 26namespace ash { 27namespace internal { 28 29using std::vector; 30using std::string; 31 32using base::StringPrintf; 33 34namespace { 35 36std::string ToDisplayName(int64 id) { 37 return "x-" + base::Int64ToString(id); 38} 39 40} // namespace 41 42class DisplayManagerTest : public test::AshTestBase, 43 public gfx::DisplayObserver, 44 public aura::WindowObserver { 45 public: 46 DisplayManagerTest() 47 : removed_count_(0U), 48 root_window_destroyed_(false) { 49 } 50 virtual ~DisplayManagerTest() {} 51 52 virtual void SetUp() OVERRIDE { 53 AshTestBase::SetUp(); 54 Shell::GetScreen()->AddObserver(this); 55 Shell::GetPrimaryRootWindow()->AddObserver(this); 56 } 57 virtual void TearDown() OVERRIDE { 58 Shell::GetPrimaryRootWindow()->RemoveObserver(this); 59 Shell::GetScreen()->RemoveObserver(this); 60 AshTestBase::TearDown(); 61 } 62 63 DisplayManager* display_manager() { 64 return Shell::GetInstance()->display_manager(); 65 } 66 const vector<gfx::Display>& changed() const { return changed_; } 67 const vector<gfx::Display>& added() const { return added_; } 68 69 string GetCountSummary() const { 70 return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS, 71 changed_.size(), added_.size(), removed_count_); 72 } 73 74 void reset() { 75 changed_.clear(); 76 added_.clear(); 77 removed_count_ = 0U; 78 root_window_destroyed_ = false; 79 } 80 81 bool root_window_destroyed() const { 82 return root_window_destroyed_; 83 } 84 85 const DisplayInfo& GetDisplayInfo(const gfx::Display& display) { 86 return display_manager()->GetDisplayInfo(display.id()); 87 } 88 89 const DisplayInfo& GetDisplayInfoAt(int index) { 90 return GetDisplayInfo(display_manager()->GetDisplayAt(index)); 91 } 92 93 const gfx::Display& GetDisplayForId(int64 id) { 94 return display_manager()->GetDisplayForId(id); 95 } 96 97 const DisplayInfo& GetDisplayInfoForId(int64 id) { 98 return GetDisplayInfo(display_manager()->GetDisplayForId(id)); 99 } 100 101 // aura::DisplayObserver overrides: 102 virtual void OnDisplayBoundsChanged(const gfx::Display& display) 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 127TEST_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) 230TEST_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 253TEST_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 358TEST_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 382TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) { 383 if (!SupportsHostWindowResize()) 384 return; 385 386 UpdateDisplay("1000x600"); 387 aura::WindowEventDispatcher* dispatcher = 388 Shell::GetPrimaryRootWindow()->GetDispatcher(); 389 EXPECT_EQ(1, dispatcher->host()->compositor()->device_scale_factor()); 390 EXPECT_EQ("1000x600", 391 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 392 UpdateDisplay("1000x600*2"); 393 EXPECT_EQ(2, dispatcher->host()->compositor()->device_scale_factor()); 394 EXPECT_EQ("500x300", 395 Shell::GetPrimaryRootWindow()->bounds().size().ToString()); 396} 397 398DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { 399 DisplayInfo info(id, ToDisplayName(id), false); 400 info.SetBounds(bounds); 401 return info; 402} 403 404TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) { 405 const int64 internal_display_id = 406 test::DisplayManagerTestApi(display_manager()). 407 SetFirstDisplayAsInternalDisplay(); 408 const int external_id = 10; 409 const int mirror_id = 11; 410 const int64 invalid_id = gfx::Display::kInvalidDisplayID; 411 const DisplayInfo internal_display_info = 412 CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500)); 413 const DisplayInfo external_display_info = 414 CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100)); 415 const DisplayInfo mirrored_display_info = 416 CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500)); 417 418 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 419 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 420 std::string default_bounds = 421 display_manager()->GetDisplayAt(0).bounds().ToString(); 422 423 std::vector<DisplayInfo> display_info_list; 424 // Primary disconnected. 425 display_manager()->OnNativeDisplaysChanged(display_info_list); 426 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 427 EXPECT_EQ(default_bounds, 428 display_manager()->GetDisplayAt(0).bounds().ToString()); 429 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 430 EXPECT_FALSE(display_manager()->IsMirrored()); 431 432 if (!SupportsMultipleDisplays()) 433 return; 434 435 // External connected while primary was disconnected. 436 display_info_list.push_back(external_display_info); 437 display_manager()->OnNativeDisplaysChanged(display_info_list); 438 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 439 440 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); 441 EXPECT_EQ("1,1 100x100", 442 GetDisplayInfoForId(external_id).bounds_in_native().ToString()); 443 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 444 EXPECT_FALSE(display_manager()->IsMirrored()); 445 EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 446 447 EXPECT_EQ(internal_display_id, gfx::Display::InternalDisplayId()); 448 449 // Primary connected, with different bounds. 450 display_info_list.clear(); 451 display_info_list.push_back(internal_display_info); 452 display_info_list.push_back(external_display_info); 453 display_manager()->OnNativeDisplaysChanged(display_info_list); 454 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 455 EXPECT_EQ(internal_display_id, Shell::GetScreen()->GetPrimaryDisplay().id()); 456 457 // This combinatino is new, so internal display becomes primary. 458 EXPECT_EQ("0,0 500x500", 459 GetDisplayForId(internal_display_id).bounds().ToString()); 460 EXPECT_EQ("1,1 100x100", 461 GetDisplayInfoForId(10).bounds_in_native().ToString()); 462 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 463 EXPECT_FALSE(display_manager()->IsMirrored()); 464 EXPECT_EQ(ToDisplayName(internal_display_id), 465 display_manager()->GetDisplayNameForId(internal_display_id)); 466 467 // Emulate suspend. 468 display_info_list.clear(); 469 display_manager()->OnNativeDisplaysChanged(display_info_list); 470 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 471 EXPECT_EQ("0,0 500x500", 472 GetDisplayForId(internal_display_id).bounds().ToString()); 473 EXPECT_EQ("1,1 100x100", 474 GetDisplayInfoForId(10).bounds_in_native().ToString()); 475 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 476 EXPECT_FALSE(display_manager()->IsMirrored()); 477 EXPECT_EQ(ToDisplayName(internal_display_id), 478 display_manager()->GetDisplayNameForId(internal_display_id)); 479 480 // External display has disconnected then resumed. 481 display_info_list.push_back(internal_display_info); 482 display_manager()->OnNativeDisplaysChanged(display_info_list); 483 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 484 EXPECT_EQ("0,0 500x500", 485 GetDisplayForId(internal_display_id).bounds().ToString()); 486 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 487 EXPECT_FALSE(display_manager()->IsMirrored()); 488 489 // External display was changed during suspend. 490 display_info_list.push_back(external_display_info); 491 display_manager()->OnNativeDisplaysChanged(display_info_list); 492 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 493 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 494 EXPECT_FALSE(display_manager()->IsMirrored()); 495 496 // suspend... 497 display_info_list.clear(); 498 display_manager()->OnNativeDisplaysChanged(display_info_list); 499 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 500 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 501 EXPECT_FALSE(display_manager()->IsMirrored()); 502 503 // and resume with different external display. 504 display_info_list.push_back(internal_display_info); 505 display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100))); 506 display_manager()->OnNativeDisplaysChanged(display_info_list); 507 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 508 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 509 EXPECT_FALSE(display_manager()->IsMirrored()); 510 EXPECT_FALSE(display_manager()->IsMirrored()); 511 512 // mirrored... 513 display_info_list.clear(); 514 display_info_list.push_back(internal_display_info); 515 display_info_list.push_back(mirrored_display_info); 516 display_manager()->OnNativeDisplaysChanged(display_info_list); 517 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 518 EXPECT_EQ("0,0 500x500", 519 GetDisplayForId(internal_display_id).bounds().ToString()); 520 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 521 EXPECT_EQ(11U, display_manager()->mirrored_display_id()); 522 EXPECT_TRUE(display_manager()->IsMirrored()); 523 524 // Test display name. 525 EXPECT_EQ(ToDisplayName(internal_display_id), 526 display_manager()->GetDisplayNameForId(internal_display_id)); 527 EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10)); 528 EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11)); 529 EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12)); 530 // Default name for the id that doesn't exist. 531 EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100)); 532 533 // and exit mirroring. 534 display_info_list.clear(); 535 display_info_list.push_back(internal_display_info); 536 display_info_list.push_back(external_display_info); 537 display_manager()->OnNativeDisplaysChanged(display_info_list); 538 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 539 EXPECT_EQ(2U, display_manager()->num_connected_displays()); 540 EXPECT_FALSE(display_manager()->IsMirrored()); 541 EXPECT_EQ("0,0 500x500", 542 GetDisplayForId(internal_display_id).bounds().ToString()); 543 EXPECT_EQ("500,0 100x100", 544 GetDisplayForId(10).bounds().ToString()); 545 546 // Turn off internal 547 display_info_list.clear(); 548 display_info_list.push_back(external_display_info); 549 display_manager()->OnNativeDisplaysChanged(display_info_list); 550 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 551 EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id()); 552 EXPECT_EQ("1,1 100x100", 553 GetDisplayInfoForId(external_id).bounds_in_native().ToString()); 554 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 555 EXPECT_FALSE(display_manager()->IsMirrored()); 556 557 // Switched to another display 558 display_info_list.clear(); 559 display_info_list.push_back(internal_display_info); 560 display_manager()->OnNativeDisplaysChanged(display_info_list); 561 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 562 EXPECT_EQ( 563 "0,0 500x500", 564 GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString()); 565 EXPECT_EQ(1U, display_manager()->num_connected_displays()); 566 EXPECT_FALSE(display_manager()->IsMirrored()); 567} 568 569#if defined(OS_WIN) 570// TODO(scottmg): RootWindow doesn't get resized on Windows 571// Ash. http://crbug.com/247916. 572#define MAYBE_TestNativeDisplaysChangedNoInternal \ 573 DISABLED_TestNativeDisplaysChangedNoInternal 574#else 575#define MAYBE_TestNativeDisplaysChangedNoInternal \ 576 TestNativeDisplaysChangedNoInternal 577#endif 578 579TEST_F(DisplayManagerTest, MAYBE_TestNativeDisplaysChangedNoInternal) { 580 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 581 582 // Don't change the display info if all displays are disconnected. 583 std::vector<DisplayInfo> display_info_list; 584 display_manager()->OnNativeDisplaysChanged(display_info_list); 585 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 586 587 // Connect another display which will become primary. 588 const DisplayInfo external_display_info = 589 CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100)); 590 display_info_list.push_back(external_display_info); 591 display_manager()->OnNativeDisplaysChanged(display_info_list); 592 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 593 EXPECT_EQ("1,1 100x100", 594 GetDisplayInfoForId(10).bounds_in_native().ToString()); 595 EXPECT_EQ("100x100", ash::Shell::GetPrimaryRootWindow()->GetDispatcher()-> 596 host()->GetBounds().size().ToString()); 597} 598 599#if defined(OS_WIN) 600// Tests that rely on the actual host size/location does not work on windows. 601#define MAYBE_EnsurePointerInDisplays DISABLED_EnsurePointerInDisplays 602#define MAYBE_EnsurePointerInDisplays_2ndOnLeft DISABLED_EnsurePointerInDisplays_2ndOnLeft 603#else 604#define MAYBE_EnsurePointerInDisplays EnsurePointerInDisplays 605#define MAYBE_EnsurePointerInDisplays_2ndOnLeft EnsurePointerInDisplays_2ndOnLeft 606#endif 607 608TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays) { 609 UpdateDisplay("200x200,300x300"); 610 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 611 612 aura::Env* env = aura::Env::GetInstance(); 613 614 aura::test::EventGenerator generator(root_windows[0]); 615 616 // Set the initial position. 617 generator.MoveMouseToInHost(350, 150); 618 EXPECT_EQ("350,150", env->last_mouse_location().ToString()); 619 620 // A mouse pointer will stay in the 2nd display. 621 UpdateDisplay("300x300,200x200"); 622 EXPECT_EQ("450,50", env->last_mouse_location().ToString()); 623 624 // A mouse pointer will be outside of displays and move to the 625 // center of 2nd display. 626 UpdateDisplay("300x300,100x100"); 627 EXPECT_EQ("350,50", env->last_mouse_location().ToString()); 628 629 // 2nd display was disconnected, and the cursor is 630 // now in the 1st display. 631 UpdateDisplay("400x400"); 632 EXPECT_EQ("50,350", env->last_mouse_location().ToString()); 633 634 // 1st display's resolution has changed, and the mouse pointer is 635 // now outside. Move the mouse pointer to the center of 1st display. 636 UpdateDisplay("300x300"); 637 EXPECT_EQ("150,150", env->last_mouse_location().ToString()); 638 639 // Move the mouse pointer to the bottom of 1st display. 640 generator.MoveMouseToInHost(150, 290); 641 EXPECT_EQ("150,290", env->last_mouse_location().ToString()); 642 643 // The mouse pointer is now on 2nd display. 644 UpdateDisplay("300x280,200x200"); 645 EXPECT_EQ("450,10", env->last_mouse_location().ToString()); 646} 647 648TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays_2ndOnLeft) { 649 // Set the 2nd display on the left. 650 DisplayLayoutStore* layout_store = 651 Shell::GetInstance()->display_manager()->layout_store(); 652 DisplayLayout layout = layout_store->default_display_layout(); 653 layout.position = DisplayLayout::LEFT; 654 layout_store->SetDefaultDisplayLayout(layout); 655 656 UpdateDisplay("200x200,300x300"); 657 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 658 659 EXPECT_EQ("-300,0 300x300", 660 ScreenUtil::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, 250)); 666 EXPECT_EQ("-150,250", env->last_mouse_location().ToString()); 667 668 // A mouse pointer will stay in 2nd display. 669 UpdateDisplay("300x300,200x300"); 670 EXPECT_EQ("-50,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 GetDisplayForId(internal_display_id).bounds().ToString()); 702 EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString()); 703 704 ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( 705 GetDisplayForId(secondary_display_info.id())); 706 EXPECT_EQ("-500,0 500x500", 707 GetDisplayForId(internal_display_id).bounds().ToString()); 708 EXPECT_EQ("0,0 100x100", GetDisplayForId(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 GetDisplayForId(internal_display_id).bounds().ToString()); 715 EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString()); 716} 717 718TEST_F(DisplayManagerTest, DontRememberBestResolution) { 719 int display_id = 1000; 720 DisplayInfo native_display_info = 721 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 722 std::vector<DisplayMode> display_modes; 723 display_modes.push_back( 724 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true)); 725 display_modes.push_back( 726 DisplayMode(gfx::Size(800, 300), 59.0f, false, false)); 727 display_modes.push_back( 728 DisplayMode(gfx::Size(400, 500), 60.0f, false, false)); 729 730 native_display_info.set_display_modes(display_modes); 731 732 std::vector<DisplayInfo> display_info_list; 733 display_info_list.push_back(native_display_info); 734 display_manager()->OnNativeDisplaysChanged(display_info_list); 735 736 DisplayMode mode; 737 EXPECT_FALSE( 738 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 739 740 // Unsupported resolution. 741 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 4000)); 742 EXPECT_FALSE( 743 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 744 745 // Supported resolution. 746 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 747 EXPECT_TRUE( 748 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 749 EXPECT_EQ("800x300", mode.size.ToString()); 750 EXPECT_EQ(59.0f, mode.refresh_rate); 751 EXPECT_FALSE(mode.native); 752 753 // Best resolution. 754 display_manager()->SetDisplayResolution(display_id, gfx::Size(1000, 500)); 755 EXPECT_TRUE( 756 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 757 EXPECT_EQ("1000x500", mode.size.ToString()); 758 EXPECT_EQ(58.0f, mode.refresh_rate); 759 EXPECT_TRUE(mode.native); 760} 761 762TEST_F(DisplayManagerTest, ResolutionFallback) { 763 int display_id = 1000; 764 DisplayInfo native_display_info = 765 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 766 std::vector<DisplayMode> display_modes; 767 display_modes.push_back( 768 DisplayMode(gfx::Size(1000, 500), 58.0f, false, true)); 769 display_modes.push_back( 770 DisplayMode(gfx::Size(800, 300), 59.0f, false, false)); 771 display_modes.push_back( 772 DisplayMode(gfx::Size(400, 500), 60.0f, false, false)); 773 774 std::vector<DisplayMode> copy = display_modes; 775 native_display_info.set_display_modes(copy); 776 777 std::vector<DisplayInfo> display_info_list; 778 display_info_list.push_back(native_display_info); 779 display_manager()->OnNativeDisplaysChanged(display_info_list); 780 { 781 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 782 DisplayInfo new_native_display_info = 783 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 400, 500)); 784 copy = display_modes; 785 new_native_display_info.set_display_modes(copy); 786 std::vector<DisplayInfo> new_display_info_list; 787 new_display_info_list.push_back(new_native_display_info); 788 display_manager()->OnNativeDisplaysChanged(new_display_info_list); 789 790 DisplayMode mode; 791 EXPECT_TRUE( 792 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 793 EXPECT_EQ("400x500", mode.size.ToString()); 794 EXPECT_EQ(60.0f, mode.refresh_rate); 795 EXPECT_FALSE(mode.native); 796 } 797 { 798 // Best resolution should find itself on the resolutions list. 799 display_manager()->SetDisplayResolution(display_id, gfx::Size(800, 300)); 800 DisplayInfo new_native_display_info = 801 CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500)); 802 std::vector<DisplayMode> copy = display_modes; 803 new_native_display_info.set_display_modes(copy); 804 std::vector<DisplayInfo> new_display_info_list; 805 new_display_info_list.push_back(new_native_display_info); 806 display_manager()->OnNativeDisplaysChanged(new_display_info_list); 807 808 DisplayMode mode; 809 EXPECT_TRUE( 810 display_manager()->GetSelectedModeForDisplayId(display_id, &mode)); 811 EXPECT_EQ("1000x500", mode.size.ToString()); 812 EXPECT_EQ(58.0f, mode.refresh_rate); 813 EXPECT_TRUE(mode.native); 814 } 815} 816 817TEST_F(DisplayManagerTest, Rotate) { 818 if (!SupportsMultipleDisplays()) 819 return; 820 821 UpdateDisplay("100x200/r,300x400/l"); 822 EXPECT_EQ("1,1 100x200", 823 GetDisplayInfoAt(0).bounds_in_native().ToString()); 824 EXPECT_EQ("200x100", 825 GetDisplayInfoAt(0).size_in_pixel().ToString()); 826 827 EXPECT_EQ("1,201 300x400", 828 GetDisplayInfoAt(1).bounds_in_native().ToString()); 829 EXPECT_EQ("400x300", 830 GetDisplayInfoAt(1).size_in_pixel().ToString()); 831 reset(); 832 UpdateDisplay("100x200/b,300x400"); 833 EXPECT_EQ("2 0 0", GetCountSummary()); 834 reset(); 835 836 EXPECT_EQ("1,1 100x200", 837 GetDisplayInfoAt(0).bounds_in_native().ToString()); 838 EXPECT_EQ("100x200", 839 GetDisplayInfoAt(0).size_in_pixel().ToString()); 840 841 EXPECT_EQ("1,201 300x400", 842 GetDisplayInfoAt(1).bounds_in_native().ToString()); 843 EXPECT_EQ("300x400", 844 GetDisplayInfoAt(1).size_in_pixel().ToString()); 845 846 // Just Rotating display will change the bounds on both display. 847 UpdateDisplay("100x200/l,300x400"); 848 EXPECT_EQ("2 0 0", GetCountSummary()); 849 reset(); 850 851 // Updating tothe same configuration should report no changes. 852 UpdateDisplay("100x200/l,300x400"); 853 EXPECT_EQ("0 0 0", GetCountSummary()); 854 reset(); 855 856 UpdateDisplay("100x200/l,300x400"); 857 EXPECT_EQ("0 0 0", GetCountSummary()); 858 reset(); 859 860 UpdateDisplay("200x200"); 861 EXPECT_EQ("1 0 1", GetCountSummary()); 862 reset(); 863 864 UpdateDisplay("200x200/l"); 865 EXPECT_EQ("1 0 0", GetCountSummary()); 866} 867 868TEST_F(DisplayManagerTest, UIScale) { 869 UpdateDisplay("1280x800"); 870 int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id(); 871 display_manager()->SetDisplayUIScale(display_id, 1.125f); 872 EXPECT_EQ(1.0, GetDisplayInfoAt(0).configured_ui_scale()); 873 display_manager()->SetDisplayUIScale(display_id, 0.8f); 874 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 875 display_manager()->SetDisplayUIScale(display_id, 0.75f); 876 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 877 display_manager()->SetDisplayUIScale(display_id, 0.625f); 878 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 879 880 gfx::Display::SetInternalDisplayId(display_id); 881 882 display_manager()->SetDisplayUIScale(display_id, 1.5f); 883 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 884 display_manager()->SetDisplayUIScale(display_id, 1.25f); 885 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 886 display_manager()->SetDisplayUIScale(display_id, 1.125f); 887 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 888 display_manager()->SetDisplayUIScale(display_id, 0.8f); 889 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 890 display_manager()->SetDisplayUIScale(display_id, 0.75f); 891 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 892 display_manager()->SetDisplayUIScale(display_id, 0.625f); 893 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 894 display_manager()->SetDisplayUIScale(display_id, 0.6f); 895 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 896 display_manager()->SetDisplayUIScale(display_id, 0.5f); 897 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 898 899 UpdateDisplay("1366x768"); 900 display_manager()->SetDisplayUIScale(display_id, 1.5f); 901 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 902 display_manager()->SetDisplayUIScale(display_id, 1.25f); 903 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 904 display_manager()->SetDisplayUIScale(display_id, 1.125f); 905 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 906 display_manager()->SetDisplayUIScale(display_id, 0.8f); 907 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 908 display_manager()->SetDisplayUIScale(display_id, 0.75f); 909 EXPECT_EQ(0.75f, GetDisplayInfoAt(0).configured_ui_scale()); 910 display_manager()->SetDisplayUIScale(display_id, 0.6f); 911 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); 912 display_manager()->SetDisplayUIScale(display_id, 0.625f); 913 EXPECT_EQ(0.6f, GetDisplayInfoAt(0).configured_ui_scale()); 914 display_manager()->SetDisplayUIScale(display_id, 0.5f); 915 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 916 917 UpdateDisplay("1280x850*2"); 918 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 919 display_manager()->SetDisplayUIScale(display_id, 1.5f); 920 EXPECT_EQ(1.5f, GetDisplayInfoAt(0).configured_ui_scale()); 921 display_manager()->SetDisplayUIScale(display_id, 1.25f); 922 EXPECT_EQ(1.25f, GetDisplayInfoAt(0).configured_ui_scale()); 923 display_manager()->SetDisplayUIScale(display_id, 1.125f); 924 EXPECT_EQ(1.125f, GetDisplayInfoAt(0).configured_ui_scale()); 925 display_manager()->SetDisplayUIScale(display_id, 1.0f); 926 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).configured_ui_scale()); 927 gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay(); 928 EXPECT_EQ(2.0f, display.device_scale_factor()); 929 EXPECT_EQ("640x425", display.bounds().size().ToString()); 930 931 display_manager()->SetDisplayUIScale(display_id, 0.8f); 932 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 933 display_manager()->SetDisplayUIScale(display_id, 0.75f); 934 EXPECT_EQ(0.8f, GetDisplayInfoAt(0).configured_ui_scale()); 935 display_manager()->SetDisplayUIScale(display_id, 0.625f); 936 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 937 display_manager()->SetDisplayUIScale(display_id, 0.6f); 938 EXPECT_EQ(0.625f, GetDisplayInfoAt(0).configured_ui_scale()); 939 display_manager()->SetDisplayUIScale(display_id, 0.5f); 940 EXPECT_EQ(0.5f, GetDisplayInfoAt(0).configured_ui_scale()); 941 942 display_manager()->SetDisplayUIScale(display_id, 2.0f); 943 EXPECT_EQ(2.0f, GetDisplayInfoAt(0).configured_ui_scale()); 944 EXPECT_EQ(1.0f, GetDisplayInfoAt(0).GetEffectiveUIScale()); 945 display = Shell::GetScreen()->GetPrimaryDisplay(); 946 EXPECT_EQ(1.0f, display.device_scale_factor()); 947 EXPECT_EQ("1280x850", display.bounds().size().ToString()); 948} 949 950 951#if defined(OS_WIN) 952// TODO(scottmg): RootWindow doesn't get resized on Windows 953// Ash. http://crbug.com/247916. 954#define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom 955#else 956#define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom 957#endif 958 959TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) { 960 // Make sure just rotating will not change native location. 961 UpdateDisplay("300x200,200x150"); 962 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 963 aura::Env* env = aura::Env::GetInstance(); 964 965 aura::test::EventGenerator generator1(root_windows[0]); 966 aura::test::EventGenerator generator2(root_windows[1]); 967 968 // Test on 1st display. 969 generator1.MoveMouseToInHost(150, 50); 970 EXPECT_EQ("150,50", env->last_mouse_location().ToString()); 971 UpdateDisplay("300x200/r,200x150"); 972 EXPECT_EQ("50,149", env->last_mouse_location().ToString()); 973 974 // Test on 2nd display. 975 generator2.MoveMouseToInHost(50, 100); 976 EXPECT_EQ("250,100", env->last_mouse_location().ToString()); 977 UpdateDisplay("300x200/r,200x150/l"); 978 EXPECT_EQ("249,50", env->last_mouse_location().ToString()); 979 980 // The native location is now outside, so move to the center 981 // of closest display. 982 UpdateDisplay("300x200/r,100x50/l"); 983 EXPECT_EQ("225,50", env->last_mouse_location().ToString()); 984 985 // Make sure just zooming will not change native location. 986 UpdateDisplay("600x400*2,400x300"); 987 988 // Test on 1st display. 989 generator1.MoveMouseToInHost(200, 300); 990 EXPECT_EQ("100,150", env->last_mouse_location().ToString()); 991 UpdateDisplay("600x400*2@1.5,400x300"); 992 EXPECT_EQ("150,225", env->last_mouse_location().ToString()); 993 994 // Test on 2nd display. 995 UpdateDisplay("600x400,400x300*2"); 996 generator2.MoveMouseToInHost(200, 250); 997 EXPECT_EQ("700,125", env->last_mouse_location().ToString()); 998 UpdateDisplay("600x400,400x300*2@1.5"); 999 EXPECT_EQ("750,187", env->last_mouse_location().ToString()); 1000 1001 // The native location is now outside, so move to the 1002 // center of closest display. 1003 UpdateDisplay("600x400,400x200*2@1.5"); 1004 EXPECT_EQ("750,75", env->last_mouse_location().ToString()); 1005} 1006 1007class TestDisplayObserver : public gfx::DisplayObserver { 1008 public: 1009 TestDisplayObserver() : changed_(false) {} 1010 virtual ~TestDisplayObserver() {} 1011 1012 // gfx::DisplayObserver overrides: 1013 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { 1014 } 1015 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 1016 // Mirror window should already be delete before restoring 1017 // the external dispay. 1018 EXPECT_FALSE(test_api.GetRootWindow()); 1019 changed_ = true; 1020 } 1021 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 1022 // Mirror window should not be created until the external display 1023 // is removed. 1024 EXPECT_FALSE(test_api.GetRootWindow()); 1025 changed_ = true; 1026 } 1027 1028 bool changed_and_reset() { 1029 bool changed = changed_; 1030 changed_ = false; 1031 return changed; 1032 } 1033 1034 private: 1035 test::MirrorWindowTestApi test_api; 1036 bool changed_; 1037 1038 DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver); 1039}; 1040 1041TEST_F(DisplayManagerTest, SoftwareMirroring) { 1042 if (!SupportsMultipleDisplays()) 1043 return; 1044 1045 UpdateDisplay("300x400,400x500"); 1046 1047 test::MirrorWindowTestApi test_api; 1048 EXPECT_EQ(NULL, test_api.GetRootWindow()); 1049 1050 TestDisplayObserver display_observer; 1051 Shell::GetScreen()->AddObserver(&display_observer); 1052 1053 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 1054 display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING); 1055 display_manager->UpdateDisplays(); 1056 EXPECT_TRUE(display_observer.changed_and_reset()); 1057 EXPECT_EQ(1U, display_manager->GetNumDisplays()); 1058 EXPECT_EQ("0,0 300x400", 1059 Shell::GetScreen()->GetPrimaryDisplay().bounds().ToString()); 1060 EXPECT_EQ("400x500", 1061 test_api.GetRootWindow()->host()->GetBounds().size().ToString()); 1062 EXPECT_EQ("300x400", 1063 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1064 EXPECT_TRUE(display_manager->IsMirrored()); 1065 1066 display_manager->SetMirrorMode(false); 1067 EXPECT_TRUE(display_observer.changed_and_reset()); 1068 EXPECT_EQ(NULL, test_api.GetRootWindow()); 1069 EXPECT_EQ(2U, display_manager->GetNumDisplays()); 1070 EXPECT_FALSE(display_manager->IsMirrored()); 1071 1072 // Make sure the mirror window has the pixel size of the 1073 // source display. 1074 display_manager->SetMirrorMode(true); 1075 EXPECT_TRUE(display_observer.changed_and_reset()); 1076 1077 UpdateDisplay("300x400@0.5,400x500"); 1078 EXPECT_FALSE(display_observer.changed_and_reset()); 1079 EXPECT_EQ("300x400", 1080 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1081 1082 UpdateDisplay("310x410*2,400x500"); 1083 EXPECT_FALSE(display_observer.changed_and_reset()); 1084 EXPECT_EQ("310x410", 1085 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1086 1087 UpdateDisplay("320x420/r,400x500"); 1088 EXPECT_FALSE(display_observer.changed_and_reset()); 1089 EXPECT_EQ("320x420", 1090 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1091 1092 UpdateDisplay("330x440/r,400x500"); 1093 EXPECT_FALSE(display_observer.changed_and_reset()); 1094 EXPECT_EQ("330x440", 1095 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1096 1097 // Overscan insets are ignored. 1098 UpdateDisplay("400x600/o,600x800/o"); 1099 EXPECT_FALSE(display_observer.changed_and_reset()); 1100 EXPECT_EQ("400x600", 1101 test_api.GetRootWindow()->window()->bounds().size().ToString()); 1102 1103 Shell::GetScreen()->RemoveObserver(&display_observer); 1104} 1105 1106TEST_F(DisplayManagerTest, MirroredLayout) { 1107 if (!SupportsMultipleDisplays()) 1108 return; 1109 1110 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 1111 UpdateDisplay("500x500,400x400"); 1112 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); 1113 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1114 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1115 1116 UpdateDisplay("1+0-500x500,1+0-500x500"); 1117 EXPECT_TRUE(display_manager->GetCurrentDisplayLayout().mirrored); 1118 EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays()); 1119 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1120 1121 UpdateDisplay("500x500,500x500"); 1122 EXPECT_FALSE(display_manager->GetCurrentDisplayLayout().mirrored); 1123 EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1124 EXPECT_EQ(2U, display_manager->num_connected_displays()); 1125} 1126 1127TEST_F(DisplayManagerTest, InvertLayout) { 1128 EXPECT_EQ("left, 0", 1129 DisplayLayout(DisplayLayout::RIGHT, 0).Invert().ToString()); 1130 EXPECT_EQ("left, -100", 1131 DisplayLayout(DisplayLayout::RIGHT, 100).Invert().ToString()); 1132 EXPECT_EQ("left, 50", 1133 DisplayLayout(DisplayLayout::RIGHT, -50).Invert().ToString()); 1134 1135 EXPECT_EQ("right, 0", 1136 DisplayLayout(DisplayLayout::LEFT, 0).Invert().ToString()); 1137 EXPECT_EQ("right, -90", 1138 DisplayLayout(DisplayLayout::LEFT, 90).Invert().ToString()); 1139 EXPECT_EQ("right, 60", 1140 DisplayLayout(DisplayLayout::LEFT, -60).Invert().ToString()); 1141 1142 EXPECT_EQ("bottom, 0", 1143 DisplayLayout(DisplayLayout::TOP, 0).Invert().ToString()); 1144 EXPECT_EQ("bottom, -80", 1145 DisplayLayout(DisplayLayout::TOP, 80).Invert().ToString()); 1146 EXPECT_EQ("bottom, 70", 1147 DisplayLayout(DisplayLayout::TOP, -70).Invert().ToString()); 1148 1149 EXPECT_EQ("top, 0", 1150 DisplayLayout(DisplayLayout::BOTTOM, 0).Invert().ToString()); 1151 EXPECT_EQ("top, -70", 1152 DisplayLayout(DisplayLayout::BOTTOM, 70).Invert().ToString()); 1153 EXPECT_EQ("top, 80", 1154 DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString()); 1155} 1156 1157#if defined(OS_WIN) 1158// TODO(scottmg): RootWindow doesn't get resized on Windows 1159// Ash. http://crbug.com/247916. 1160#define MAYBE_UpdateDisplayWithHostOrigin DISABLED_UpdateDisplayWithHostOrigin 1161#else 1162#define MAYBE_UpdateDisplayWithHostOrigin UpdateDisplayWithHostOrigin 1163#endif 1164 1165TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) { 1166 UpdateDisplay("100x200,300x400"); 1167 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1168 aura::Window::Windows root_windows = 1169 Shell::GetInstance()->GetAllRootWindows(); 1170 ASSERT_EQ(2U, root_windows.size()); 1171 aura::WindowEventDispatcher* dispatcher0 = root_windows[0]->GetDispatcher(); 1172 aura::WindowEventDispatcher* dispatcher1 = root_windows[1]->GetDispatcher(); 1173 1174 EXPECT_EQ("1,1", dispatcher0->host()->GetBounds().origin().ToString()); 1175 EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); 1176 // UpdateDisplay set the origin if it's not set. 1177 EXPECT_NE("1,1", dispatcher1->host()->GetBounds().origin().ToString()); 1178 EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); 1179 1180 UpdateDisplay("100x200,200+300-300x400"); 1181 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1182 EXPECT_EQ("0,0", dispatcher0->host()->GetBounds().origin().ToString()); 1183 EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); 1184 EXPECT_EQ("200,300", dispatcher1->host()->GetBounds().origin().ToString()); 1185 EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); 1186 1187 UpdateDisplay("400+500-200x300,300x400"); 1188 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1189 EXPECT_EQ("400,500", dispatcher0->host()->GetBounds().origin().ToString()); 1190 EXPECT_EQ("200x300", dispatcher0->host()->GetBounds().size().ToString()); 1191 EXPECT_EQ("0,0", dispatcher1->host()->GetBounds().origin().ToString()); 1192 EXPECT_EQ("300x400", dispatcher1->host()->GetBounds().size().ToString()); 1193 1194 UpdateDisplay("100+200-100x200,300+500-200x300"); 1195 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays()); 1196 EXPECT_EQ("100,200", dispatcher0->host()->GetBounds().origin().ToString()); 1197 EXPECT_EQ("100x200", dispatcher0->host()->GetBounds().size().ToString()); 1198 EXPECT_EQ("300,500", dispatcher1->host()->GetBounds().origin().ToString()); 1199 EXPECT_EQ("200x300", dispatcher1->host()->GetBounds().size().ToString()); 1200} 1201 1202 1203class ScreenShutdownTest : public test::AshTestBase { 1204 public: 1205 ScreenShutdownTest() { 1206 } 1207 virtual ~ScreenShutdownTest() {} 1208 1209 virtual void TearDown() OVERRIDE { 1210 gfx::Screen* orig_screen = 1211 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 1212 AshTestBase::TearDown(); 1213 if (!SupportsMultipleDisplays()) 1214 return; 1215 gfx::Screen* screen = 1216 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 1217 EXPECT_NE(orig_screen, screen); 1218 EXPECT_EQ(2, screen->GetNumDisplays()); 1219 EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString()); 1220 std::vector<gfx::Display> all = screen->GetAllDisplays(); 1221 EXPECT_EQ("500x300", all[0].size().ToString()); 1222 EXPECT_EQ("800x400", all[1].size().ToString()); 1223 } 1224 1225 private: 1226 DISALLOW_COPY_AND_ASSIGN(ScreenShutdownTest); 1227}; 1228 1229TEST_F(ScreenShutdownTest, ScreenAfterShutdown) { 1230 if (!SupportsMultipleDisplays()) 1231 return; 1232 UpdateDisplay("500x300,800x400"); 1233} 1234 1235} // namespace internal 1236} // namespace ash 1237