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