summaryrefslogtreecommitdiffstats
path: root/ash/desktop_background
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-05 19:32:58 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-05 19:32:58 +0000
commitd86de6b25c7b9020d0795ff13de2fc29aead20af (patch)
treeeb3fc1b5f44dbbcc431046698fa23b8c4fe33b9a /ash/desktop_background
parent7502551150ee02157a30ee10fa8992f858accc00 (diff)
downloadchromium_src-d86de6b25c7b9020d0795ff13de2fc29aead20af.zip
chromium_src-d86de6b25c7b9020d0795ff13de2fc29aead20af.tar.gz
chromium_src-d86de6b25c7b9020d0795ff13de2fc29aead20af.tar.bz2
ash: Add tests for desktop background, fix names
* Add basic unit tests for DesktopBackgroundController * Add test for race condition between Chrome OS resume from sleep/wallpaper refresh and screen unlock. See bug. * Rename ComponentWrapper class to AnimatingDesktopController * Rename kComponentWrapper key to kAnimatingDesktopController * Rename kWindowDesktopComponent key to kDesktopController * Fix lots of component vs. controller names BUG=149043 TEST=added DesktopBackgroundControllerTest.* Review URL: https://chromiumcodereview.appspot.com/11026047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160449 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/desktop_background')
-rw-r--r--ash/desktop_background/desktop_background_controller.cc65
-rw-r--r--ash/desktop_background/desktop_background_controller.h4
-rw-r--r--ash/desktop_background/desktop_background_controller_unittest.cc182
-rw-r--r--ash/desktop_background/desktop_background_view.cc16
-rw-r--r--ash/desktop_background/desktop_background_widget_controller.cc25
-rw-r--r--ash/desktop_background/desktop_background_widget_controller.h36
6 files changed, 263 insertions, 65 deletions
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc
index ae22b55..ca697d6 100644
--- a/ash/desktop_background/desktop_background_controller.cc
+++ b/ash/desktop_background/desktop_background_controller.cc
@@ -24,8 +24,8 @@
#include "ui/views/widget/widget.h"
using ash::internal::DesktopBackgroundWidgetController;
-using ash::internal::kComponentWrapper;
-using ash::internal::kWindowDesktopComponent;
+using ash::internal::kAnimatingDesktopController;
+using ash::internal::kDesktopController;
namespace ash {
namespace {
@@ -154,7 +154,7 @@ void DesktopBackgroundController::OnRootWindowAdded(
}
}
- InstallComponent(root_window);
+ InstallDesktopController(root_window);
}
void DesktopBackgroundController::CacheDefaultWallpaper(int index) {
@@ -221,7 +221,7 @@ void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode(
background_color_ = color;
desktop_background_mode_ = BACKGROUND_SOLID_COLOR;
- InstallComponentForAllWindows();
+ InstallDesktopControllerForAllWindows();
}
void DesktopBackgroundController::CreateEmptyWallpaper() {
@@ -259,15 +259,15 @@ bool DesktopBackgroundController::MoveDesktopToUnlockedContainer() {
}
void DesktopBackgroundController::OnWindowDestroying(aura::Window* window) {
- window->SetProperty(internal::kWindowDesktopComponent,
+ window->SetProperty(kDesktopController,
static_cast<internal::DesktopBackgroundWidgetController*>(NULL));
- window->SetProperty(internal::kComponentWrapper,
- static_cast<internal::ComponentWrapper*>(NULL));
+ window->SetProperty(kAnimatingDesktopController,
+ static_cast<internal::AnimatingDesktopController*>(NULL));
}
void DesktopBackgroundController::SetDesktopBackgroundImageMode() {
desktop_background_mode_ = BACKGROUND_IMAGE;
- InstallComponentForAllWindows();
+ InstallDesktopControllerForAllWindows();
}
void DesktopBackgroundController::OnWallpaperLoadCompleted(
@@ -303,7 +303,7 @@ ui::Layer* DesktopBackgroundController::SetColorLayerForContainer(
return background_layer;
}
-void DesktopBackgroundController::InstallComponent(
+void DesktopBackgroundController::InstallDesktopController(
aura::RootWindow* root_window) {
internal::DesktopBackgroundWidgetController* component = NULL;
int container_id = GetBackgroundContainerId(locked_);
@@ -326,19 +326,20 @@ void DesktopBackgroundController::InstallComponent(
NOTREACHED();
}
}
- if (NULL == root_window->GetProperty(internal::kComponentWrapper)) {
- // First time for this root window
+ // Ensure we're only observing the root window once. Don't rely on a window
+ // property check as those can be cleared by tests resetting the background.
+ if (!root_window->HasObserver(this))
root_window->AddObserver(this);
- }
- root_window->SetProperty(internal::kComponentWrapper,
- new internal::ComponentWrapper(component));
+
+ root_window->SetProperty(kAnimatingDesktopController,
+ new internal::AnimatingDesktopController(component));
}
-void DesktopBackgroundController::InstallComponentForAllWindows() {
+void DesktopBackgroundController::InstallDesktopControllerForAllWindows() {
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (Shell::RootWindowList::iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
- InstallComponent(*iter);
+ InstallDesktopController(*iter);
}
}
@@ -350,26 +351,28 @@ bool DesktopBackgroundController::ReparentBackgroundWidgets(int src_container,
iter != root_windows.end(); ++iter) {
aura::RootWindow* root_window = *iter;
// In the steady state (no animation playing) the background widget
- // controller exists in the kWindowDesktopComponent property.
- DesktopBackgroundWidgetController* desktop_component = root_window->
- GetProperty(kWindowDesktopComponent);
- if (desktop_component) {
- moved |= desktop_component->Reparent(root_window,
- src_container,
- dst_container);
+ // controller exists in the kDesktopController property.
+ DesktopBackgroundWidgetController* desktop_controller = root_window->
+ GetProperty(kDesktopController);
+ if (desktop_controller) {
+ moved |= desktop_controller->Reparent(root_window,
+ src_container,
+ dst_container);
}
- // During desktop show animations the controller lives in kComponentWrapper.
+ // During desktop show animations the controller lives in
+ // kAnimatingDesktopController.
// NOTE: If a wallpaper load happens during a desktop show animation there
// can temporarily be two desktop background widgets. We must reparent
// both of them - one above and one here.
- DesktopBackgroundWidgetController* wrapped_component =
- root_window->GetProperty(kComponentWrapper) ?
- root_window->GetProperty(kComponentWrapper)->GetComponent(false) :
+ DesktopBackgroundWidgetController* animating_controller =
+ root_window->GetProperty(kAnimatingDesktopController) ?
+ root_window->GetProperty(kAnimatingDesktopController)->
+ GetController(false) :
NULL;
- if (wrapped_component) {
- moved |= wrapped_component->Reparent(root_window,
- src_container,
- dst_container);
+ if (animating_controller) {
+ moved |= animating_controller->Reparent(root_window,
+ src_container,
+ dst_container);
}
}
return moved;
diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h
index 8976a31..47a69f4 100644
--- a/ash/desktop_background/desktop_background_controller.h
+++ b/ash/desktop_background/desktop_background_controller.h
@@ -151,11 +151,11 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver {
// Creates and adds component for current mode (either Widget or Layer) to
// |root_window|.
- void InstallComponent(aura::RootWindow* root_window);
+ void InstallDesktopController(aura::RootWindow* root_window);
// Creates and adds component for current mode (either Widget or Layer) to
// all root windows.
- void InstallComponentForAllWindows();
+ void InstallDesktopControllerForAllWindows();
// Moves all desktop components from one container to other across all root
// windows. Returns true if a desktop moved.
diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc
new file mode 100644
index 0000000..3b04bc4
--- /dev/null
+++ b/ash/desktop_background/desktop_background_controller_unittest.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/desktop_background/desktop_background_controller.h"
+
+#include "ash/desktop_background/desktop_background_widget_controller.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/test/ash_test_base.h"
+#include "ui/aura/root_window.h"
+
+using aura::RootWindow;
+using aura::Window;
+
+namespace {
+
+// Containers IDs used for tests.
+const int kDesktopBackgroundId =
+ ash::internal::kShellWindowId_DesktopBackgroundContainer;
+const int kLockScreenBackgroundId =
+ ash::internal::kShellWindowId_LockScreenBackgroundContainer;
+
+// Returns number of child windows in a shell window container.
+int ChildCountForContainer(int container_id) {
+ RootWindow* root = ash::Shell::GetPrimaryRootWindow();
+ Window* container = root->GetChildById(container_id);
+ return static_cast<int>(container->children().size());
+}
+
+// Steps a widget's layer animation until it is completed. Animations must be
+// enabled.
+void RunAnimationForWidget(views::Widget* widget) {
+ // Animations must be enabled for stepping to work.
+ DCHECK(!ui::LayerAnimator::disable_animations_for_test());
+
+ ui::Layer* layer = widget->GetNativeView()->layer();
+ ui::LayerAnimator* animator = layer->GetAnimator();
+ ui::AnimationContainerElement* element = layer->GetAnimator();
+ // Multiple steps are required to complete complex animations.
+ // TODO(vollick): This should not be necessary. crbug.com/154017
+ while (animator->is_animating()) {
+ base::TimeTicks step_time = animator->last_step_time();
+ element->Step(step_time + base::TimeDelta::FromMilliseconds(1000));
+ }
+}
+
+} // namespace
+
+namespace ash {
+namespace internal {
+
+class DesktopBackgroundControllerTest : public test::AshTestBase {
+ public:
+ DesktopBackgroundControllerTest() {}
+ virtual ~DesktopBackgroundControllerTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ test::AshTestBase::SetUp();
+ // Ash shell initialization creates wallpaper. Reset it so we can manually
+ // control wallpaper creation and animation in our tests.
+ RootWindow* root = Shell::GetPrimaryRootWindow();
+ root->SetProperty(kDesktopController,
+ static_cast<DesktopBackgroundWidgetController*>(NULL));
+ root->SetProperty(kAnimatingDesktopController,
+ static_cast<AnimatingDesktopController*>(NULL));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
+};
+
+TEST_F(DesktopBackgroundControllerTest, BasicReparenting) {
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->CreateEmptyWallpaper();
+
+ // Wallpaper view/window exists in the desktop background container and
+ // nothing is in the lock screen background container.
+ EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
+
+ // Moving background to lock container should succeed the first time but
+ // subsequent calls should do nothing.
+ EXPECT_TRUE(controller->MoveDesktopToLockedContainer());
+ EXPECT_FALSE(controller->MoveDesktopToLockedContainer());
+
+ // One window is moved from desktop to lock container.
+ EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(1, ChildCountForContainer(kLockScreenBackgroundId));
+
+ // Moving background to desktop container should succeed the first time.
+ EXPECT_TRUE(controller->MoveDesktopToUnlockedContainer());
+ EXPECT_FALSE(controller->MoveDesktopToUnlockedContainer());
+
+ // One window is moved from lock to desktop container.
+ EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
+}
+
+TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
+ // We cannot short-circuit animations for this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
+ // Create wallpaper and background view.
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->CreateEmptyWallpaper();
+
+ // The new wallpaper is ready to start animating. kAnimatingDesktopController
+ // holds the widget controller instance. kDesktopController will get it later.
+ RootWindow* root = Shell::GetPrimaryRootWindow();
+ EXPECT_TRUE(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false));
+
+ // kDesktopController will receive the widget controller when the animation
+ // is done.
+ EXPECT_FALSE(root->GetProperty(kDesktopController));
+
+ // Force the widget's layer animation to play to completion.
+ RunAnimationForWidget(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false)->
+ widget());
+
+ // Ownership has moved from kAnimatingDesktopController to kDesktopController.
+ EXPECT_FALSE(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false));
+ EXPECT_TRUE(root->GetProperty(kDesktopController));
+}
+
+// Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we
+// move all desktop views if there are more than one.
+TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
+ // We cannot short-circuit animations for this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
+ // Reset wallpaper state, see ControllerOwnership above.
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->CreateEmptyWallpaper();
+
+ // Run wallpaper show animation to completion.
+ RootWindow* root = Shell::GetPrimaryRootWindow();
+ RunAnimationForWidget(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false)->
+ widget());
+
+ // User locks the screen, which moves the background forward.
+ controller->MoveDesktopToLockedContainer();
+
+ // Suspend/resume cycle causes wallpaper to refresh, loading a new desktop
+ // background that will animate in on top of the old one.
+ controller->CreateEmptyWallpaper();
+
+ // In this state we have two desktop background views stored in different
+ // properties. Both are in the lock screen background container.
+ EXPECT_TRUE(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false));
+ EXPECT_TRUE(root->GetProperty(kDesktopController));
+ EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId));
+
+ // Before the wallpaper's animation completes, user unlocks the screen, which
+ // moves the desktop to the back.
+ controller->MoveDesktopToUnlockedContainer();
+
+ // Ensure both desktop backgrounds have moved.
+ EXPECT_EQ(2, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
+
+ // Finish the new desktop background animation.
+ RunAnimationForWidget(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false)->
+ widget());
+
+ // Now there is one desktop background, in the back.
+ EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
+ EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc
index 38324b8..9ebb8ea 100644
--- a/ash/desktop_background/desktop_background_view.cc
+++ b/ash/desktop_background/desktop_background_view.cc
@@ -52,12 +52,14 @@ class ShowWallpaperAnimationObserver : public ui::ImplicitAnimationObserver,
shell->GetPrimaryRootWindowController()->HandleDesktopBackgroundVisible();
shell->user_wallpaper_delegate()->OnWallpaperAnimationFinished();
// Only removes old component when wallpaper animation finished. If we
- // remove the old one too early, there will be a white flash during
- // animation.
- if (root_window_->GetProperty(kComponentWrapper)) {
- internal::DesktopBackgroundWidgetController* component =
- root_window_->GetProperty(kComponentWrapper)->GetComponent(true);
- root_window_->SetProperty(kWindowDesktopComponent, component);
+ // remove the old one before the new wallpaper is done fading in there will
+ // be a white flash during the animation.
+ if (root_window_->GetProperty(kAnimatingDesktopController)) {
+ DesktopBackgroundWidgetController* controller =
+ root_window_->GetProperty(kAnimatingDesktopController)->
+ GetController(true);
+ // Release the old controller and close its background widget.
+ root_window_->SetProperty(kDesktopController, controller);
}
delete this;
}
@@ -173,7 +175,7 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window,
// will animate from a white screen. Note that boot animation is different.
// It animates from a white background.
if (animation_type == ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE &&
- NULL == root_window->GetProperty(internal::kComponentWrapper)) {
+ NULL == root_window->GetProperty(kAnimatingDesktopController)) {
ash::SetWindowVisibilityAnimationTransition(desktop_widget->GetNativeView(),
ash::ANIMATE_NONE);
} else {
diff --git a/ash/desktop_background/desktop_background_widget_controller.cc b/ash/desktop_background/desktop_background_widget_controller.cc
index 6b796d0..dd247ee 100644
--- a/ash/desktop_background/desktop_background_widget_controller.cc
+++ b/ash/desktop_background/desktop_background_widget_controller.cc
@@ -4,18 +4,23 @@
#include "ash/desktop_background/desktop_background_widget_controller.h"
+#include "ash/ash_export.h"
#include "ui/aura/root_window.h"
#include "ui/views/widget/widget.h"
-DECLARE_WINDOW_PROPERTY_TYPE(ash::internal::DesktopBackgroundWidgetController*);
-DECLARE_WINDOW_PROPERTY_TYPE(ash::internal::ComponentWrapper*);
+// Exported for tests.
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(
+ ASH_EXPORT, ash::internal::DesktopBackgroundWidgetController*);
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(
+ ASH_EXPORT, ash::internal::AnimatingDesktopController*);
namespace ash {
namespace internal {
DEFINE_OWNED_WINDOW_PROPERTY_KEY(DesktopBackgroundWidgetController,
- kWindowDesktopComponent, NULL);
-DEFINE_OWNED_WINDOW_PROPERTY_KEY(ComponentWrapper, kComponentWrapper, NULL);
+ kDesktopController, NULL);
+DEFINE_OWNED_WINDOW_PROPERTY_KEY(AnimatingDesktopController,
+ kAnimatingDesktopController, NULL);
DesktopBackgroundWidgetController::DesktopBackgroundWidgetController(
views::Widget* widget) : widget_(widget) {
@@ -67,19 +72,19 @@ bool DesktopBackgroundWidgetController::Reparent(aura::RootWindow* root_window,
return false;
}
-ComponentWrapper::ComponentWrapper(
+AnimatingDesktopController::AnimatingDesktopController(
DesktopBackgroundWidgetController* component) {
- component_.reset(component);
+ controller_.reset(component);
}
-ComponentWrapper::~ComponentWrapper() {
+AnimatingDesktopController::~AnimatingDesktopController() {
}
-DesktopBackgroundWidgetController* ComponentWrapper::GetComponent(
+DesktopBackgroundWidgetController* AnimatingDesktopController::GetController(
bool pass_ownership) {
if (pass_ownership)
- return component_.release();
- return component_.get();
+ return controller_.release();
+ return controller_.get();
}
} // namespace internal
diff --git a/ash/desktop_background/desktop_background_widget_controller.h b/ash/desktop_background/desktop_background_widget_controller.h
index 7017eb0..31a48bd 100644
--- a/ash/desktop_background/desktop_background_widget_controller.h
+++ b/ash/desktop_background/desktop_background_widget_controller.h
@@ -5,6 +5,7 @@
#ifndef ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_WIDGET_CONTROLLER_H_
#define ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_WIDGET_CONTROLLER_H_
+#include "ash/ash_export.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_property.h"
#include "ui/compositor/layer.h"
@@ -20,8 +21,9 @@ namespace internal {
// RootWindow. To avoid a white flash during wallpaper changes the old
// DesktopBackgroundWidgetController is moved to a secondary property
// (kComponentWrapper). When the animation completes the old
-// DesktopBackgroundWidgetController is destroyed.
-class DesktopBackgroundWidgetController : public views::WidgetObserver {
+// DesktopBackgroundWidgetController is destroyed. Exported for tests.
+class ASH_EXPORT DesktopBackgroundWidgetController
+ : public views::WidgetObserver {
public:
// Create
explicit DesktopBackgroundWidgetController(views::Widget* widget);
@@ -55,30 +57,34 @@ class DesktopBackgroundWidgetController : public views::WidgetObserver {
// This class wraps a DesktopBackgroundWidgetController pointer. It is installed
// as an owned property on the RootWindow. DesktopBackgroundWidgetController is
// moved to this property before animation completes. After animation completes,
-// the kWindowDesktopComponent property on RootWindow is set to the
-// DesktopBackgroundWidgetController in this class.
-class ComponentWrapper {
+// the kDesktopController property on RootWindow is set to the
+// DesktopBackgroundWidgetController in this class. Exported for tests.
+class ASH_EXPORT AnimatingDesktopController {
public:
- explicit ComponentWrapper(
+ explicit AnimatingDesktopController(
DesktopBackgroundWidgetController* component);
- ~ComponentWrapper();
+ ~AnimatingDesktopController();
// Gets the wrapped DesktopBackgroundWidgetController pointer. Caller should
// take ownership of the pointer if |pass_ownership| is true.
- DesktopBackgroundWidgetController* GetComponent(bool pass_ownership);
+ DesktopBackgroundWidgetController* GetController(bool pass_ownership);
private:
- scoped_ptr<DesktopBackgroundWidgetController> component_;
+ scoped_ptr<DesktopBackgroundWidgetController> controller_;
- DISALLOW_COPY_AND_ASSIGN(ComponentWrapper);
+ DISALLOW_COPY_AND_ASSIGN(AnimatingDesktopController);
};
// Window property key, that binds instance of DesktopBackgroundWidgetController
-// to root windows.
-extern const aura::WindowProperty<DesktopBackgroundWidgetController*>* const
- kWindowDesktopComponent;
-
-extern const aura::WindowProperty<ComponentWrapper*>* const kComponentWrapper;
+// to root windows. Owned property.
+ASH_EXPORT extern
+ const aura::WindowProperty<DesktopBackgroundWidgetController*>* const
+ kDesktopController;
+
+// Wrapper for the DesktopBackgroundWidgetController for a desktop background
+// that is animating in. Owned property.
+ASH_EXPORT extern const aura::WindowProperty<AnimatingDesktopController*>* const
+ kAnimatingDesktopController;
} // namespace internal
} // namespace ash