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/desktop_background/desktop_background_controller.h" 6 7 #include <cmath> 8 #include <cstdlib> 9 10 #include "ash/ash_switches.h" 11 #include "ash/desktop_background/desktop_background_controller_observer.h" 12 #include "ash/desktop_background/desktop_background_widget_controller.h" 13 #include "ash/root_window_controller.h" 14 #include "ash/shell.h" 15 #include "ash/shell_window_ids.h" 16 #include "ash/test/ash_test_base.h" 17 #include "ash/test/display_manager_test_api.h" 18 #include "ash/test/test_user_wallpaper_delegate.h" 19 #include "base/command_line.h" 20 #include "base/file_util.h" 21 #include "base/files/file_path.h" 22 #include "base/files/scoped_temp_dir.h" 23 #include "base/message_loop/message_loop.h" 24 #include "base/threading/sequenced_worker_pool.h" 25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/test/test_browser_thread.h" 27 #include "content/public/test/test_utils.h" 28 #include "third_party/skia/include/core/SkBitmap.h" 29 #include "third_party/skia/include/core/SkColor.h" 30 #include "ui/aura/root_window.h" 31 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 32 #include "ui/compositor/test/layer_animator_test_controller.h" 33 #include "ui/gfx/codec/jpeg_codec.h" 34 #include "ui/gfx/point.h" 35 #include "ui/gfx/rect.h" 36 37 using aura::RootWindow; 38 using aura::Window; 39 40 namespace ash { 41 namespace { 42 43 // Containers IDs used for tests. 44 const int kDesktopBackgroundId = 45 ash::internal::kShellWindowId_DesktopBackgroundContainer; 46 const int kLockScreenBackgroundId = 47 ash::internal::kShellWindowId_LockScreenBackgroundContainer; 48 49 // Returns number of child windows in a shell window container. 50 int ChildCountForContainer(int container_id) { 51 Window* root = ash::Shell::GetPrimaryRootWindow(); 52 Window* container = root->GetChildById(container_id); 53 return static_cast<int>(container->children().size()); 54 } 55 56 class TestObserver : public DesktopBackgroundControllerObserver { 57 public: 58 explicit TestObserver(DesktopBackgroundController* controller) 59 : controller_(controller) { 60 DCHECK(controller_); 61 controller_->AddObserver(this); 62 } 63 64 virtual ~TestObserver() { 65 controller_->RemoveObserver(this); 66 } 67 68 void WaitForWallpaperDataChanged() { 69 base::MessageLoop::current()->Run(); 70 } 71 72 // DesktopBackgroundControllerObserver overrides: 73 virtual void OnWallpaperDataChanged() OVERRIDE { 74 base::MessageLoop::current()->Quit(); 75 } 76 77 private: 78 DesktopBackgroundController* controller_; 79 }; 80 81 // Steps a widget's layer animation until it is completed. Animations must be 82 // enabled. 83 void RunAnimationForWidget(views::Widget* widget) { 84 // Animations must be enabled for stepping to work. 85 ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(), 86 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); 87 88 ui::Layer* layer = widget->GetNativeView()->layer(); 89 ui::LayerAnimatorTestController controller(layer->GetAnimator()); 90 gfx::AnimationContainerElement* element = layer->GetAnimator(); 91 // Multiple steps are required to complete complex animations. 92 // TODO(vollick): This should not be necessary. crbug.com/154017 93 while (controller.animator()->is_animating()) { 94 controller.StartThreadedAnimationsIfNeeded(); 95 base::TimeTicks step_time = controller.animator()->last_step_time(); 96 element->Step(step_time + base::TimeDelta::FromMilliseconds(1000)); 97 } 98 } 99 100 } // namespace 101 102 class DesktopBackgroundControllerTest : public test::AshTestBase { 103 public: 104 DesktopBackgroundControllerTest() 105 : command_line_(CommandLine::NO_PROGRAM), 106 controller_(NULL) { 107 } 108 virtual ~DesktopBackgroundControllerTest() {} 109 110 virtual void SetUp() OVERRIDE { 111 test::AshTestBase::SetUp(); 112 // Ash shell initialization creates wallpaper. Reset it so we can manually 113 // control wallpaper creation and animation in our tests. 114 internal::RootWindowController* root_window_controller = 115 Shell::GetPrimaryRootWindowController(); 116 root_window_controller->SetWallpaperController(NULL); 117 root_window_controller->SetAnimatingWallpaperController(NULL); 118 controller_ = Shell::GetInstance()->desktop_background_controller(); 119 wallpaper_delegate_ = static_cast<test::TestUserWallpaperDelegate*>( 120 Shell::GetInstance()->user_wallpaper_delegate()); 121 controller_->set_wallpaper_reload_delay_for_test(0); 122 } 123 124 protected: 125 // Colors used for different default wallpapers by 126 // WriteWallpapersAndSetFlags(). 127 static const SkColor kLargeWallpaperColor = SK_ColorRED; 128 static const SkColor kSmallWallpaperColor = SK_ColorGREEN; 129 static const SkColor kLargeGuestWallpaperColor = SK_ColorBLUE; 130 static const SkColor kSmallGuestWallpaperColor = SK_ColorYELLOW; 131 132 // Dimension used for width and height of default wallpaper images. A 133 // small value is used to minimize the amount of time spent compressing 134 // and writing images. 135 static const int kWallpaperSize = 2; 136 137 // Creates an image of size |size|. 138 gfx::ImageSkia CreateImage(int width, int height) { 139 SkBitmap bitmap; 140 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); 141 bitmap.allocPixels(); 142 gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); 143 return image; 144 } 145 146 // Runs kAnimatingDesktopController's animation to completion. 147 // TODO(bshe): Don't require tests to run animations; it's slow. 148 void RunDesktopControllerAnimation() { 149 internal::DesktopBackgroundWidgetController* controller = 150 Shell::GetPrimaryRootWindowController()-> 151 animating_wallpaper_controller()->GetController(false); 152 ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget())); 153 } 154 155 // Returns true if the color at the center of |image| is close to 156 // |expected_color|. (The center is used so small wallpaper images can be 157 // used.) 158 bool ImageIsNearColor(gfx::ImageSkia image, SkColor expected_color) { 159 if (image.size().IsEmpty()) { 160 LOG(ERROR) << "Image is empty"; 161 return false; 162 } 163 164 const SkBitmap* bitmap = image.bitmap(); 165 if (!bitmap) { 166 LOG(ERROR) << "Unable to get bitmap from image"; 167 return false; 168 } 169 170 bitmap->lockPixels(); 171 gfx::Point center = gfx::Rect(image.size()).CenterPoint(); 172 SkColor image_color = bitmap->getColor(center.x(), center.y()); 173 bitmap->unlockPixels(); 174 175 const int kDiff = 3; 176 if (std::abs(static_cast<int>(SkColorGetA(image_color)) - 177 static_cast<int>(SkColorGetA(expected_color))) > kDiff || 178 std::abs(static_cast<int>(SkColorGetR(image_color)) - 179 static_cast<int>(SkColorGetR(expected_color))) > kDiff || 180 std::abs(static_cast<int>(SkColorGetG(image_color)) - 181 static_cast<int>(SkColorGetG(expected_color))) > kDiff || 182 std::abs(static_cast<int>(SkColorGetB(image_color)) - 183 static_cast<int>(SkColorGetB(expected_color))) > kDiff) { 184 LOG(ERROR) << "Expected color near 0x" << std::hex << expected_color 185 << " but got 0x" << image_color; 186 return false; 187 } 188 189 return true; 190 } 191 192 // Writes a JPEG image of the specified size and color to |path|. Returns 193 // true on success. 194 bool WriteJPEGFile(const base::FilePath& path, 195 int width, 196 int height, 197 SkColor color) { 198 SkBitmap bitmap; 199 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0); 200 bitmap.allocPixels(); 201 bitmap.eraseColor(color); 202 203 const int kQuality = 80; 204 std::vector<unsigned char> output; 205 if (!gfx::JPEGCodec::Encode( 206 static_cast<const unsigned char*>(bitmap.getPixels()), 207 gfx::JPEGCodec::FORMAT_SkBitmap, width, height, bitmap.rowBytes(), 208 kQuality, &output)) { 209 LOG(ERROR) << "Unable to encode " << width << "x" << height << " bitmap"; 210 return false; 211 } 212 213 size_t bytes_written = file_util::WriteFile( 214 path, reinterpret_cast<const char*>(&output[0]), output.size()); 215 if (bytes_written != output.size()) { 216 LOG(ERROR) << "Wrote " << bytes_written << " byte(s) instead of " 217 << output.size() << " to " << path.value(); 218 return false; 219 } 220 221 return true; 222 } 223 224 // Initializes |wallpaper_dir_|, writes JPEG wallpaper images to it, and 225 // passes |controller_| a command line instructing it to use the images. 226 // Only needs to be called (once) by tests that want to test loading of 227 // default wallpapers. 228 void WriteWallpapersAndSetFlags() { 229 wallpaper_dir_.reset(new base::ScopedTempDir); 230 ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir()); 231 232 const base::FilePath kLargePath = 233 wallpaper_dir_->path().Append(FILE_PATH_LITERAL("large.jpg")); 234 ASSERT_TRUE(WriteJPEGFile(kLargePath, kWallpaperSize, kWallpaperSize, 235 kLargeWallpaperColor)); 236 command_line_.AppendSwitchPath( 237 switches::kAshDefaultWallpaperLarge, kLargePath); 238 239 const base::FilePath kSmallPath = 240 wallpaper_dir_->path().Append(FILE_PATH_LITERAL("small.jpg")); 241 ASSERT_TRUE(WriteJPEGFile(kSmallPath, kWallpaperSize, kWallpaperSize, 242 kSmallWallpaperColor)); 243 command_line_.AppendSwitchPath( 244 switches::kAshDefaultWallpaperSmall, kSmallPath); 245 246 const base::FilePath kLargeGuestPath = 247 wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_large.jpg")); 248 ASSERT_TRUE(WriteJPEGFile(kLargeGuestPath, kWallpaperSize, kWallpaperSize, 249 kLargeGuestWallpaperColor)); 250 command_line_.AppendSwitchPath( 251 switches::kAshGuestWallpaperLarge, kLargeGuestPath); 252 253 const base::FilePath kSmallGuestPath = 254 wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_small.jpg")); 255 ASSERT_TRUE(WriteJPEGFile(kSmallGuestPath, kWallpaperSize, kWallpaperSize, 256 kSmallGuestWallpaperColor)); 257 command_line_.AppendSwitchPath( 258 switches::kAshGuestWallpaperSmall, kSmallGuestPath); 259 260 controller_->set_command_line_for_testing(&command_line_); 261 } 262 263 // Custom command line passed to DesktopBackgroundController by 264 // WriteWallpapersAndSetFlags(). 265 CommandLine command_line_; 266 267 // Directory created by WriteWallpapersAndSetFlags() to store default 268 // wallpaper images. 269 scoped_ptr<base::ScopedTempDir> wallpaper_dir_; 270 271 DesktopBackgroundController* controller_; // Not owned. 272 273 test::TestUserWallpaperDelegate* wallpaper_delegate_; 274 275 private: 276 DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest); 277 }; 278 279 TEST_F(DesktopBackgroundControllerTest, BasicReparenting) { 280 DesktopBackgroundController* controller = 281 Shell::GetInstance()->desktop_background_controller(); 282 controller->CreateEmptyWallpaper(); 283 284 // Wallpaper view/window exists in the desktop background container and 285 // nothing is in the lock screen background container. 286 EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId)); 287 EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId)); 288 289 // Moving background to lock container should succeed the first time but 290 // subsequent calls should do nothing. 291 EXPECT_TRUE(controller->MoveDesktopToLockedContainer()); 292 EXPECT_FALSE(controller->MoveDesktopToLockedContainer()); 293 294 // One window is moved from desktop to lock container. 295 EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId)); 296 EXPECT_EQ(1, ChildCountForContainer(kLockScreenBackgroundId)); 297 298 // Moving background to desktop container should succeed the first time. 299 EXPECT_TRUE(controller->MoveDesktopToUnlockedContainer()); 300 EXPECT_FALSE(controller->MoveDesktopToUnlockedContainer()); 301 302 // One window is moved from lock to desktop container. 303 EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId)); 304 EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId)); 305 } 306 307 TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) { 308 // We cannot short-circuit animations for this test. 309 ui::ScopedAnimationDurationScaleMode normal_duration_mode( 310 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); 311 312 // Create wallpaper and background view. 313 DesktopBackgroundController* controller = 314 Shell::GetInstance()->desktop_background_controller(); 315 controller->CreateEmptyWallpaper(); 316 317 // The new wallpaper is ready to start animating. kAnimatingDesktopController 318 // holds the widget controller instance. kDesktopController will get it later. 319 internal::RootWindowController* root_window_controller = 320 Shell::GetPrimaryRootWindowController(); 321 EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> 322 GetController(false)); 323 324 // kDesktopController will receive the widget controller when the animation 325 // is done. 326 EXPECT_FALSE(root_window_controller->wallpaper_controller()); 327 328 // Force the widget's layer animation to play to completion. 329 RunDesktopControllerAnimation(); 330 331 // Ownership has moved from kAnimatingDesktopController to kDesktopController. 332 EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()-> 333 GetController(false)); 334 EXPECT_TRUE(root_window_controller->wallpaper_controller()); 335 } 336 337 // Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we 338 // move all desktop views if there are more than one. 339 TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) { 340 // We cannot short-circuit animations for this test. 341 ui::ScopedAnimationDurationScaleMode normal_duration_mode( 342 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); 343 344 // Reset wallpaper state, see ControllerOwnership above. 345 DesktopBackgroundController* controller = 346 Shell::GetInstance()->desktop_background_controller(); 347 controller->CreateEmptyWallpaper(); 348 349 // Run wallpaper show animation to completion. 350 RunDesktopControllerAnimation(); 351 352 // User locks the screen, which moves the background forward. 353 controller->MoveDesktopToLockedContainer(); 354 355 // Suspend/resume cycle causes wallpaper to refresh, loading a new desktop 356 // background that will animate in on top of the old one. 357 controller->CreateEmptyWallpaper(); 358 359 // In this state we have two desktop background views stored in different 360 // properties. Both are in the lock screen background container. 361 internal::RootWindowController* root_window_controller = 362 Shell::GetPrimaryRootWindowController(); 363 EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> 364 GetController(false)); 365 EXPECT_TRUE(root_window_controller->wallpaper_controller()); 366 EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId)); 367 EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId)); 368 369 // Before the wallpaper's animation completes, user unlocks the screen, which 370 // moves the desktop to the back. 371 controller->MoveDesktopToUnlockedContainer(); 372 373 // Ensure both desktop backgrounds have moved. 374 EXPECT_EQ(2, ChildCountForContainer(kDesktopBackgroundId)); 375 EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId)); 376 377 // Finish the new desktop background animation. 378 RunDesktopControllerAnimation(); 379 380 // Now there is one desktop background, in the back. 381 EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId)); 382 EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId)); 383 } 384 385 // Test for crbug.com/156542. Animating wallpaper should immediately finish 386 // animation and replace current wallpaper before next animation starts. 387 TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) { 388 // We cannot short-circuit animations for this test. 389 ui::ScopedAnimationDurationScaleMode normal_duration_mode( 390 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); 391 392 // Reset wallpaper state, see ControllerOwnership above. 393 DesktopBackgroundController* controller = 394 Shell::GetInstance()->desktop_background_controller(); 395 controller->CreateEmptyWallpaper(); 396 397 // Run wallpaper show animation to completion. 398 RunDesktopControllerAnimation(); 399 400 // Change to a new wallpaper. 401 controller->CreateEmptyWallpaper(); 402 403 internal::RootWindowController* root_window_controller = 404 Shell::GetPrimaryRootWindowController(); 405 internal::DesktopBackgroundWidgetController* animating_controller = 406 root_window_controller->animating_wallpaper_controller()-> 407 GetController(false); 408 EXPECT_TRUE(animating_controller); 409 EXPECT_TRUE(root_window_controller->wallpaper_controller()); 410 411 // Change to another wallpaper before animation finished. 412 controller->CreateEmptyWallpaper(); 413 414 // The animating controller should immediately move to desktop controller. 415 EXPECT_EQ(animating_controller, 416 root_window_controller->wallpaper_controller()); 417 418 // Cache the new animating controller. 419 animating_controller = root_window_controller-> 420 animating_wallpaper_controller()->GetController(false); 421 422 // Run wallpaper show animation to completion. 423 ASSERT_NO_FATAL_FAILURE( 424 RunAnimationForWidget( 425 root_window_controller->animating_wallpaper_controller()-> 426 GetController(false)->widget())); 427 428 EXPECT_TRUE(root_window_controller->wallpaper_controller()); 429 EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()-> 430 GetController(false)); 431 // The desktop controller should be the last created animating controller. 432 EXPECT_EQ(animating_controller, 433 root_window_controller->wallpaper_controller()); 434 } 435 436 TEST_F(DesktopBackgroundControllerTest, DisplayChange) { 437 // TODO(derat|oshima|bshe): Host windows can't be resized on Win8. 438 if (!SupportsHostWindowResize()) 439 return; 440 441 // Set the wallpaper to ensure that UpdateWallpaper() will be called when the 442 // display configuration changes. 443 gfx::ImageSkia image = CreateImage(640, 480); 444 wallpaper_delegate_->set_custom_wallpaper(image); 445 controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH); 446 447 // Small wallpaper images should be used for configurations less than or 448 // equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if 449 // multiple displays are connected. 450 test::DisplayManagerTestApi display_manager_test_api( 451 Shell::GetInstance()->display_manager()); 452 display_manager_test_api.UpdateDisplay("800x600"); 453 RunAllPendingInMessageLoop(); 454 EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, 455 controller_->GetAppropriateResolution()); 456 EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 457 458 display_manager_test_api.UpdateDisplay("800x600,800x600"); 459 RunAllPendingInMessageLoop(); 460 EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, 461 controller_->GetAppropriateResolution()); 462 EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 463 464 display_manager_test_api.UpdateDisplay("1366x800"); 465 RunAllPendingInMessageLoop(); 466 EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, 467 controller_->GetAppropriateResolution()); 468 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 469 470 // At larger sizes, large wallpapers should be used. 471 display_manager_test_api.UpdateDisplay("1367x800"); 472 RunAllPendingInMessageLoop(); 473 EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, 474 controller_->GetAppropriateResolution()); 475 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 476 477 display_manager_test_api.UpdateDisplay("1367x801"); 478 RunAllPendingInMessageLoop(); 479 EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, 480 controller_->GetAppropriateResolution()); 481 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 482 483 display_manager_test_api.UpdateDisplay("2560x1700"); 484 RunAllPendingInMessageLoop(); 485 EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, 486 controller_->GetAppropriateResolution()); 487 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 488 489 // Rotated smaller screen may use larger image. 490 display_manager_test_api.UpdateDisplay("800x600/r"); 491 RunAllPendingInMessageLoop(); 492 EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, 493 controller_->GetAppropriateResolution()); 494 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 495 496 display_manager_test_api.UpdateDisplay("800x600/r,800x600"); 497 RunAllPendingInMessageLoop(); 498 EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, 499 controller_->GetAppropriateResolution()); 500 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 501 display_manager_test_api.UpdateDisplay("1366x800/r"); 502 RunAllPendingInMessageLoop(); 503 EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, 504 controller_->GetAppropriateResolution()); 505 EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 506 507 // Max display size didn't chagne. 508 display_manager_test_api.UpdateDisplay("900x800/r,400x1366"); 509 RunAllPendingInMessageLoop(); 510 EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset()); 511 } 512 513 // Test that DesktopBackgroundController loads the appropriate wallpaper 514 // images as specified via command-line flags in various situations. 515 // Splitting these into separate tests avoids needing to run animations. 516 // TODO(derat): Combine these into a single test -- see 517 // RunDesktopControllerAnimation()'s TODO. 518 TEST_F(DesktopBackgroundControllerTest, SmallDefaultWallpaper) { 519 if (!SupportsMultipleDisplays()) 520 return; 521 522 WriteWallpapersAndSetFlags(); 523 TestObserver observer(controller_); 524 525 // At 800x600, the small wallpaper should be loaded. 526 test::DisplayManagerTestApi display_manager_test_api( 527 Shell::GetInstance()->display_manager()); 528 display_manager_test_api.UpdateDisplay("800x600"); 529 ASSERT_TRUE(controller_->SetDefaultWallpaper(false)); 530 observer.WaitForWallpaperDataChanged(); 531 EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), 532 kSmallWallpaperColor)); 533 534 // Requesting the same wallpaper again should be a no-op. 535 ASSERT_FALSE(controller_->SetDefaultWallpaper(false)); 536 } 537 538 TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaper) { 539 if (!SupportsMultipleDisplays()) 540 return; 541 542 WriteWallpapersAndSetFlags(); 543 TestObserver observer(controller_); 544 test::DisplayManagerTestApi display_manager_test_api( 545 Shell::GetInstance()->display_manager()); 546 display_manager_test_api.UpdateDisplay("1600x1200"); 547 ASSERT_TRUE(controller_->SetDefaultWallpaper(false)); 548 observer.WaitForWallpaperDataChanged(); 549 EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), 550 kLargeWallpaperColor)); 551 } 552 553 TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaperWhenRotated) { 554 if (!SupportsMultipleDisplays()) 555 return; 556 WriteWallpapersAndSetFlags(); 557 TestObserver observer(controller_); 558 test::DisplayManagerTestApi display_manager_test_api( 559 Shell::GetInstance()->display_manager()); 560 561 display_manager_test_api.UpdateDisplay("1200x800/r"); 562 ASSERT_TRUE(controller_->SetDefaultWallpaper(false)); 563 observer.WaitForWallpaperDataChanged(); 564 EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), 565 kLargeWallpaperColor)); 566 } 567 568 TEST_F(DesktopBackgroundControllerTest, SmallGuestWallpaper) { 569 if (!SupportsMultipleDisplays()) 570 return; 571 572 WriteWallpapersAndSetFlags(); 573 TestObserver observer(controller_); 574 test::DisplayManagerTestApi display_manager_test_api( 575 Shell::GetInstance()->display_manager()); 576 display_manager_test_api.UpdateDisplay("800x600"); 577 ASSERT_TRUE(controller_->SetDefaultWallpaper(true)); 578 observer.WaitForWallpaperDataChanged(); 579 EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), 580 kSmallGuestWallpaperColor)); 581 } 582 583 TEST_F(DesktopBackgroundControllerTest, LargeGuestWallpaper) { 584 if (!SupportsMultipleDisplays()) 585 return; 586 587 WriteWallpapersAndSetFlags(); 588 TestObserver observer(controller_); 589 test::DisplayManagerTestApi display_manager_test_api( 590 Shell::GetInstance()->display_manager()); 591 display_manager_test_api.UpdateDisplay("1600x1200"); 592 ASSERT_TRUE(controller_->SetDefaultWallpaper(true)); 593 observer.WaitForWallpaperDataChanged(); 594 EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), 595 kLargeGuestWallpaperColor)); 596 } 597 598 TEST_F(DesktopBackgroundControllerTest, ResizeCustomWallpaper) { 599 if (!SupportsMultipleDisplays()) 600 return; 601 602 test::DisplayManagerTestApi display_manager_test_api( 603 Shell::GetInstance()->display_manager()); 604 display_manager_test_api.UpdateDisplay("320x200"); 605 606 gfx::ImageSkia image = CreateImage(640, 480); 607 608 // Set the image as custom wallpaper, wait for the resize to finish, and check 609 // that the resized image is the expected size. 610 controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH); 611 EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper())); 612 content::BrowserThread::GetBlockingPool()->FlushForTesting(); 613 content::RunAllPendingInMessageLoop(); 614 gfx::ImageSkia resized_image = controller_->GetWallpaper(); 615 EXPECT_FALSE(image.BackedBySameObjectAs(resized_image)); 616 EXPECT_EQ(gfx::Size(320, 200).ToString(), resized_image.size().ToString()); 617 618 // Load the original wallpaper again and check that we're still using the 619 // previously-resized image instead of doing another resize 620 // (http://crbug.com/321402). 621 controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH); 622 content::BrowserThread::GetBlockingPool()->FlushForTesting(); 623 content::RunAllPendingInMessageLoop(); 624 EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper())); 625 } 626 627 TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) { 628 // Device scale factor shouldn't affect the native size. 629 UpdateDisplay("1000x300*2"); 630 EXPECT_EQ( 631 "1000x300", 632 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 633 634 // Rotated display should return the rotated size. 635 UpdateDisplay("1000x300*2/r"); 636 EXPECT_EQ( 637 "300x1000", 638 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 639 640 // UI Scaling shouldn't affect the native size. 641 UpdateDisplay("1000x300*2 (at) 1.5"); 642 EXPECT_EQ( 643 "1000x300", 644 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 645 646 if (!SupportsMultipleDisplays()) 647 return; 648 649 // First display has maximum size. 650 UpdateDisplay("400x300,100x100"); 651 EXPECT_EQ( 652 "400x300", 653 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 654 655 // Second display has maximum size. 656 UpdateDisplay("400x300,500x600"); 657 EXPECT_EQ( 658 "500x600", 659 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 660 661 // Maximum width and height belongs to different displays. 662 UpdateDisplay("400x300,100x500"); 663 EXPECT_EQ( 664 "400x500", 665 DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); 666 } 667 668 } // namespace ash 669