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