15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/desktop_background/desktop_background_controller.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <cmath>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <cstdlib>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/ash_switches.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/desktop_background/desktop_background_widget_controller.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/root_window_controller.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/test/display_manager_test_api.h"
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/test/test_user_wallpaper_delegate.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/message_loop/message_loop.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/test/test_browser_thread.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/test_utils.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/skia/include/core/SkBitmap.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/skia/include/core/SkColor.h"
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/test/layer_animator_test_controller.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using aura::RootWindow;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using aura::Window;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace ash {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Containers IDs used for tests.
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kDesktopBackgroundId = ash::kShellWindowId_DesktopBackgroundContainer;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLockScreenBackgroundId =
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ash::kShellWindowId_LockScreenBackgroundContainer;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns number of child windows in a shell window container.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChildCountForContainer(int container_id) {
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Window* root = ash::Shell::GetPrimaryRootWindow();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* container = root->GetChildById(container_id);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<int>(container->children().size());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Steps a widget's layer animation until it is completed. Animations must be
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enabled.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunAnimationForWidget(views::Widget* widget) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animations must be enabled for stepping to work.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Layer* layer = widget->GetNativeView()->layer();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::LayerAnimatorTestController controller(layer->GetAnimator());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multiple steps are required to complete complex animations.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(vollick): This should not be necessary. crbug.com/154017
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (controller.animator()->is_animating()) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller.StartThreadedAnimationsIfNeeded();
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::TimeTicks step_time = controller.animator()->last_step_time();
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    layer->GetAnimator()->Step(step_time +
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1000));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DesktopBackgroundControllerTest : public test::AshTestBase {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DesktopBackgroundControllerTest()
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : controller_(NULL),
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        wallpaper_delegate_(NULL) {
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DesktopBackgroundControllerTest() {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test::AshTestBase::SetUp();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ash shell initialization creates wallpaper. Reset it so we can manually
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // control wallpaper creation and animation in our tests.
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    RootWindowController* root_window_controller =
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        Shell::GetPrimaryRootWindowController();
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    root_window_controller->SetWallpaperController(NULL);
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    root_window_controller->SetAnimatingWallpaperController(NULL);
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    controller_ = Shell::GetInstance()->desktop_background_controller();
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    wallpaper_delegate_ = static_cast<test::TestUserWallpaperDelegate*>(
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        Shell::GetInstance()->user_wallpaper_delegate());
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    controller_->set_wallpaper_reload_delay_for_test(0);
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected:
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A color that can be passed to CreateImage(). Specifically chosen to not
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // conflict with any of the default wallpaper colors.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const SkColor kCustomWallpaperColor = SK_ColorMAGENTA;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates an image of size |size|.
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::ImageSkia CreateImage(int width, int height, SkColor color) {
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkBitmap bitmap;
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bitmap.allocN32Pixels(width, height);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bitmap.eraseColor(color);
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return image;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Runs kAnimatingDesktopController's animation to completion.
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(bshe): Don't require tests to run animations; it's slow.
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void RunDesktopControllerAnimation() {
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    DesktopBackgroundWidgetController* controller =
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        Shell::GetPrimaryRootWindowController()
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            ->animating_wallpaper_controller()
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            ->GetController(false);
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_TRUE(!!controller);
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget()));
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DesktopBackgroundController* controller_;  // Not owned.
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  test::TestUserWallpaperDelegate* wallpaper_delegate_;
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, BasicReparenting) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopBackgroundController* controller =
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetInstance()->desktop_background_controller();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wallpaper view/window exists in the desktop background container and
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nothing is in the lock screen background container.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moving background to lock container should succeed the first time but
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // subsequent calls should do nothing.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller->MoveDesktopToLockedContainer());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller->MoveDesktopToLockedContainer());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One window is moved from desktop to lock container.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ChildCountForContainer(kLockScreenBackgroundId));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moving background to desktop container should succeed the first time.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller->MoveDesktopToUnlockedContainer());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller->MoveDesktopToUnlockedContainer());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One window is moved from lock to desktop container.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations for this test.
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create wallpaper and background view.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopBackgroundController* controller =
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetInstance()->desktop_background_controller();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The new wallpaper is ready to start animating. kAnimatingDesktopController
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // holds the widget controller instance. kDesktopController will get it later.
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RootWindowController* root_window_controller =
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Shell::GetPrimaryRootWindowController();
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              GetController(false));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kDesktopController will receive the widget controller when the animation
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is done.
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(root_window_controller->wallpaper_controller());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force the widget's layer animation to play to completion.
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunDesktopControllerAnimation();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ownership has moved from kAnimatingDesktopController to kDesktopController.
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               GetController(false));
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->wallpaper_controller());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// move all desktop views if there are more than one.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations for this test.
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset wallpaper state, see ControllerOwnership above.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopBackgroundController* controller =
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetInstance()->desktop_background_controller();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run wallpaper show animation to completion.
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunDesktopControllerAnimation();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // User locks the screen, which moves the background forward.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->MoveDesktopToLockedContainer();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suspend/resume cycle causes wallpaper to refresh, loading a new desktop
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // background that will animate in on top of the old one.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In this state we have two desktop background views stored in different
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // properties. Both are in the lock screen background container.
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RootWindowController* root_window_controller =
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Shell::GetPrimaryRootWindowController();
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              GetController(false));
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->wallpaper_controller());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before the wallpaper's animation completes, user unlocks the screen, which
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // moves the desktop to the back.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->MoveDesktopToUnlockedContainer();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure both desktop backgrounds have moved.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, ChildCountForContainer(kDesktopBackgroundId));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finish the new desktop background animation.
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunDesktopControllerAnimation();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now there is one desktop background, in the back.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/156542. Animating wallpaper should immediately finish
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// animation and replace current wallpaper before next animation starts.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations for this test.
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset wallpaper state, see ControllerOwnership above.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopBackgroundController* controller =
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetInstance()->desktop_background_controller();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run wallpaper show animation to completion.
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunDesktopControllerAnimation();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change to a new wallpaper.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RootWindowController* root_window_controller =
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Shell::GetPrimaryRootWindowController();
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DesktopBackgroundWidgetController* animating_controller =
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      root_window_controller->animating_wallpaper_controller()->GetController(
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          false);
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(animating_controller);
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->wallpaper_controller());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change to another wallpaper before animation finished.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller->CreateEmptyWallpaper();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The animating controller should immediately move to desktop controller.
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(animating_controller,
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            root_window_controller->wallpaper_controller());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache the new animating controller.
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  animating_controller = root_window_controller->
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      animating_wallpaper_controller()->GetController(false);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run wallpaper show animation to completion.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunAnimationForWidget(
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          root_window_controller->animating_wallpaper_controller()->
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              GetController(false)->widget()));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(root_window_controller->wallpaper_controller());
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               GetController(false));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The desktop controller should be the last created animating controller.
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(animating_controller,
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            root_window_controller->wallpaper_controller());
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, ResizeCustomWallpaper) {
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!SupportsMultipleDisplays())
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  test::DisplayManagerTestApi display_manager_test_api(
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Shell::GetInstance()->display_manager());
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  display_manager_test_api.UpdateDisplay("320x200");
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::ImageSkia image = CreateImage(640, 480, kCustomWallpaperColor);
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set the image as custom wallpaper, wait for the resize to finish, and check
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // that the resized image is the expected size.
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper()));
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RunAllBlockingPoolTasksUntilIdle();
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::ImageSkia resized_image = controller_->GetWallpaper();
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(image.BackedBySameObjectAs(resized_image));
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(gfx::Size(320, 200).ToString(), resized_image.size().ToString());
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Load the original wallpaper again and check that we're still using the
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // previously-resized image instead of doing another resize
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // (http://crbug.com/321402).
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RunAllBlockingPoolTasksUntilIdle();
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper()));
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) {
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Device scale factor shouldn't affect the native size.
30968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("1000x300*2");
31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "1000x300",
31268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
31368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Rotated display should return the rotated size.
31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("1000x300*2/r");
31668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
31768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "300x1000",
31868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
32068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // UI Scaling shouldn't affect the native size.
32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("1000x300*2@1.5");
32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "1000x300",
32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!SupportsMultipleDisplays())
32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // First display has maximum size.
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("400x300,100x100");
33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "400x300",
33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
33568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Second display has maximum size.
33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("400x300,500x600");
33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "500x600",
33968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
34168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Maximum width and height belongs to different displays.
34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateDisplay("400x300,100x500");
34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(
34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "400x500",
34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
350