Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ash / desktop_background / desktop_background_controller_unittest.cc
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_widget_controller.h"
12 #include "ash/root_window_controller.h"
13 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h"
15 #include "ash/test/ash_test_base.h"
16 #include "ash/test/display_manager_test_api.h"
17 #include "ash/test/test_user_wallpaper_delegate.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/threading/sequenced_worker_pool.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/test/test_browser_thread.h"
22 #include "content/public/test/test_utils.h"
23 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "third_party/skia/include/core/SkColor.h"
25 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
27 #include "ui/compositor/test/layer_animator_test_controller.h"
28
29 using aura::RootWindow;
30 using aura::Window;
31
32 namespace ash {
33 namespace {
34
35 // Containers IDs used for tests.
36 const int kDesktopBackgroundId = ash::kShellWindowId_DesktopBackgroundContainer;
37 const int kLockScreenBackgroundId =
38     ash::kShellWindowId_LockScreenBackgroundContainer;
39
40 // Returns number of child windows in a shell window container.
41 int ChildCountForContainer(int container_id) {
42   Window* root = ash::Shell::GetPrimaryRootWindow();
43   Window* container = root->GetChildById(container_id);
44   return static_cast<int>(container->children().size());
45 }
46
47 // Steps a widget's layer animation until it is completed. Animations must be
48 // enabled.
49 void RunAnimationForWidget(views::Widget* widget) {
50   // Animations must be enabled for stepping to work.
51   ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
52             ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
53
54   ui::Layer* layer = widget->GetNativeView()->layer();
55   ui::LayerAnimatorTestController controller(layer->GetAnimator());
56   // Multiple steps are required to complete complex animations.
57   // TODO(vollick): This should not be necessary. crbug.com/154017
58   while (controller.animator()->is_animating()) {
59     controller.StartThreadedAnimationsIfNeeded();
60     base::TimeTicks step_time = controller.animator()->last_step_time();
61     layer->GetAnimator()->Step(step_time +
62                                base::TimeDelta::FromMilliseconds(1000));
63   }
64 }
65
66 }  // namespace
67
68 class DesktopBackgroundControllerTest : public test::AshTestBase {
69  public:
70   DesktopBackgroundControllerTest()
71       : controller_(NULL),
72         wallpaper_delegate_(NULL) {
73   }
74   ~DesktopBackgroundControllerTest() override {}
75
76   void SetUp() override {
77     test::AshTestBase::SetUp();
78     // Ash shell initialization creates wallpaper. Reset it so we can manually
79     // control wallpaper creation and animation in our tests.
80     RootWindowController* root_window_controller =
81         Shell::GetPrimaryRootWindowController();
82     root_window_controller->SetWallpaperController(NULL);
83     root_window_controller->SetAnimatingWallpaperController(NULL);
84     controller_ = Shell::GetInstance()->desktop_background_controller();
85     wallpaper_delegate_ = static_cast<test::TestUserWallpaperDelegate*>(
86         Shell::GetInstance()->user_wallpaper_delegate());
87     controller_->set_wallpaper_reload_delay_for_test(0);
88   }
89
90  protected:
91   // A color that can be passed to CreateImage(). Specifically chosen to not
92   // conflict with any of the default wallpaper colors.
93   static const SkColor kCustomWallpaperColor = SK_ColorMAGENTA;
94
95   // Creates an image of size |size|.
96   gfx::ImageSkia CreateImage(int width, int height, SkColor color) {
97     SkBitmap bitmap;
98     bitmap.allocN32Pixels(width, height);
99     bitmap.eraseColor(color);
100     gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
101     return image;
102   }
103
104   // Runs kAnimatingDesktopController's animation to completion.
105   // TODO(bshe): Don't require tests to run animations; it's slow.
106   void RunDesktopControllerAnimation() {
107     DesktopBackgroundWidgetController* controller =
108         Shell::GetPrimaryRootWindowController()
109             ->animating_wallpaper_controller()
110             ->GetController(false);
111     EXPECT_TRUE(!!controller);
112     ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget()));
113   }
114
115   DesktopBackgroundController* controller_;  // Not owned.
116
117   test::TestUserWallpaperDelegate* wallpaper_delegate_;
118
119  private:
120   DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
121 };
122
123 TEST_F(DesktopBackgroundControllerTest, BasicReparenting) {
124   DesktopBackgroundController* controller =
125       Shell::GetInstance()->desktop_background_controller();
126   controller->CreateEmptyWallpaper();
127
128   // Wallpaper view/window exists in the desktop background container and
129   // nothing is in the lock screen background container.
130   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
131   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
132
133   // Moving background to lock container should succeed the first time but
134   // subsequent calls should do nothing.
135   EXPECT_TRUE(controller->MoveDesktopToLockedContainer());
136   EXPECT_FALSE(controller->MoveDesktopToLockedContainer());
137
138   // One window is moved from desktop to lock container.
139   EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
140   EXPECT_EQ(1, ChildCountForContainer(kLockScreenBackgroundId));
141
142   // Moving background to desktop container should succeed the first time.
143   EXPECT_TRUE(controller->MoveDesktopToUnlockedContainer());
144   EXPECT_FALSE(controller->MoveDesktopToUnlockedContainer());
145
146   // One window is moved from lock to desktop container.
147   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
148   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
149 }
150
151 TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
152   // We cannot short-circuit animations for this test.
153   ui::ScopedAnimationDurationScaleMode test_duration_mode(
154       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
155
156   // Create wallpaper and background view.
157   DesktopBackgroundController* controller =
158       Shell::GetInstance()->desktop_background_controller();
159   controller->CreateEmptyWallpaper();
160
161   // The new wallpaper is ready to start animating. kAnimatingDesktopController
162   // holds the widget controller instance. kDesktopController will get it later.
163   RootWindowController* root_window_controller =
164       Shell::GetPrimaryRootWindowController();
165   EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
166               GetController(false));
167
168   // kDesktopController will receive the widget controller when the animation
169   // is done.
170   EXPECT_FALSE(root_window_controller->wallpaper_controller());
171
172   // Force the widget's layer animation to play to completion.
173   RunDesktopControllerAnimation();
174
175   // Ownership has moved from kAnimatingDesktopController to kDesktopController.
176   EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
177                GetController(false));
178   EXPECT_TRUE(root_window_controller->wallpaper_controller());
179 }
180
181 // Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we
182 // move all desktop views if there are more than one.
183 TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
184   // We cannot short-circuit animations for this test.
185   ui::ScopedAnimationDurationScaleMode test_duration_mode(
186       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
187
188   // Reset wallpaper state, see ControllerOwnership above.
189   DesktopBackgroundController* controller =
190       Shell::GetInstance()->desktop_background_controller();
191   controller->CreateEmptyWallpaper();
192
193   // Run wallpaper show animation to completion.
194   RunDesktopControllerAnimation();
195
196   // User locks the screen, which moves the background forward.
197   controller->MoveDesktopToLockedContainer();
198
199   // Suspend/resume cycle causes wallpaper to refresh, loading a new desktop
200   // background that will animate in on top of the old one.
201   controller->CreateEmptyWallpaper();
202
203   // In this state we have two desktop background views stored in different
204   // properties. Both are in the lock screen background container.
205   RootWindowController* root_window_controller =
206       Shell::GetPrimaryRootWindowController();
207   EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
208               GetController(false));
209   EXPECT_TRUE(root_window_controller->wallpaper_controller());
210   EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
211   EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId));
212
213   // Before the wallpaper's animation completes, user unlocks the screen, which
214   // moves the desktop to the back.
215   controller->MoveDesktopToUnlockedContainer();
216
217   // Ensure both desktop backgrounds have moved.
218   EXPECT_EQ(2, ChildCountForContainer(kDesktopBackgroundId));
219   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
220
221   // Finish the new desktop background animation.
222   RunDesktopControllerAnimation();
223
224   // Now there is one desktop background, in the back.
225   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
226   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
227 }
228
229 // Test for crbug.com/156542. Animating wallpaper should immediately finish
230 // animation and replace current wallpaper before next animation starts.
231 TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
232   // We cannot short-circuit animations for this test.
233   ui::ScopedAnimationDurationScaleMode test_duration_mode(
234       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
235
236   // Reset wallpaper state, see ControllerOwnership above.
237   DesktopBackgroundController* controller =
238       Shell::GetInstance()->desktop_background_controller();
239   controller->CreateEmptyWallpaper();
240
241   // Run wallpaper show animation to completion.
242   RunDesktopControllerAnimation();
243
244   // Change to a new wallpaper.
245   controller->CreateEmptyWallpaper();
246
247   RootWindowController* root_window_controller =
248       Shell::GetPrimaryRootWindowController();
249   DesktopBackgroundWidgetController* animating_controller =
250       root_window_controller->animating_wallpaper_controller()->GetController(
251           false);
252   EXPECT_TRUE(animating_controller);
253   EXPECT_TRUE(root_window_controller->wallpaper_controller());
254
255   // Change to another wallpaper before animation finished.
256   controller->CreateEmptyWallpaper();
257
258   // The animating controller should immediately move to desktop controller.
259   EXPECT_EQ(animating_controller,
260             root_window_controller->wallpaper_controller());
261
262   // Cache the new animating controller.
263   animating_controller = root_window_controller->
264       animating_wallpaper_controller()->GetController(false);
265
266   // Run wallpaper show animation to completion.
267   ASSERT_NO_FATAL_FAILURE(
268       RunAnimationForWidget(
269           root_window_controller->animating_wallpaper_controller()->
270               GetController(false)->widget()));
271
272   EXPECT_TRUE(root_window_controller->wallpaper_controller());
273   EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
274                GetController(false));
275   // The desktop controller should be the last created animating controller.
276   EXPECT_EQ(animating_controller,
277             root_window_controller->wallpaper_controller());
278 }
279
280 TEST_F(DesktopBackgroundControllerTest, ResizeCustomWallpaper) {
281   if (!SupportsMultipleDisplays())
282     return;
283
284   test::DisplayManagerTestApi display_manager_test_api(
285       Shell::GetInstance()->display_manager());
286   display_manager_test_api.UpdateDisplay("320x200");
287
288   gfx::ImageSkia image = CreateImage(640, 480, kCustomWallpaperColor);
289
290   // Set the image as custom wallpaper, wait for the resize to finish, and check
291   // that the resized image is the expected size.
292   controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
293   EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper()));
294   content::RunAllBlockingPoolTasksUntilIdle();
295   gfx::ImageSkia resized_image = controller_->GetWallpaper();
296   EXPECT_FALSE(image.BackedBySameObjectAs(resized_image));
297   EXPECT_EQ(gfx::Size(320, 200).ToString(), resized_image.size().ToString());
298
299   // Load the original wallpaper again and check that we're still using the
300   // previously-resized image instead of doing another resize
301   // (http://crbug.com/321402).
302   controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
303   content::RunAllBlockingPoolTasksUntilIdle();
304   EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper()));
305 }
306
307 TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) {
308   // Device scale factor shouldn't affect the native size.
309   UpdateDisplay("1000x300*2");
310   EXPECT_EQ(
311       "1000x300",
312       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
313
314   // Rotated display should return the rotated size.
315   UpdateDisplay("1000x300*2/r");
316   EXPECT_EQ(
317       "300x1000",
318       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
319
320   // UI Scaling shouldn't affect the native size.
321   UpdateDisplay("1000x300*2@1.5");
322   EXPECT_EQ(
323       "1000x300",
324       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
325
326   if (!SupportsMultipleDisplays())
327     return;
328
329   // First display has maximum size.
330   UpdateDisplay("400x300,100x100");
331   EXPECT_EQ(
332       "400x300",
333       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
334
335   // Second display has maximum size.
336   UpdateDisplay("400x300,500x600");
337   EXPECT_EQ(
338       "500x600",
339       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
340
341   // Maximum width and height belongs to different displays.
342   UpdateDisplay("400x300,100x500");
343   EXPECT_EQ(
344       "400x500",
345       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
346 }
347
348
349 }  // namespace ash