summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbruthig <bruthig@chromium.org>2014-09-12 16:48:06 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-12 23:53:51 +0000
commitca2e1496db635fb826949d54c72798fd56f7fcfd (patch)
tree7577d5939b474547e977e24d7e199e15c4ca50e6
parent36f186d9260f10ab4b134987d369d0dd93f298ff (diff)
downloadchromium_src-ca2e1496db635fb826949d54c72798fd56f7fcfd.zip
chromium_src-ca2e1496db635fb826949d54c72798fd56f7fcfd.tar.gz
chromium_src-ca2e1496db635fb826949d54c72798fd56f7fcfd.tar.bz2
- Moved screenshot shortcut handling from MaximizeModeController to PowerButtonController
- Added a command line switch to enable quick locking mode. - Refactored SessionStateAnimator into an interface, implementation, and a test double so that all the LockStateControllerTests could be re-enabled. - Re-enabled LockStateControllerTests. BUG=371608, 167048, 162645 Review URL: https://codereview.chromium.org/326813004 Cr-Commit-Position: refs/heads/master@{#294696}
-rw-r--r--ash/ash.gyp4
-rw-r--r--ash/ash_switches.cc4
-rw-r--r--ash/ash_switches.h1
-rw-r--r--ash/test/test_session_state_animator.cc304
-rw-r--r--ash/test/test_session_state_animator.h166
-rw-r--r--ash/wm/lock_state_controller.cc249
-rw-r--r--ash/wm/lock_state_controller.h23
-rw-r--r--ash/wm/lock_state_controller_unittest.cc611
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller.cc46
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller.h3
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller_unittest.cc30
-rw-r--r--ash/wm/power_button_controller.cc34
-rw-r--r--ash/wm/power_button_controller.h28
-rw-r--r--ash/wm/session_state_animator.cc574
-rw-r--r--ash/wm/session_state_animator.h172
-rw-r--r--ash/wm/session_state_animator_impl.cc669
-rw-r--r--ash/wm/session_state_animator_impl.h88
-rw-r--r--chrome/browser/chromeos/power/power_button_observer.cc7
18 files changed, 1831 insertions, 1182 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 6480900..0dd433c 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -598,6 +598,8 @@
'wm/screen_dimmer.h',
'wm/session_state_animator.cc',
'wm/session_state_animator.h',
+ 'wm/session_state_animator_impl.cc',
+ 'wm/session_state_animator_impl.h',
'wm/stacking_controller.cc',
'wm/stacking_controller.h',
'wm/status_area_layout_manager.cc',
@@ -698,6 +700,8 @@
'test/test_overlay_delegate.h',
'test/test_screenshot_delegate.cc',
'test/test_screenshot_delegate.h',
+ 'test/test_session_state_animator.cc',
+ 'test/test_session_state_animator.h',
'test/test_session_state_delegate.cc',
'test/test_session_state_delegate.h',
'test/test_shelf_delegate.cc',
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index d37e73a..b79eae9 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -58,6 +58,10 @@ const char kAshEnableMagnifierKeyScroller[] =
const char kAshDisableTextFilteringInOverviewMode[] =
"ash-disable-text-filtering-in-overview-mode";
+// Enables quick, non-cancellable locking of the screen when in maximize mode.
+const char kAshEnablePowerButtonQuickLock[] =
+ "ash-enable-power-button-quick-lock";
+
// Enables software based mirroring.
const char kAshEnableSoftwareMirroring[] = "ash-enable-software-mirroring";
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index ad4c86c..42ba11d 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -30,6 +30,7 @@ ASH_EXPORT extern const char kAshDisableTouchExplorationMode[];
ASH_EXPORT extern const char kAshEnableMagnifierKeyScroller[];
#endif
ASH_EXPORT extern const char kAshDisableTextFilteringInOverviewMode[];
+ASH_EXPORT extern const char kAshEnablePowerButtonQuickLock[];
ASH_EXPORT extern const char kAshEnableSoftwareMirroring[];
ASH_EXPORT extern const char kAshEnableSystemSounds[];
ASH_EXPORT extern const char kAshEnableTouchViewTesting[];
diff --git a/ash/test/test_session_state_animator.cc b/ash/test/test_session_state_animator.cc
new file mode 100644
index 0000000..b1d5b47
--- /dev/null
+++ b/ash/test/test_session_state_animator.cc
@@ -0,0 +1,304 @@
+// Copyright 2014 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/test/test_session_state_animator.h"
+
+#include <vector>
+
+#include "base/bind.h"
+
+namespace ash {
+namespace test {
+
+namespace {
+// A no-op callback that can be used when managing an animation that didn't
+// actually have a callback given.
+void DummyCallback() {}
+}
+
+const SessionStateAnimator::Container
+ TestSessionStateAnimator::kAllContainers[] = {
+ SessionStateAnimator::DESKTOP_BACKGROUND,
+ SessionStateAnimator::LAUNCHER,
+ SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
+ SessionStateAnimator::LOCK_SCREEN_BACKGROUND,
+ SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
+ SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS,
+ SessionStateAnimator::ROOT_CONTAINER
+ };
+
+// A simple SessionStateAnimator::AnimationSequence that tracks the number of
+// attached sequences. The callback will be invoked if all animations complete
+// successfully.
+class TestSessionStateAnimator::AnimationSequence
+ : public SessionStateAnimator::AnimationSequence {
+ public:
+ AnimationSequence(base::Closure callback, TestSessionStateAnimator* animator)
+ : SessionStateAnimator::AnimationSequence(callback),
+ sequence_count_(0),
+ sequence_aborted_(false),
+ animator_(animator) {
+ }
+
+ virtual ~AnimationSequence() {}
+
+ virtual void SequenceAttached() {
+ ++sequence_count_;
+ }
+
+ // Notify the sequence that is has completed.
+ virtual void SequenceFinished(bool successfully) {
+ DCHECK_GT(sequence_count_, 0);
+ --sequence_count_;
+ sequence_aborted_ |= !successfully;
+ if (sequence_count_ == 0) {
+ if (sequence_aborted_)
+ OnAnimationAborted();
+ else
+ OnAnimationCompleted();
+ }
+ }
+
+ // ash::SessionStateAnimator::AnimationSequence:
+ virtual void StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) OVERRIDE {
+ animator_->StartAnimationInSequence(container_mask, type, speed, this);
+ }
+
+ private:
+ // Tracks the number of contained animations.
+ int sequence_count_;
+
+ // True if the sequence was aborted.
+ bool sequence_aborted_;
+
+ // The TestSessionAnimator that created this. Not owned.
+ TestSessionStateAnimator* animator_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
+};
+
+TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
+ int animation_epoch,
+ base::TimeDelta duration,
+ SessionStateAnimator::Container container,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure success_callback,
+ base::Closure failed_callback)
+ : animation_epoch(animation_epoch),
+ remaining_duration(duration),
+ container(container),
+ type(type),
+ speed(speed),
+ success_callback(success_callback),
+ failed_callback(failed_callback) {
+}
+
+TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() {
+}
+
+TestSessionStateAnimator::TestSessionStateAnimator()
+ : last_animation_epoch_(0),
+ is_background_hidden_(false) {
+}
+
+TestSessionStateAnimator::~TestSessionStateAnimator() {
+ CompleteAllAnimations(false);
+}
+
+void TestSessionStateAnimator::ResetAnimationEpoch() {
+ CompleteAllAnimations(false);
+ last_animation_epoch_ = 0;
+}
+
+void TestSessionStateAnimator::Advance(const base::TimeDelta& duration) {
+ for (ActiveAnimationsMap::iterator container_iter =
+ active_animations_.begin();
+ container_iter != active_animations_.end();
+ ++container_iter) {
+ AnimationList::iterator animation_iter = (*container_iter).second.begin();
+ while (animation_iter != (*container_iter).second.end()) {
+ ActiveAnimation& active_animation = *animation_iter;
+ active_animation.remaining_duration -= duration;
+ if (active_animation.remaining_duration <= base::TimeDelta()) {
+ active_animation.success_callback.Run();
+ animation_iter = (*container_iter).second.erase(animation_iter);
+ } else {
+ ++animation_iter;
+ }
+ }
+ }
+}
+
+void TestSessionStateAnimator::CompleteAnimations(int animation_epoch,
+ bool completed_successfully) {
+ for (ActiveAnimationsMap::iterator container_iter =
+ active_animations_.begin();
+ container_iter != active_animations_.end();
+ ++container_iter) {
+ AnimationList::iterator animation_iter = (*container_iter).second.begin();
+ while (animation_iter != (*container_iter).second.end()) {
+ ActiveAnimation active_animation = *animation_iter;
+ if (active_animation.animation_epoch <= animation_epoch) {
+ if (completed_successfully)
+ active_animation.success_callback.Run();
+ else
+ active_animation.failed_callback.Run();
+ animation_iter = (*container_iter).second.erase(animation_iter);
+ } else {
+ ++animation_iter;
+ }
+ }
+ }
+}
+
+void TestSessionStateAnimator::CompleteAllAnimations(
+ bool completed_successfully) {
+ CompleteAnimations(last_animation_epoch_, completed_successfully);
+}
+
+bool TestSessionStateAnimator::IsContainerAnimated(
+ SessionStateAnimator::Container container,
+ SessionStateAnimator::AnimationType type) const {
+ ActiveAnimationsMap::const_iterator container_iter =
+ active_animations_.find(container);
+ if (container_iter != active_animations_.end()) {
+ for (AnimationList::const_iterator animation_iter =
+ (*container_iter).second.begin();
+ animation_iter != (*container_iter).second.end();
+ ++animation_iter) {
+ const ActiveAnimation& active_animation = *animation_iter;
+ if (active_animation.type == type)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TestSessionStateAnimator::AreContainersAnimated(
+ int container_mask, SessionStateAnimator::AnimationType type) const {
+ for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
+ if (container_mask & kAllContainers[i] &&
+ !IsContainerAnimated(kAllContainers[i], type)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+size_t TestSessionStateAnimator::GetAnimationCount() const {
+ size_t count = 0;
+ for (ActiveAnimationsMap::const_iterator container_iter =
+ active_animations_.begin();
+ container_iter != active_animations_.end();
+ ++container_iter) {
+ count += (*container_iter).second.size();
+ }
+ return count;
+}
+
+void TestSessionStateAnimator::StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) {
+ ++last_animation_epoch_;
+ for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
+ if (container_mask & kAllContainers[i]) {
+ // Use a dummy no-op callback because one isn't required by the client
+ // but one is required when completing or aborting animations.
+ base::Closure callback = base::Bind(&DummyCallback);
+ AddAnimation(kAllContainers[i], type, speed, callback, callback);
+ }
+ }
+}
+
+void TestSessionStateAnimator::StartAnimationWithCallback(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure callback) {
+ ++last_animation_epoch_;
+ for (size_t i = 0; i < arraysize(kAllContainers); ++i)
+ if (container_mask & kAllContainers[i]) {
+ // ash::SessionStateAnimatorImpl invokes the callback whether or not the
+ // animation was completed successfully or not.
+ AddAnimation(kAllContainers[i], type, speed, callback, callback);
+ }
+}
+
+ash::SessionStateAnimator::AnimationSequence*
+ TestSessionStateAnimator::BeginAnimationSequence(base::Closure callback) {
+ return new AnimationSequence(callback, this);
+}
+
+bool TestSessionStateAnimator::IsBackgroundHidden() const {
+ return is_background_hidden_;
+}
+
+void TestSessionStateAnimator::ShowBackground() {
+ is_background_hidden_ = false;
+}
+
+void TestSessionStateAnimator::HideBackground() {
+ is_background_hidden_ = true;
+}
+
+void TestSessionStateAnimator::StartAnimationInSequence(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ AnimationSequence* animation_sequence) {
+ ++last_animation_epoch_;
+ for (size_t i = 0; i < arraysize(kAllContainers); ++i) {
+ if (container_mask & kAllContainers[i]) {
+ base::Closure success_callback =
+ base::Bind(&AnimationSequence::SequenceFinished,
+ base::Unretained(animation_sequence), true);
+ base::Closure failed_callback =
+ base::Bind(&AnimationSequence::SequenceFinished,
+ base::Unretained(animation_sequence), false);
+ animation_sequence->SequenceAttached();
+ AddAnimation(kAllContainers[i], type, speed, success_callback,
+ failed_callback);
+ }
+ }
+}
+
+void TestSessionStateAnimator::AddAnimation(
+ SessionStateAnimator::Container container,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure success_callback,
+ base::Closure failed_callback) {
+ base::TimeDelta duration = GetDuration(speed);
+ ActiveAnimation active_animation(last_animation_epoch_,
+ duration,
+ container,
+ type,
+ speed,
+ success_callback,
+ failed_callback);
+ // This test double is limited to only have one animation active for a given
+ // container at a time.
+ AbortAnimation(container);
+ active_animations_[container].push_back(active_animation);
+}
+
+void TestSessionStateAnimator::AbortAnimation(
+ SessionStateAnimator::Container container) {
+ ActiveAnimationsMap::iterator container_iter =
+ active_animations_.find(container);
+ if (container_iter != active_animations_.end()) {
+ AnimationList::iterator animation_iter = (*container_iter).second.begin();
+ while (animation_iter != (*container_iter).second.end()) {
+ ActiveAnimation active_animation = *animation_iter;
+ active_animation.failed_callback.Run();
+ animation_iter = (*container_iter).second.erase(animation_iter);
+ }
+ }
+}
+
+} // namespace test
+} // namespace ash
diff --git a/ash/test/test_session_state_animator.h b/ash/test/test_session_state_animator.h
new file mode 100644
index 0000000..d308010
--- /dev/null
+++ b/ash/test/test_session_state_animator.h
@@ -0,0 +1,166 @@
+// Copyright 2014 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.
+
+#ifndef ASH_TEST_TEST_SESSION_STATE_ANIMATOR_H_
+#define ASH_TEST_TEST_SESSION_STATE_ANIMATOR_H_
+
+#include <map>
+#include <vector>
+
+#include "ash/ash_export.h"
+#include "ash/wm/session_state_animator.h"
+#include "base/basictypes.h"
+#include "base/time/time.h"
+
+namespace ash {
+namespace test {
+
+// A SessionStateAnimator that offers control over the lifetime of active
+// animations.
+// NOTE: The TestSessionStateAnimator limits each
+// SessionStateAnimator::Container to a single active animation at any one time.
+// If a new animation is started on a container the existing one will be
+// aborted.
+class TestSessionStateAnimator : public SessionStateAnimator {
+ public:
+ TestSessionStateAnimator();
+ virtual ~TestSessionStateAnimator();
+
+ int last_animation_epoch() {
+ return last_animation_epoch_;
+ }
+
+ // Resets the current animation epoch back to 0 and aborts all currently
+ // active animations.
+ void ResetAnimationEpoch();
+
+ // Advances all contained animations by the specified |duration|. Any
+ // animations that will have completed after |duration| will have its
+ // callback called.
+ void Advance(const base::TimeDelta& duration);
+
+ // Simulates running all of the contained animations to completion. Each
+ // contained AnimationSequence will have OnAnimationCompleted called if
+ // |completed_successfully| is true and OnAnimationAborted called if false.
+ void CompleteAnimations(int animation_epoch, bool completed_successfully);
+
+ // Convenience method that calls CompleteAnimations with the last
+ // |animation_epoch|. In effect this will complete all animations.
+ // See CompleteAnimations for more documenation on |completed_succesffully|.
+ void CompleteAllAnimations(bool completed_successfully);
+
+ // Returns true if there is an animation active with |type| for the given
+ // |container|.
+ bool IsContainerAnimated(SessionStateAnimator::Container container,
+ SessionStateAnimator::AnimationType type) const;
+
+ // Returns true if there is an animation active with |type| for all the given
+ // containers specified by |container_mask|.
+ bool AreContainersAnimated(int container_mask,
+ SessionStateAnimator::AnimationType type) const;
+
+ // Returns the number of active animations.
+ size_t GetAnimationCount() const;
+
+ // ash::SessionStateAnimator:
+ virtual void StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) OVERRIDE;
+ virtual void StartAnimationWithCallback(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure callback) OVERRIDE;
+ virtual AnimationSequence* BeginAnimationSequence(
+ base::Closure callback) OVERRIDE;
+ virtual bool IsBackgroundHidden() const OVERRIDE;
+ virtual void ShowBackground() OVERRIDE;
+ virtual void HideBackground() OVERRIDE;
+
+ private:
+ class AnimationSequence;
+ friend class AnimationSequence;
+
+ // Data structure to track the currently active animations and their
+ // callbacks.
+ struct ActiveAnimation {
+ ActiveAnimation(
+ int animation_epoch,
+ base::TimeDelta duration,
+ SessionStateAnimator::Container container,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure success_callback,
+ base::Closure failed_callback);
+ virtual ~ActiveAnimation();
+
+ // The time epoch that this animation was scheduled.
+ int animation_epoch;
+
+ // The time remaining for this animation.
+ base::TimeDelta remaining_duration;
+
+ // The container which is being animated.
+ SessionStateAnimator::Container container;
+
+ // The animation type that is being done.
+ AnimationType type;
+
+ // The speed at which the animation is being done.
+ AnimationSpeed speed;
+
+ // The callback to be invoked upon a successful completion.
+ base::Closure success_callback;
+
+ // The callback to be invoked upon an unsuccessful completion.
+ base::Closure failed_callback;
+ };
+
+ typedef std::vector<ActiveAnimation> AnimationList;
+ typedef std::map<SessionStateAnimator::Container, AnimationList>
+ ActiveAnimationsMap;
+
+ // Starts an animation in the |animation_sequence| for each container
+ // specified by |container_mask| with the given |type| and |speed|.
+ virtual void StartAnimationInSequence(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ AnimationSequence* animation_sequence);
+
+ // Adds a single animation to the currently active animations. If an
+ // animation is already active for the given |container| then it will be
+ // replaced by the new one. The existing animation will be aborted by calling
+ // OnAnimationAborted.
+ void AddAnimation(SessionStateAnimator::Container container,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure success_callback,
+ base::Closure failed_callback);
+
+ // If an animation is currently active for the given |container| it will be
+ // aborted by invoking OnAnimationAborted and removed from the list of active
+ // animations.
+ void AbortAnimation(SessionStateAnimator::Container container);
+
+ // Used for easy iteration over all the containers.
+ static const SessionStateAnimator::Container kAllContainers[];
+
+ // A map of currently active animations.
+ ActiveAnimationsMap active_animations_;
+
+ // A time counter that tracks the last scheduled animation or animation
+ // sequence.
+ int last_animation_epoch_;
+
+ // Tracks whether the background is hidden or not.
+ bool is_background_hidden_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestSessionStateAnimator);
+};
+
+} // namespace test
+} // namespace ash
+
+#endif // ASH_TEST_TEST_SESSION_STATE_ANIMATOR_H_
diff --git a/ash/wm/lock_state_controller.cc b/ash/wm/lock_state_controller.cc
index ebb0698..a03a958 100644
--- a/ash/wm/lock_state_controller.cc
+++ b/ash/wm/lock_state_controller.cc
@@ -5,6 +5,7 @@
#include "ash/wm/lock_state_controller.h"
#include <algorithm>
+#include <string>
#include "ash/accessibility_delegate.h"
#include "ash/ash_switches.h"
@@ -14,13 +15,12 @@
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/session_state_animator.h"
+#include "ash/wm/session_state_animator_impl.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/strings/string_util.h"
#include "base/timer/timer.h"
#include "ui/aura/window_tree_host.h"
-#include "ui/compositor/layer_animation_sequence.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/wm/core/compound_event_filter.h"
@@ -41,113 +41,6 @@ namespace {
const int kMaxShutdownSoundDurationMs = 1500;
#endif
-aura::Window* GetBackground() {
- aura::Window* root_window = Shell::GetPrimaryRootWindow();
- return Shell::GetContainer(root_window,
- kShellWindowId_DesktopBackgroundContainer);
-}
-
-bool IsBackgroundHidden() {
- return !GetBackground()->IsVisible();
-}
-
-void ShowBackground() {
- ui::ScopedLayerAnimationSettings settings(
- GetBackground()->layer()->GetAnimator());
- settings.SetTransitionDuration(base::TimeDelta());
- GetBackground()->Show();
-}
-
-void HideBackground() {
- ui::ScopedLayerAnimationSettings settings(
- GetBackground()->layer()->GetAnimator());
- settings.SetTransitionDuration(base::TimeDelta());
- GetBackground()->Hide();
-}
-
-// This observer is intended to use in cases when some action has to be taken
-// once some animation successfully completes (i.e. it was not aborted).
-// Observer will count a number of sequences it is attached to, and a number of
-// finished sequences (either Ended or Aborted). Once these two numbers are
-// equal, observer will delete itself, calling callback passed to constructor if
-// there were no aborted animations.
-// This way it can be either used to wait for some animation to be finished in
-// multiple layers, to wait once a sequence of animations is finished in one
-// layer or the mixture of both.
-class AnimationFinishedObserver : public ui::LayerAnimationObserver {
- public:
- explicit AnimationFinishedObserver(base::Closure &callback)
- : callback_(callback),
- sequences_attached_(0),
- sequences_completed_(0),
- paused_(false) {
- }
-
- // Pauses observer: no checks will be made while paused. It can be used when
- // a sequence has some immediate animations in the beginning, and for
- // animations that can be tested with flag that makes all animations
- // immediate.
- void Pause() {
- paused_ = true;
- }
-
- // Unpauses observer. It does a check and calls callback if conditions are
- // met.
- void Unpause() {
- if (!paused_)
- return;
- paused_ = false;
- if (sequences_completed_ == sequences_attached_) {
- callback_.Run();
- delete this;
- }
- }
-
- private:
- virtual ~AnimationFinishedObserver() {
- }
-
- // LayerAnimationObserver implementation
- virtual void OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) OVERRIDE {
- sequences_completed_++;
- if ((sequences_completed_ == sequences_attached_) && !paused_) {
- callback_.Run();
- delete this;
- }
- }
-
- virtual void OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) OVERRIDE {
- sequences_completed_++;
- if ((sequences_completed_ == sequences_attached_) && !paused_)
- delete this;
- }
-
- virtual void OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) OVERRIDE {
- }
-
- virtual void OnAttachedToSequence(
- ui::LayerAnimationSequence* sequence) OVERRIDE {
- LayerAnimationObserver::OnAttachedToSequence(sequence);
- sequences_attached_++;
- }
-
- // Callback to be called.
- base::Closure callback_;
-
- // Number of sequences this observer was attached to.
- int sequences_attached_;
-
- // Number of sequences either ended or aborted.
- int sequences_completed_;
-
- bool paused_;
-
- DISALLOW_COPY_AND_ASSIGN(AnimationFinishedObserver);
-};
-
} // namespace
const int LockStateController::kLockTimeoutMs = 400;
@@ -164,7 +57,7 @@ LockStateController::TestApi::~TestApi() {
}
LockStateController::LockStateController()
- : animator_(new SessionStateAnimator()),
+ : animator_(new SessionStateAnimatorImpl()),
login_status_(user::LOGGED_IN_NONE),
system_is_locked_(false),
shutting_down_(false),
@@ -179,8 +72,9 @@ LockStateController::~LockStateController() {
Shell::GetPrimaryRootWindow()->GetHost()->RemoveObserver(this);
}
-void LockStateController::SetDelegate(LockStateControllerDelegate* delegate) {
- delegate_.reset(delegate);
+void LockStateController::SetDelegate(
+ scoped_ptr<LockStateControllerDelegate> delegate) {
+ delegate_ = delegate.Pass();
}
void LockStateController::AddObserver(LockStateObserver* observer) {
@@ -209,9 +103,11 @@ void LockStateController::StartShutdownAnimation() {
StartCancellableShutdownAnimation();
}
-void LockStateController::StartLockAnimationAndLockImmediately() {
+void LockStateController::StartLockAnimationAndLockImmediately(
+ bool shutdown_after_lock) {
if (animating_lock_)
return;
+ shutdown_after_lock_ = shutdown_after_lock;
StartImmediatePreLockAnimation(true /* request_lock_on_completion */);
}
@@ -253,7 +149,8 @@ void LockStateController::CancelShutdownAnimation() {
return;
}
- animator_->StartGlobalAnimation(
+ animator_->StartAnimation(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
pre_shutdown_timer_.Stop();
@@ -277,7 +174,8 @@ void LockStateController::RequestShutdown() {
shell->cursor_manager()->HideCursor();
shell->cursor_manager()->LockCursor();
- animator_->StartGlobalAnimation(
+ animator_->StartAnimation(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
StartRealShutdownTimer(true);
@@ -314,7 +212,7 @@ void LockStateController::OnAppTerminating() {
Shell* shell = ash::Shell::GetInstance();
shell->cursor_manager()->HideCursor();
shell->cursor_manager()->LockCursor();
- animator_->StartAnimation(SessionStateAnimator::kAllContainersMask,
+ animator_->StartAnimation(SessionStateAnimator::kAllNonRootContainersMask,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
@@ -418,7 +316,8 @@ void LockStateController::StartCancellableShutdownAnimation() {
// Hide cursor, but let it reappear if the mouse moves.
shell->cursor_manager()->HideCursor();
- animator_->StartGlobalAnimation(
+ animator_->StartAnimation(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
StartPreShutdownAnimationTimer();
@@ -434,29 +333,25 @@ void LockStateController::StartImmediatePreLockAnimation(
base::Bind(&LockStateController::PreLockAnimationFinished,
weak_ptr_factory_.GetWeakPtr(),
request_lock_on_completion);
- AnimationFinishedObserver* observer =
- new AnimationFinishedObserver(next_animation_starter);
-
- observer->Pause();
+ SessionStateAnimator::AnimationSequence* animation_sequence =
+ animator_->BeginAnimationSequence(next_animation_starter);
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT,
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
- observer);
- animator_->StartAnimationWithObserver(
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ animation_sequence->StartAnimation(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_OUT,
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
- observer);
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
// Hide the screen locker containers so we can raise them later.
animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
AnimateBackgroundAppearanceIfNecessary(
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, observer);
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, animation_sequence);
- observer->Unpause();
+ animation_sequence->EndSequence();
DispatchCancelMode();
FOR_EACH_OBSERVER(LockStateObserver, observers_,
@@ -471,32 +366,28 @@ void LockStateController::StartCancellablePreLockAnimation() {
base::Bind(&LockStateController::PreLockAnimationFinished,
weak_ptr_factory_.GetWeakPtr(),
true /* request_lock */);
- AnimationFinishedObserver* observer =
- new AnimationFinishedObserver(next_animation_starter);
-
- observer->Pause();
+ SessionStateAnimator::AnimationSequence* animation_sequence =
+ animator_->BeginAnimationSequence(next_animation_starter);
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT,
- SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
- observer);
- animator_->StartAnimationWithObserver(
+ SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
+ animation_sequence->StartAnimation(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_OUT,
- SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
- observer);
+ SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
// Hide the screen locker containers so we can raise them later.
animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
AnimateBackgroundAppearanceIfNecessary(
- SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, observer);
+ SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, animation_sequence);
DispatchCancelMode();
FOR_EACH_OBSERVER(LockStateObserver, observers_,
OnLockStateEvent(LockStateObserver::EVENT_PRELOCK_ANIMATION_STARTED));
- observer->Unpause();
+ animation_sequence->EndSequence();
}
void LockStateController::CancelPreLockAnimation() {
@@ -504,25 +395,22 @@ void LockStateController::CancelPreLockAnimation() {
base::Closure next_animation_starter =
base::Bind(&LockStateController::LockAnimationCancelled,
weak_ptr_factory_.GetWeakPtr());
- AnimationFinishedObserver* observer =
- new AnimationFinishedObserver(next_animation_starter);
+ SessionStateAnimator::AnimationSequence* animation_sequence =
+ animator_->BeginAnimationSequence(next_animation_starter);
- observer->Pause();
-
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_UNDO_LIFT,
- SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
- observer);
- animator_->StartAnimationWithObserver(
+ SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
+ animation_sequence->StartAnimation(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_IN,
- SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
- observer);
+ SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
AnimateBackgroundHidingIfNecessary(
- SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS, observer);
+ SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
+ animation_sequence);
- observer->Unpause();
+ animation_sequence->EndSequence();
}
void LockStateController::StartPostLockAnimation() {
@@ -530,17 +418,14 @@ void LockStateController::StartPostLockAnimation() {
base::Closure next_animation_starter =
base::Bind(&LockStateController::PostLockAnimationFinished,
weak_ptr_factory_.GetWeakPtr());
+ SessionStateAnimator::AnimationSequence* animation_sequence =
+ animator_->BeginAnimationSequence(next_animation_starter);
- AnimationFinishedObserver* observer =
- new AnimationFinishedObserver(next_animation_starter);
-
- observer->Pause();
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN,
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
- observer);
- observer->Unpause();
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ animation_sequence->EndSequence();
}
void LockStateController::StartUnlockAnimationBeforeUIDestroyed(
@@ -558,25 +443,20 @@ void LockStateController::StartUnlockAnimationAfterUIDestroyed() {
base::Closure next_animation_starter =
base::Bind(&LockStateController::UnlockAnimationAfterUIDestroyedFinished,
weak_ptr_factory_.GetWeakPtr());
+ SessionStateAnimator::AnimationSequence* animation_sequence =
+ animator_->BeginAnimationSequence(next_animation_starter);
- AnimationFinishedObserver* observer =
- new AnimationFinishedObserver(next_animation_starter);
-
- observer->Pause();
-
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_DROP,
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
- observer);
- animator_->StartAnimationWithObserver(
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ animation_sequence->StartAnimation(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_IN,
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
- observer);
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
AnimateBackgroundHidingIfNecessary(
- SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, observer);
- observer->Unpause();
+ SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, animation_sequence);
+ animation_sequence->EndSequence();
}
void LockStateController::LockAnimationCancelled() {
@@ -642,14 +522,15 @@ void LockStateController::UnlockAnimationAfterUIDestroyedFinished() {
void LockStateController::StoreUnlockedProperties() {
if (!unlocked_properties_) {
unlocked_properties_.reset(new UnlockedStateProperties());
- unlocked_properties_->background_is_hidden = IsBackgroundHidden();
+ unlocked_properties_->background_is_hidden =
+ animator_->IsBackgroundHidden();
}
if (unlocked_properties_->background_is_hidden) {
// Hide background so that it can be animated later.
animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
- ShowBackground();
+ animator_->ShowBackground();
}
}
@@ -657,7 +538,7 @@ void LockStateController::RestoreUnlockedProperties() {
if (!unlocked_properties_)
return;
if (unlocked_properties_->background_is_hidden) {
- HideBackground();
+ animator_->HideBackground();
// Restore background visibility.
animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_FADE_IN,
@@ -668,27 +549,25 @@ void LockStateController::RestoreUnlockedProperties() {
void LockStateController::AnimateBackgroundAppearanceIfNecessary(
SessionStateAnimator::AnimationSpeed speed,
- ui::LayerAnimationObserver* observer) {
+ SessionStateAnimator::AnimationSequence* animation_sequence) {
if (unlocked_properties_.get() &&
unlocked_properties_->background_is_hidden) {
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_FADE_IN,
- speed,
- observer);
+ speed);
}
}
void LockStateController::AnimateBackgroundHidingIfNecessary(
SessionStateAnimator::AnimationSpeed speed,
- ui::LayerAnimationObserver* observer) {
+ SessionStateAnimator::AnimationSequence* animation_sequence) {
if (unlocked_properties_.get() &&
unlocked_properties_->background_is_hidden) {
- animator_->StartAnimationWithObserver(
+ animation_sequence->StartAnimation(
SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_FADE_OUT,
- speed,
- observer);
+ speed);
}
}
diff --git a/ash/wm/lock_state_controller.h b/ash/wm/lock_state_controller.h
index b6d134f..ca16688 100644
--- a/ash/wm/lock_state_controller.h
+++ b/ash/wm/lock_state_controller.h
@@ -52,8 +52,8 @@ class ASH_EXPORT LockStateControllerDelegate {
// Entry points:
// * StartLockAnimation (bool shutdown after lock) - starts lock that can be
// cancelled.
-// * StartLockAnimationAndLockImmediately - starts uninterruptible lock
-// animation.
+// * StartLockAnimationAndLockImmediately (bool shutdown after lock) - starts
+// uninterruptible lock animation.
// This leads to call of either StartImmediatePreLockAnimation or
// StartCancellablePreLockAnimation. Once they complete
// PreLockAnimationFinished is called, and system lock is requested.
@@ -135,6 +135,7 @@ class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
controller_->OnRealShutdownTimeout();
controller_->real_shutdown_timer_.Stop();
}
+
private:
LockStateController* controller_; // not owned
@@ -144,8 +145,7 @@ class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
LockStateController();
virtual ~LockStateController();
- // Takes ownership of |delegate|.
- void SetDelegate(LockStateControllerDelegate* delegate);
+ void SetDelegate(scoped_ptr<LockStateControllerDelegate> delegate);
void AddObserver(LockStateObserver* observer);
void RemoveObserver(LockStateObserver* observer);
@@ -160,9 +160,10 @@ class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
// Starts shutting down (with slow animation) that can be cancelled.
void StartShutdownAnimation();
- // Starts usual lock animation, but locks immediately.
- // Unlike StartLockAnimation it does no lead to StartShutdownAnimation.
- void StartLockAnimationAndLockImmediately();
+ // Starts usual lock animation, but locks immediately. After locking and
+ // |kLockToShutdownTimeoutMs| StartShutdownAnimation() will be called unless
+ // CancelShutdownAnimation() is called, if |shutdown_after_lock| is true.
+ void StartLockAnimationAndLockImmediately(bool shutdown_after_lock);
// Returns true if we have requested system to lock, but haven't received
// confirmation yet.
@@ -206,6 +207,10 @@ class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
virtual void OnAppTerminating() OVERRIDE;
virtual void OnLockStateChanged(bool locked) OVERRIDE;
+ void set_animator_for_test(SessionStateAnimator* animator) {
+ animator_.reset(animator);
+ }
+
private:
friend class test::PowerButtonControllerTest;
friend class test::LockStateControllerTest;
@@ -266,12 +271,12 @@ class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
// Fades in background layer with |speed| if it was hidden in unlocked state.
void AnimateBackgroundAppearanceIfNecessary(
ash::SessionStateAnimator::AnimationSpeed speed,
- ui::LayerAnimationObserver* observer);
+ SessionStateAnimator::AnimationSequence* animation_sequence);
// Fades out background layer with |speed| if it was hidden in unlocked state.
void AnimateBackgroundHidingIfNecessary(
ash::SessionStateAnimator::AnimationSpeed speed,
- ui::LayerAnimationObserver* observer);
+ SessionStateAnimator::AnimationSequence* animation_sequence);
scoped_ptr<SessionStateAnimator> animator_;
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc
index 80db349..cca575f 100644
--- a/ash/wm/lock_state_controller_unittest.cc
+++ b/ash/wm/lock_state_controller_unittest.cc
@@ -4,26 +4,20 @@
#include "ash/wm/lock_state_controller.h"
-#include "ash/ash_switches.h"
#include "ash/session/session_state_delegate.h"
#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_lock_state_controller_delegate.h"
+#include "ash/test/test_screenshot_delegate.h"
+#include "ash/test/test_session_state_animator.h"
#include "ash/test/test_shell_delegate.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/power_button_controller.h"
#include "ash/wm/session_state_animator.h"
-#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
-#include "ui/aura/env.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/compositor/layer_animator.h"
-#include "ui/compositor/scoped_animation_duration_scale_mode.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/test/event_generator.h"
-#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#if defined(OS_CHROMEOS)
@@ -32,10 +26,6 @@
#include "ui/display/types/display_constants.h"
#endif
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
namespace ash {
namespace test {
namespace {
@@ -49,66 +39,35 @@ void CheckCalledCallback(bool* flag) {
(*flag) = true;
}
-aura::Window* GetContainer(int container ) {
- aura::Window* root_window = Shell::GetPrimaryRootWindow();
- return Shell::GetContainer(root_window, container);
-}
-
-bool IsBackgroundHidden() {
- return !GetContainer(kShellWindowId_DesktopBackgroundContainer)->IsVisible();
-}
-
-void HideBackground() {
- ui::ScopedLayerAnimationSettings settings(
- GetContainer(kShellWindowId_DesktopBackgroundContainer)
- ->layer()
- ->GetAnimator());
- settings.SetTransitionDuration(base::TimeDelta());
- GetContainer(kShellWindowId_DesktopBackgroundContainer)->Hide();
-}
-
-} // namespace
+} // namespace
class LockStateControllerTest : public AshTestBase {
public:
- LockStateControllerTest() : controller_(NULL), delegate_(NULL) {}
+ LockStateControllerTest() : power_button_controller_(NULL),
+ lock_state_controller_(NULL),
+ lock_state_controller_delegate_(NULL),
+ test_animator_(NULL) {
+ }
virtual ~LockStateControllerTest() {}
virtual void SetUp() OVERRIDE {
AshTestBase::SetUp();
- // We would control animations in a fine way:
- animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
- ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION));
- // TODO(antrim) : restore
- // animator_helper_ = ui::test::CreateLayerAnimatorHelperForTest();
-
- // Temporary disable animations so that observer is always called, and
- // no leaks happen during tests.
- animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
- // TODO(antrim): once there is a way to mock time and run animations, make
- // sure that animations are finished even in simple tests.
-
- delegate_ = new TestLockStateControllerDelegate;
- controller_ = Shell::GetInstance()->power_button_controller();
- lock_state_controller_ = static_cast<LockStateController*>(
- Shell::GetInstance()->lock_state_controller());
- lock_state_controller_->SetDelegate(delegate_); // transfers ownership
+ scoped_ptr<LockStateControllerDelegate> lock_state_controller_delegate(
+ lock_state_controller_delegate_ = new TestLockStateControllerDelegate);
+ test_animator_ = new TestSessionStateAnimator;
+
+ lock_state_controller_ = Shell::GetInstance()->lock_state_controller();
+ lock_state_controller_->SetDelegate(lock_state_controller_delegate.Pass());
+ lock_state_controller_->set_animator_for_test(test_animator_);
+
test_api_.reset(new LockStateController::TestApi(lock_state_controller_));
- animator_api_.reset(
- new SessionStateAnimator::TestApi(lock_state_controller_->
- animator_.get()));
- shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
- ash::Shell::GetInstance()->delegate());
+
+ power_button_controller_ = Shell::GetInstance()->power_button_controller();
session_state_delegate_ = Shell::GetInstance()->session_state_delegate();
- }
- virtual void TearDown() {
- // TODO(antrim) : restore
- // animator_helper_->AdvanceUntilDone();
- window_.reset();
- AshTestBase::TearDown();
+ shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
+ ash::Shell::GetInstance()->delegate());
}
protected:
@@ -118,241 +77,260 @@ class LockStateControllerTest : public AshTestBase {
}
int NumShutdownRequests() {
- return delegate_->num_shutdown_requests() +
- shell_delegate_->num_exit_requests();
+ return lock_state_controller_delegate_->num_shutdown_requests() +
+ shell_delegate_->num_exit_requests();
}
void Advance(SessionStateAnimator::AnimationSpeed speed) {
- // TODO (antrim) : restore
- // animator_helper_->Advance(SessionStateAnimator::GetDuration(speed));
+ test_animator_->Advance(test_animator_->GetDuration(speed));
}
void AdvancePartially(SessionStateAnimator::AnimationSpeed speed,
float factor) {
-// TODO (antrim) : restore
-// base::TimeDelta duration = SessionStateAnimator::GetDuration(speed);
-// base::TimeDelta partial_duration =
-// base::TimeDelta::FromInternalValue(duration.ToInternalValue() * factor);
-// animator_helper_->Advance(partial_duration);
+ base::TimeDelta duration = test_animator_->GetDuration(speed);
+ base::TimeDelta partial_duration =
+ base::TimeDelta::FromInternalValue(duration.ToInternalValue() * factor);
+ test_animator_->Advance(partial_duration);
}
void ExpectPreLockAnimationStarted() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectPreLockAnimationStarted");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT));
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_OUT));
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
EXPECT_TRUE(test_api_->is_animating_lock());
}
+ void ExpectPreLockAnimationRunning() {
+ SCOPED_TRACE("Failure in ExpectPreLockAnimationRunning");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
+ EXPECT_TRUE(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
+ SessionStateAnimator::ANIMATION_LIFT));
+ EXPECT_TRUE(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::LAUNCHER,
+ SessionStateAnimator::ANIMATION_FADE_OUT));
+ EXPECT_TRUE(test_api_->is_animating_lock());
+ }
+
void ExpectPreLockAnimationCancel() {
+ SCOPED_TRACE("Failure in ExpectPreLockAnimationCancel");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- SessionStateAnimator::ANIMATION_DROP));
+ SessionStateAnimator::ANIMATION_UNDO_LIFT));
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_IN));
}
void ExpectPreLockAnimationFinished() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ SCOPED_TRACE("Failure in ExpectPreLockAnimationFinished");
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT));
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_OUT));
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
}
void ExpectPostLockAnimationStarted() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectPostLockAnimationStarted");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
}
- void ExpectPastLockAnimationFinished() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ void ExpectPostLockAnimationFinished() {
+ SCOPED_TRACE("Failure in ExpectPostLockAnimationFinished");
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
}
void ExpectUnlockBeforeUIDestroyedAnimationStarted() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectUnlockBeforeUIDestroyedAnimationStarted");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT));
}
void ExpectUnlockBeforeUIDestroyedAnimationFinished() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ SCOPED_TRACE("Failure in ExpectUnlockBeforeUIDestroyedAnimationFinished");
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT));
}
void ExpectUnlockAfterUIDestroyedAnimationStarted() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectUnlockAfterUIDestroyedAnimationStarted");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_DROP));
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_IN));
}
void ExpectUnlockAfterUIDestroyedAnimationFinished() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ SCOPED_TRACE("Failure in ExpectUnlockAfterUIDestroyedAnimationFinished");
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_DROP));
- EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::LAUNCHER,
SessionStateAnimator::ANIMATION_FADE_IN));
}
void ExpectShutdownAnimationStarted() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectShutdownAnimationStarted");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->RootWindowIsAnimated(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
}
- void ExpectShutdownAnimationFinished() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
- EXPECT_TRUE(
- animator_api_->RootWindowIsAnimated(
+ void ExpectShutdownAnimationFinished() {
+ SCOPED_TRACE("Failure in ExpectShutdownAnimationFinished");
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
+ EXPECT_FALSE(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
}
void ExpectShutdownAnimationCancel() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectShutdownAnimationCancel");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->RootWindowIsAnimated(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::ROOT_CONTAINER,
SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS));
}
void ExpectBackgroundIsShowing() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectBackgroundIsShowing");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_FADE_IN));
}
void ExpectBackgroundIsHiding() {
- //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectBackgroundIsHiding");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
+ test_animator_->AreContainersAnimated(
SessionStateAnimator::DESKTOP_BACKGROUND,
SessionStateAnimator::ANIMATION_FADE_OUT));
}
+ void ExpectRestoringBackgroundVisibility() {
+ SCOPED_TRACE("Failure in ExpectRestoringBackgroundVisibility");
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
+ EXPECT_TRUE(
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::DESKTOP_BACKGROUND,
+ SessionStateAnimator::ANIMATION_FADE_IN));
+ }
+
void ExpectUnlockedState() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectUnlockedState");
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
EXPECT_FALSE(session_state_delegate_->IsScreenLocked());
-
- aura::Window::Windows containers;
-
- SessionStateAnimator::GetContainers(
- SessionStateAnimator::LAUNCHER |
- SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- aura::Window* window = *it;
- ui::Layer* layer = window->layer();
- EXPECT_EQ(1.0f, layer->opacity());
- EXPECT_EQ(0.0f, layer->layer_brightness());
- EXPECT_EQ(0.0f, layer->layer_saturation());
- EXPECT_EQ(gfx::Transform(), layer->transform());
- }
}
void ExpectLockedState() {
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
+ SCOPED_TRACE("Failure in ExpectLockedState");
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
EXPECT_TRUE(session_state_delegate_->IsScreenLocked());
+ }
- aura::Window::Windows containers;
-
- SessionStateAnimator::GetContainers(
- SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS |
- SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
- &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- aura::Window* window = *it;
- ui::Layer* layer = window->layer();
- EXPECT_EQ(1.0f, layer->opacity());
- EXPECT_EQ(0.0f, layer->layer_brightness());
- EXPECT_EQ(0.0f, layer->layer_saturation());
- EXPECT_EQ(gfx::Transform(), layer->transform());
- }
+ void HideBackground() {
+ test_animator_->HideBackground();
}
void PressPowerButton() {
- controller_->OnPowerButtonEvent(true, base::TimeTicks::Now());
- //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
+ power_button_controller_->OnPowerButtonEvent(true, base::TimeTicks::Now());
}
void ReleasePowerButton() {
- controller_->OnPowerButtonEvent(false, base::TimeTicks::Now());
- //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
+ power_button_controller_->OnPowerButtonEvent(false, base::TimeTicks::Now());
}
void PressLockButton() {
- controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
+ power_button_controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
}
void ReleaseLockButton() {
- controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
+ power_button_controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
+ }
+
+ void PressVolumeDown() {
+ GetEventGenerator().PressKey(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
+ }
+
+ void ReleaseVolumeDown() {
+ GetEventGenerator().ReleaseKey(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
}
void SystemLocks() {
lock_state_controller_->OnLockStateChanged(true);
session_state_delegate_->LockScreen();
- //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
}
void SuccessfulAuthentication(bool* call_flag) {
base::Closure closure = base::Bind(&CheckCalledCallback, call_flag);
lock_state_controller_->OnLockScreenHide(closure);
- //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
}
void SystemUnlocks() {
lock_state_controller_->OnLockStateChanged(false);
session_state_delegate_->UnlockScreen();
- //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
+ }
+
+ void EnableMaximizeMode(bool enable) {
+ Shell::GetInstance()->maximize_mode_controller()->
+ EnableMaximizeModeWindowManager(enable);
}
void Initialize(bool legacy_button, user::LoginStatus status) {
- controller_->set_has_legacy_power_button_for_test(legacy_button);
+ power_button_controller_->set_has_legacy_power_button_for_test(
+ legacy_button);
lock_state_controller_->OnLoginStateChanged(status);
SetUserLoggedIn(status != user::LOGGED_IN_NONE);
if (status == user::LOGGED_IN_GUEST)
@@ -360,32 +338,14 @@ class LockStateControllerTest : public AshTestBase {
lock_state_controller_->OnLockStateChanged(false);
}
- void CreateWindowForLockscreen() {
- window_.reset(new aura::Window(&window_delegate_));
- window_->SetBounds(gfx::Rect(0, 0, 100, 100));
- window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
- window_->Init(aura::WINDOW_LAYER_TEXTURED);
- window_->SetName("WINDOW");
- aura::Window* container = Shell::GetContainer(
- Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer);
- ASSERT_TRUE(container);
- container->AddChild(window_.get());
- window_->Show();
- }
-
- PowerButtonController* controller_; // not owned
+ PowerButtonController* power_button_controller_; // not owned
LockStateController* lock_state_controller_; // not owned
- TestLockStateControllerDelegate* delegate_; // not owned
- TestShellDelegate* shell_delegate_; // not owned
+ TestLockStateControllerDelegate*
+ lock_state_controller_delegate_; // not owned
+ TestSessionStateAnimator* test_animator_; // not owned
SessionStateDelegate* session_state_delegate_; // not owned
-
- aura::test::TestWindowDelegate window_delegate_;
- scoped_ptr<aura::Window> window_;
- scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration_mode_;
scoped_ptr<LockStateController::TestApi> test_api_;
- scoped_ptr<SessionStateAnimator::TestApi> animator_api_;
- // TODO(antrim) : restore
-// scoped_ptr<ui::test::AnimationContainerTestHelper> animator_helper_;
+ TestShellDelegate* shell_delegate_; // not owned
private:
DISALLOW_COPY_AND_ASSIGN(LockStateControllerTest);
@@ -395,8 +355,7 @@ class LockStateControllerTest : public AshTestBase {
// correctly report power button releases. We should lock immediately the first
// time the button is pressed and shut down when it's pressed from the locked
// state.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_LegacyLockAndShutDown) {
+TEST_F(LockStateControllerTest, LegacyLockAndShutDown) {
Initialize(true, user::LOGGED_IN_USER);
ExpectUnlockedState();
@@ -405,26 +364,23 @@ TEST_F(LockStateControllerTest, DISABLED_LegacyLockAndShutDown) {
// power button get pressed.
PressPowerButton();
- ExpectPreLockAnimationStarted();
-
EXPECT_FALSE(test_api_->is_lock_cancellable());
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
-
+ ExpectPreLockAnimationStarted();
+ test_animator_->CompleteAllAnimations(true);
ExpectPreLockAnimationFinished();
- EXPECT_EQ(1, delegate_->num_lock_requests());
+
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
// Notify that we locked successfully.
lock_state_controller_->OnStartingLock();
- // We had that animation already.
- //TODO (antrim) : restore
- // EXPECT_FALSE(animator_helper_->IsAnimating());
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
SystemLocks();
ExpectPostLockAnimationStarted();
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
- ExpectPastLockAnimationFinished();
+ test_animator_->CompleteAllAnimations(true);
+ ExpectPostLockAnimationFinished();
// We shouldn't progress towards the shutdown state, however.
EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
@@ -510,8 +466,7 @@ TEST_F(LockStateControllerTest, ShutdownWhenNotLoggedIn) {
}
// Test that we lock the screen and deal with unlocking correctly.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_LockAndUnlock) {
+TEST_F(LockStateControllerTest, LockAndUnlock) {
Initialize(false, user::LOGGED_IN_USER);
ExpectUnlockedState();
@@ -522,23 +477,23 @@ TEST_F(LockStateControllerTest, DISABLED_LockAndUnlock) {
ExpectPreLockAnimationStarted();
EXPECT_TRUE(test_api_->is_lock_cancellable());
- EXPECT_EQ(0, delegate_->num_lock_requests());
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
- Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
+ test_animator_->CompleteAllAnimations(true);
ExpectPreLockAnimationFinished();
- EXPECT_EQ(1, delegate_->num_lock_requests());
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
// Notify that we locked successfully.
lock_state_controller_->OnStartingLock();
// We had that animation already.
- //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
+ EXPECT_EQ(0u, test_animator_->GetAnimationCount());
SystemLocks();
ExpectPostLockAnimationStarted();
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
- ExpectPastLockAnimationFinished();
+ test_animator_->CompleteAllAnimations(true);
+ ExpectPostLockAnimationFinished();
// When we release the power button, the lock-to-shutdown timer should be
// stopped.
@@ -555,7 +510,7 @@ TEST_F(LockStateControllerTest, DISABLED_LockAndUnlock) {
ExpectUnlockBeforeUIDestroyedAnimationStarted();
EXPECT_FALSE(called);
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ test_animator_->CompleteAllAnimations(true);
ExpectUnlockBeforeUIDestroyedAnimationFinished();
EXPECT_TRUE(called);
@@ -563,15 +518,14 @@ TEST_F(LockStateControllerTest, DISABLED_LockAndUnlock) {
SystemUnlocks();
ExpectUnlockAfterUIDestroyedAnimationStarted();
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ test_animator_->CompleteAllAnimations(true);
ExpectUnlockAfterUIDestroyedAnimationFinished();
ExpectUnlockedState();
}
// Test that we deal with cancelling lock correctly.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_LockAndCancel) {
+TEST_F(LockStateControllerTest, LockAndCancel) {
Initialize(false, user::LOGGED_IN_USER);
ExpectUnlockedState();
@@ -586,28 +540,18 @@ TEST_F(LockStateControllerTest, DISABLED_LockAndCancel) {
// forward only half way through
AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
- gfx::Transform transform_before_button_released =
- GetContainer(kShellWindowId_DefaultContainer)->layer()->transform();
-
// Release the button before the lock timer fires.
ReleasePowerButton();
ExpectPreLockAnimationCancel();
- gfx::Transform transform_after_button_released =
- GetContainer(kShellWindowId_DefaultContainer)->layer()->transform();
- // Expect no flickering, animation should proceed from mid-state.
- EXPECT_EQ(transform_before_button_released, transform_after_button_released);
-
Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
ExpectUnlockedState();
- EXPECT_EQ(0, delegate_->num_lock_requests());
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
}
// Test that we deal with cancelling lock correctly.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest,
- DISABLED_LockAndCancelAndLockAgain) {
+TEST_F(LockStateControllerTest, LockAndCancelAndLockAgain) {
Initialize(false, user::LOGGED_IN_USER);
ExpectUnlockedState();
@@ -626,7 +570,8 @@ TEST_F(LockStateControllerTest,
ReleasePowerButton();
ExpectPreLockAnimationCancel();
- AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, 0.5f);
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
+ 0.5f);
PressPowerButton();
ExpectPreLockAnimationStarted();
@@ -634,17 +579,15 @@ TEST_F(LockStateControllerTest,
AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);
- EXPECT_EQ(0, delegate_->num_lock_requests());
- ExpectPreLockAnimationStarted();
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);
ExpectPreLockAnimationFinished();
- EXPECT_EQ(1, delegate_->num_lock_requests());
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
}
// Hold the power button down from the unlocked state to eventual shutdown.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_LockToShutdown) {
+TEST_F(LockStateControllerTest, LockToShutdown) {
Initialize(false, user::LOGGED_IN_USER);
// Hold the power button and lock the screen.
@@ -699,13 +642,11 @@ TEST_F(LockStateControllerTest, CancelLockToShutdown) {
EXPECT_FALSE(test_api_->shutdown_timer_is_running());
}
+// TODO(bruthig): Investigate why this hangs on Windows 8 and whether it can be
+// safely enabled on OS_WIN.
+#ifndef OS_WIN
// Test that we handle the case where lock requests are ignored.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_Lock) {
- // We require animations to have a duration for this test.
- ui::ScopedAnimationDurationScaleMode normal_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
-
+TEST_F(LockStateControllerTest, Lock) {
Initialize(false, user::LOGGED_IN_USER);
// Hold the power button and lock the screen.
@@ -714,20 +655,16 @@ TEST_F(LockStateControllerTest, DISABLED_Lock) {
Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
- EXPECT_EQ(1, delegate_->num_lock_requests());
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
EXPECT_TRUE(test_api_->lock_fail_timer_is_running());
// We shouldn't start the lock-to-shutdown timer until the screen has actually
// been locked and this was animated.
EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
- // Act as if the request timed out. We should restore the windows.
- test_api_->trigger_lock_fail_timeout();
-
- ExpectUnlockAfterUIDestroyedAnimationStarted();
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
- ExpectUnlockAfterUIDestroyedAnimationFinished();
- ExpectUnlockedState();
+ // Act as if the request timed out.
+ EXPECT_DEATH(test_api_->trigger_lock_fail_timeout(), "");
}
+#endif
// Test the basic operation of the lock button (not logged in).
TEST_F(LockStateControllerTest, LockButtonBasicNotLoggedIn) {
@@ -737,7 +674,7 @@ TEST_F(LockStateControllerTest, LockButtonBasicNotLoggedIn) {
PressLockButton();
EXPECT_FALSE(test_api_->is_animating_lock());
ReleaseLockButton();
- EXPECT_EQ(0, delegate_->num_lock_requests());
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
}
// Test the basic operation of the lock button (guest).
@@ -748,12 +685,11 @@ TEST_F(LockStateControllerTest, LockButtonBasicGuest) {
PressLockButton();
EXPECT_FALSE(test_api_->is_animating_lock());
ReleaseLockButton();
- EXPECT_EQ(0, delegate_->num_lock_requests());
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
}
// Test the basic operation of the lock button.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_LockButtonBasic) {
+TEST_F(LockStateControllerTest, LockButtonBasic) {
// If we're logged in as a regular user, we should start the lock timer and
// the pre-lock animation.
Initialize(false, user::LOGGED_IN_USER);
@@ -768,14 +704,14 @@ TEST_F(LockStateControllerTest, DISABLED_LockButtonBasic) {
Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
ExpectUnlockedState();
- EXPECT_EQ(0, delegate_->num_lock_requests());
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
// Press the button again and let the lock timeout fire. We should request
// that the screen be locked.
PressLockButton();
ExpectPreLockAnimationStarted();
Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
- EXPECT_EQ(1, delegate_->num_lock_requests());
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
// Pressing the lock button while we have a pending lock request shouldn't do
// anything.
@@ -793,30 +729,34 @@ TEST_F(LockStateControllerTest, DISABLED_LockButtonBasic) {
ExpectPostLockAnimationStarted();
Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
- ExpectPastLockAnimationFinished();
+ ExpectPostLockAnimationFinished();
PressLockButton();
ReleaseLockButton();
- ExpectPastLockAnimationFinished();
+ ExpectPostLockAnimationFinished();
}
// Test that the power button takes priority over the lock button.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest,
- DISABLED_PowerButtonPreemptsLockButton) {
+TEST_F(LockStateControllerTest, PowerButtonPreemptsLockButton) {
Initialize(false, user::LOGGED_IN_USER);
// While the lock button is down, hold the power button.
PressLockButton();
ExpectPreLockAnimationStarted();
+
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.1f);
+ ExpectPreLockAnimationRunning();
+
PressPowerButton();
- ExpectPreLockAnimationStarted();
+ ExpectPreLockAnimationRunning();
- AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.1f);
+ ExpectPreLockAnimationRunning();
// The lock timer shouldn't be stopped when the lock button is released.
ReleaseLockButton();
- ExpectPreLockAnimationStarted();
+ ExpectPreLockAnimationRunning();
+
ReleasePowerButton();
ExpectPreLockAnimationCancel();
@@ -826,14 +766,20 @@ TEST_F(LockStateControllerTest,
// Now press the power button first and then the lock button.
PressPowerButton();
ExpectPreLockAnimationStarted();
+
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.1f);
+
PressLockButton();
- ExpectPreLockAnimationStarted();
+ ExpectPreLockAnimationRunning();
- AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.1f);
// Releasing the power button should stop the lock timer.
ReleasePowerButton();
ExpectPreLockAnimationCancel();
+
+ AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.1f);
+
ReleaseLockButton();
ExpectPreLockAnimationCancel();
}
@@ -847,10 +793,10 @@ TEST_F(LockStateControllerTest, LockWithoutButton) {
ExpectPreLockAnimationStarted();
EXPECT_FALSE(test_api_->is_lock_cancellable());
+ EXPECT_LT(0u, test_animator_->GetAnimationCount());
- // TODO(antrim): After time-faking is fixed, let the pre-lock animation
- // complete here and check that delegate_->num_lock_requests() is 0 to
- // prevent http://crbug.com/172487 from regressing.
+ test_animator_->CompleteAllAnimations(true);
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
}
// When we hear that the process is exiting but we haven't had a chance to
@@ -860,8 +806,8 @@ TEST_F(LockStateControllerTest, ShutdownWithoutButton) {
lock_state_controller_->OnAppTerminating();
EXPECT_TRUE(
- animator_api_->ContainersAreAnimated(
- SessionStateAnimator::kAllContainersMask,
+ test_animator_->AreContainersAnimated(
+ SessionStateAnimator::kAllNonRootContainersMask,
SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
GenerateMouseMoveEvent();
EXPECT_FALSE(cursor_visible());
@@ -871,7 +817,6 @@ TEST_F(LockStateControllerTest, ShutdownWithoutButton) {
// outside request to shut down (e.g. from the login or lock screen).
TEST_F(LockStateControllerTest, RequestShutdownFromLoginScreen) {
Initialize(false, user::LOGGED_IN_NONE);
- CreateWindowForLockscreen();
lock_state_controller_->RequestShutdown();
@@ -891,9 +836,9 @@ TEST_F(LockStateControllerTest, RequestShutdownFromLockScreen) {
Initialize(false, user::LOGGED_IN_USER);
SystemLocks();
- CreateWindowForLockscreen();
+
Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
- ExpectPastLockAnimationFinished();
+ ExpectPostLockAnimationFinished();
lock_state_controller_->RequestShutdown();
@@ -909,9 +854,7 @@ TEST_F(LockStateControllerTest, RequestShutdownFromLockScreen) {
EXPECT_EQ(1, NumShutdownRequests());
}
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest,
- DISABLED_RequestAndCancelShutdownFromLockScreen) {
+TEST_F(LockStateControllerTest, RequestAndCancelShutdownFromLockScreen) {
Initialize(false, user::LOGGED_IN_USER);
SystemLocks();
@@ -927,9 +870,6 @@ TEST_F(LockStateControllerTest,
AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);
- float grayscale_before_button_release =
- Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();
-
// Release the power button before the shutdown timer fires.
ReleasePowerButton();
@@ -937,12 +877,7 @@ TEST_F(LockStateControllerTest,
ExpectShutdownAnimationCancel();
- float grayscale_after_button_release =
- Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();
- // Expect no flickering in undo animation.
- EXPECT_EQ(grayscale_before_button_release, grayscale_after_button_release);
-
- Advance(SessionStateAnimator::ANIMATION_SPEED_REVERT);
+ Advance(SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
ExpectLockedState();
}
@@ -952,14 +887,14 @@ TEST_F(LockStateControllerTest, IgnorePowerButtonIfScreenIsOff) {
// When the screen brightness is at 0%, we shouldn't do anything in response
// to power button presses.
- controller_->OnScreenBrightnessChanged(0.0);
+ power_button_controller_->OnScreenBrightnessChanged(0.0);
PressPowerButton();
EXPECT_FALSE(test_api_->is_animating_lock());
ReleasePowerButton();
// After increasing the brightness to 10%, we should start the timer like
// usual.
- controller_->OnScreenBrightnessChanged(10.0);
+ power_button_controller_->OnScreenBrightnessChanged(10.0);
PressPowerButton();
EXPECT_TRUE(test_api_->is_animating_lock());
ReleasePowerButton();
@@ -988,12 +923,12 @@ TEST_F(LockStateControllerTest, HonorPowerButtonInDockedMode) {
// When all of the displays are turned off (e.g. due to user inactivity), the
// power button should be ignored.
- controller_->OnScreenBrightnessChanged(0.0);
+ power_button_controller_->OnScreenBrightnessChanged(0.0);
static_cast<ui::TestDisplaySnapshot*>(outputs[0].display)
->set_current_mode(NULL);
static_cast<ui::TestDisplaySnapshot*>(outputs[1].display)
->set_current_mode(NULL);
- controller_->OnDisplayModeChanged(outputs);
+ power_button_controller_->OnDisplayModeChanged(outputs);
PressPowerButton();
EXPECT_FALSE(test_api_->is_animating_lock());
ReleasePowerButton();
@@ -1003,7 +938,7 @@ TEST_F(LockStateControllerTest, HonorPowerButtonInDockedMode) {
// brightness to 0%), the power button should still be handled.
static_cast<ui::TestDisplaySnapshot*>(outputs[1].display)
->set_current_mode(modes[0]);
- controller_->OnDisplayModeChanged(outputs);
+ power_button_controller_->OnDisplayModeChanged(outputs);
PressPowerButton();
EXPECT_TRUE(test_api_->is_animating_lock());
ReleasePowerButton();
@@ -1011,17 +946,14 @@ TEST_F(LockStateControllerTest, HonorPowerButtonInDockedMode) {
#endif
// Test that hidden background appears and revers correctly on lock/cancel.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockCancel) {
+TEST_F(LockStateControllerTest, TestHiddenBackgroundLockCancel) {
Initialize(false, user::LOGGED_IN_USER);
HideBackground();
- EXPECT_TRUE(IsBackgroundHidden());
ExpectUnlockedState();
PressPowerButton();
ExpectPreLockAnimationStarted();
- EXPECT_FALSE(IsBackgroundHidden());
ExpectBackgroundIsShowing();
// Forward only half way through.
@@ -1031,21 +963,23 @@ TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockCancel) {
ReleasePowerButton();
ExpectPreLockAnimationCancel();
ExpectBackgroundIsHiding();
- EXPECT_FALSE(IsBackgroundHidden());
- Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+ Advance(SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
+
+ // When the CancelPrelockAnimation sequence finishes it queues up a
+ // restore background visibilty sequence when the background is hidden.
+ ExpectRestoringBackgroundVisibility();
+
+ Advance(SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
ExpectUnlockedState();
- EXPECT_TRUE(IsBackgroundHidden());
}
// Test that hidden background appears and revers correctly on lock/unlock.
-// TODO(antrim): Reenable this: http://crbug.com/167048
-TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockUnlock) {
+TEST_F(LockStateControllerTest, TestHiddenBackgroundLockUnlock) {
Initialize(false, user::LOGGED_IN_USER);
HideBackground();
- EXPECT_TRUE(IsBackgroundHidden());
ExpectUnlockedState();
// Press the power button and check that the lock timer is started and that we
@@ -1053,7 +987,6 @@ TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockUnlock) {
PressPowerButton();
ExpectPreLockAnimationStarted();
- EXPECT_FALSE(IsBackgroundHidden());
ExpectBackgroundIsShowing();
Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
@@ -1066,7 +999,7 @@ TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockUnlock) {
ExpectPostLockAnimationStarted();
Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
- ExpectPastLockAnimationFinished();
+ ExpectPostLockAnimationFinished();
ExpectLockedState();
@@ -1080,14 +1013,104 @@ TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockUnlock) {
ExpectUnlockAfterUIDestroyedAnimationStarted();
ExpectBackgroundIsHiding();
- EXPECT_FALSE(IsBackgroundHidden());
Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
+
+ // When the StartUnlockAnimationAfterUIDestroyed sequence finishes it queues
+ // up a restore background visibilty sequence when the background is hidden.
+ ExpectRestoringBackgroundVisibility();
+
+ Advance(SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
+
ExpectUnlockAfterUIDestroyedAnimationFinished();
- EXPECT_TRUE(IsBackgroundHidden());
ExpectUnlockedState();
}
+TEST_F(LockStateControllerTest, Screenshot) {
+ test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
+ delegate->set_can_take_screenshot(true);
+
+ EnableMaximizeMode(false);
+
+ // Screenshot handling should not be active when not in maximize mode.
+ ASSERT_EQ(0, delegate->handle_take_screenshot_count());
+ PressVolumeDown();
+ PressPowerButton();
+ ReleasePowerButton();
+ ReleaseVolumeDown();
+ EXPECT_EQ(0, delegate->handle_take_screenshot_count());
+
+ EnableMaximizeMode(true);
+
+ // Pressing power alone does not take a screenshot.
+ PressPowerButton();
+ ReleasePowerButton();
+ EXPECT_EQ(0, delegate->handle_take_screenshot_count());
+
+ // Press & release volume then pressing power does not take a screenshot.
+ ASSERT_EQ(0, delegate->handle_take_screenshot_count());
+ PressVolumeDown();
+ ReleaseVolumeDown();
+ PressPowerButton();
+ ReleasePowerButton();
+ EXPECT_EQ(0, delegate->handle_take_screenshot_count());
+
+ // Pressing power and then volume does not take a screenshot.
+ ASSERT_EQ(0, delegate->handle_take_screenshot_count());
+ PressPowerButton();
+ ReleasePowerButton();
+ PressVolumeDown();
+ ReleaseVolumeDown();
+ EXPECT_EQ(0, delegate->handle_take_screenshot_count());
+
+ // Holding volume down and pressing power takes a screenshot.
+ ASSERT_EQ(0, delegate->handle_take_screenshot_count());
+ PressVolumeDown();
+ PressPowerButton();
+ ReleasePowerButton();
+ ReleaseVolumeDown();
+ EXPECT_EQ(1, delegate->handle_take_screenshot_count());
+}
+
+// Tests that a lock action is cancellable when quick lock is turned on and
+// maximize mode is not active.
+TEST_F(LockStateControllerTest, QuickLockWhileNotInMaximizeMode) {
+ Initialize(false, user::LOGGED_IN_USER);
+ power_button_controller_->set_enable_quick_lock_for_test(true);
+ EnableMaximizeMode(false);
+
+ PressPowerButton();
+
+ ExpectPreLockAnimationStarted();
+ EXPECT_TRUE(test_api_->is_animating_lock());
+ EXPECT_TRUE(lock_state_controller_->CanCancelLockAnimation());
+
+ ReleasePowerButton();
+
+ EXPECT_EQ(0, lock_state_controller_delegate_->num_lock_requests());
+}
+
+// Tests that a lock action is not cancellable when quick lock is turned on and
+// maximize mode is active.
+TEST_F(LockStateControllerTest, QuickLockWhileInMaximizeMode) {
+ Initialize(false, user::LOGGED_IN_USER);
+ power_button_controller_->set_enable_quick_lock_for_test(true);
+ EnableMaximizeMode(true);
+
+ PressPowerButton();
+
+ ExpectPreLockAnimationStarted();
+ EXPECT_TRUE(test_api_->is_animating_lock());
+ EXPECT_FALSE(lock_state_controller_->CanCancelLockAnimation());
+
+ ReleasePowerButton();
+
+ ExpectPreLockAnimationStarted();
+
+ test_animator_->CompleteAllAnimations(true);
+ EXPECT_EQ(1, lock_state_controller_delegate_->num_lock_requests());
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc
index 663dcfc..dc78d28 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -19,7 +19,6 @@
#include "base/time/tick_clock.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/events/event.h"
-#include "ui/events/event_handler.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/vector3d_f.h"
@@ -113,47 +112,6 @@ float ClockwiseAngleBetweenVectorsInDegrees(const gfx::Vector3dF& base,
return angle;
}
-#if defined(OS_CHROMEOS)
-
-// An event handler which listens for a volume down + power keypress and
-// triggers a screenshot when this is seen.
-class ScreenshotActionHandler : public ui::EventHandler {
- public:
- ScreenshotActionHandler();
- virtual ~ScreenshotActionHandler();
-
- // ui::EventHandler:
- virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
-
- private:
- bool volume_down_pressed_;
-
- DISALLOW_COPY_AND_ASSIGN(ScreenshotActionHandler);
-};
-
-ScreenshotActionHandler::ScreenshotActionHandler()
- : volume_down_pressed_(false) {
- Shell::GetInstance()->PrependPreTargetHandler(this);
-}
-
-ScreenshotActionHandler::~ScreenshotActionHandler() {
- Shell::GetInstance()->RemovePreTargetHandler(this);
-}
-
-void ScreenshotActionHandler::OnKeyEvent(ui::KeyEvent* event) {
- if (event->key_code() == ui::VKEY_VOLUME_DOWN) {
- volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED ||
- event->type() == ui::ET_TRANSLATED_KEY_PRESS;
- } else if (volume_down_pressed_ &&
- event->key_code() == ui::VKEY_POWER &&
- event->type() == ui::ET_KEY_PRESSED) {
- Shell::GetInstance()->accelerator_controller()->PerformAction(
- ash::TAKE_SCREENSHOT, ui::Accelerator());
- }
-}
-
-#endif // OS_CHROMEOS
-
} // namespace
MaximizeModeController::MaximizeModeController()
@@ -447,9 +405,6 @@ void MaximizeModeController::EnterMaximizeMode() {
#if defined(USE_X11)
event_blocker_.reset(new ScopedDisableInternalMouseAndKeyboardX11);
#endif
-#if defined(OS_CHROMEOS)
- event_handler_.reset(new ScreenshotActionHandler);
-#endif
Shell::GetInstance()->display_controller()->AddObserver(this);
}
@@ -467,7 +422,6 @@ void MaximizeModeController::LeaveMaximizeMode() {
SetRotationLocked(false);
EnableMaximizeModeWindowManager(false);
event_blocker_.reset();
- event_handler_.reset();
Shell::GetInstance()->display_controller()->RemoveObserver(this);
}
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h
index 76199b7..d8fe9ca 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.h
+++ b/ash/wm/maximize_mode/maximize_mode_controller.h
@@ -175,9 +175,6 @@ class ASH_EXPORT MaximizeModeController
// internal keyboard and touchpad.
scoped_ptr<ScopedDisableInternalMouseAndKeyboard> event_blocker_;
- // An event handler used to detect screenshot actions while in maximize mode.
- scoped_ptr<ui::EventHandler> event_handler_;
-
// When true calls to OnAccelerometerUpdated will not rotate the display.
bool rotation_locked_;
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index 3996579..72e17af 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -12,8 +12,6 @@
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/display_manager_test_api.h"
-#include "ash/test/test_lock_state_controller_delegate.h"
-#include "ash/test/test_screenshot_delegate.h"
#include "ash/test/test_system_tray_delegate.h"
#include "ash/test/test_volume_control_delegate.h"
#include "base/test/simple_test_tick_clock.h"
@@ -411,34 +409,6 @@ TEST_F(MaximizeModeControllerTest, RotationOnlyInMaximizeMode) {
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
}
-#if defined(OS_CHROMEOS)
-// Tests that a screenshot can be taken in maximize mode by holding volume down
-// and pressing power.
-TEST_F(MaximizeModeControllerTest, Screenshot) {
- Shell::GetInstance()->lock_state_controller()->SetDelegate(
- new test::TestLockStateControllerDelegate);
- aura::Window* root = Shell::GetPrimaryRootWindow();
- ui::test::EventGenerator event_generator(root, root);
- test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
- delegate->set_can_take_screenshot(true);
-
- // Open up 270 degrees.
- OpenLidToAngle(270.0f);
- ASSERT_TRUE(IsMaximizeModeStarted());
-
- // Pressing power alone does not take a screenshot.
- event_generator.PressKey(ui::VKEY_POWER, 0);
- event_generator.ReleaseKey(ui::VKEY_POWER, 0);
- EXPECT_EQ(0, delegate->handle_take_screenshot_count());
-
- // Holding volume down and pressing power takes a screenshot.
- event_generator.PressKey(ui::VKEY_VOLUME_DOWN, 0);
- event_generator.PressKey(ui::VKEY_POWER, 0);
- event_generator.ReleaseKey(ui::VKEY_POWER, 0);
- EXPECT_EQ(1, delegate->handle_take_screenshot_count());
- event_generator.ReleaseKey(ui::VKEY_VOLUME_DOWN, 0);
-}
-#endif // OS_CHROMEOS
TEST_F(MaximizeModeControllerTest, LaptopTest) {
// Feeds in sample accelerometer data and verifies that there are no
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index 6e96c65..990e573 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -9,10 +9,12 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/lock_state_controller.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/session_state_animator.h"
#include "base/command_line.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/display/types/chromeos/display_snapshot.h"
+#include "ui/events/event_handler.h"
#include "ui/wm/core/compound_event_filter.h"
namespace ash {
@@ -21,21 +23,26 @@ PowerButtonController::PowerButtonController(
LockStateController* controller)
: power_button_down_(false),
lock_button_down_(false),
+ volume_down_pressed_(false),
brightness_is_zero_(false),
internal_display_off_and_external_display_on_(false),
has_legacy_power_button_(
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAuraLegacyPowerButton)),
+ enable_quick_lock_(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAshEnablePowerButtonQuickLock)),
controller_(controller) {
#if defined(OS_CHROMEOS)
Shell::GetInstance()->display_configurator()->AddObserver(this);
#endif
+ Shell::GetInstance()->PrependPreTargetHandler(this);
}
PowerButtonController::~PowerButtonController() {
#if defined(OS_CHROMEOS)
Shell::GetInstance()->display_configurator()->RemoveObserver(this);
#endif
+ Shell::GetInstance()->RemovePreTargetHandler(this);
}
void PowerButtonController::OnScreenBrightnessChanged(double percent) {
@@ -55,6 +62,14 @@ void PowerButtonController::OnPowerButtonEvent(
if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
return;
+ if (volume_down_pressed_ && down &&
+ Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled()) {
+ Shell::GetInstance()->accelerator_controller()->PerformAction(
+ ash::TAKE_SCREENSHOT, ui::Accelerator());
+ return;
+ }
+
const SessionStateDelegate* session_state_delegate =
Shell::GetInstance()->session_state_delegate();
if (has_legacy_power_button_) {
@@ -65,7 +80,7 @@ void PowerButtonController::OnPowerButtonEvent(
if (session_state_delegate->CanLockScreen() &&
!session_state_delegate->IsScreenLocked() &&
!controller_->LockRequested()) {
- controller_->StartLockAnimationAndLockImmediately();
+ controller_->StartLockAnimationAndLockImmediately(false);
} else {
controller_->RequestShutdown();
}
@@ -78,7 +93,11 @@ void PowerButtonController::OnPowerButtonEvent(
if (session_state_delegate->CanLockScreen() &&
!session_state_delegate->IsScreenLocked()) {
- controller_->StartLockAnimation(true);
+ if (Shell::GetInstance()->maximize_mode_controller()->
+ IsMaximizeModeWindowManagerEnabled() && enable_quick_lock_)
+ controller_->StartLockAnimationAndLockImmediately(true);
+ else
+ controller_->StartLockAnimation(true);
} else {
controller_->StartShutdownAnimation();
}
@@ -104,9 +123,7 @@ void PowerButtonController::OnLockButtonEvent(
return;
}
- // Give the power button precedence over the lock button (we don't expect both
- // buttons to be present, so this is just making sure that we don't do
- // something completely stupid if that assumption changes later).
+ // Give the power button precedence over the lock button.
if (power_button_down_)
return;
@@ -116,6 +133,13 @@ void PowerButtonController::OnLockButtonEvent(
controller_->CancelLockAnimation();
}
+void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
+ if (event->key_code() == ui::VKEY_VOLUME_DOWN) {
+ volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED ||
+ event->type() == ui::ET_TRANSLATED_KEY_PRESS;
+ }
+}
+
#if defined(OS_CHROMEOS)
void PowerButtonController::OnDisplayModeChanged(
const ui::DisplayConfigurator::DisplayStateList& display_states) {
diff --git a/ash/wm/power_button_controller.h b/ash/wm/power_button_controller.h
index f178014..6511a5f 100644
--- a/ash/wm/power_button_controller.h
+++ b/ash/wm/power_button_controller.h
@@ -5,9 +5,13 @@
#ifndef ASH_WM_POWER_BUTTON_CONTROLLER_H_
#define ASH_WM_POWER_BUTTON_CONTROLLER_H_
+#include "ash/accelerators/accelerator_controller.h"
+#include "ash/accelerators/accelerator_table.h"
#include "ash/ash_export.h"
#include "ash/wm/session_state_animator.h"
#include "base/basictypes.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/events/event_handler.h"
#if defined(OS_CHROMEOS)
#include "ui/display/chromeos/display_configurator.h"
@@ -30,13 +34,14 @@ class PowerButtonControllerTest;
class LockStateController;
-// Displays onscreen animations and locks or suspends the system in response to
-// the power button being pressed or released.
-class ASH_EXPORT PowerButtonController
+// Handles power & lock button events which may result in the locking or
+// shutting down of the system as well as taking screen shots while in maximize
+// mode.
+class ASH_EXPORT PowerButtonController : ui::EventHandler
// TODO(derat): Remove these ifdefs after DisplayConfigurator becomes
// cross-platform.
#if defined(OS_CHROMEOS)
- : public ui::DisplayConfigurator::Observer
+ , public ui::DisplayConfigurator::Observer
#endif
{
public:
@@ -47,6 +52,10 @@ class ASH_EXPORT PowerButtonController
has_legacy_power_button_ = legacy;
}
+ void set_enable_quick_lock_for_test(bool enable_quick_lock) {
+ enable_quick_lock_ = enable_quick_lock;
+ }
+
// Called when the current screen brightness changes.
void OnScreenBrightnessChanged(double percent);
@@ -54,6 +63,9 @@ class ASH_EXPORT PowerButtonController
void OnPowerButtonEvent(bool down, const base::TimeTicks& timestamp);
void OnLockButtonEvent(bool down, const base::TimeTicks& timestamp);
+ // ui::EventHandler:
+ virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
+
#if defined(OS_CHROMEOS)
// Overriden from ui::DisplayConfigurator::Observer:
virtual void OnDisplayModeChanged(
@@ -67,6 +79,9 @@ class ASH_EXPORT PowerButtonController
bool power_button_down_;
bool lock_button_down_;
+ // True when the volume down button is being held down.
+ bool volume_down_pressed_;
+
// Has the screen brightness been reduced to 0%?
bool brightness_is_zero_;
@@ -79,7 +94,10 @@ class ASH_EXPORT PowerButtonController
// that misreports power button releases?
bool has_legacy_power_button_;
- LockStateController* controller_; // Not owned.
+ // Enables quick, non-cancellable locking of the screen when in maximize mode.
+ bool enable_quick_lock_;
+
+ LockStateController* controller_; // Not owned.
DISALLOW_COPY_AND_ASSIGN(PowerButtonController);
};
diff --git a/ash/wm/session_state_animator.cc b/ash/wm/session_state_animator.cc
index 9900275..009f88e 100644
--- a/ash/wm/session_state_animator.cc
+++ b/ash/wm/session_state_animator.cc
@@ -15,415 +15,62 @@
#include "ui/views/widget/widget.h"
namespace ash {
-namespace {
-// Slightly-smaller size that we scale the screen down to for the pre-lock and
-// pre-shutdown states.
-const float kSlowCloseSizeRatio = 0.95f;
-
-// Maximum opacity of white layer when animating pre-shutdown state.
-const float kPartialFadeRatio = 0.3f;
-
-// Minimum size. Not zero as it causes numeric issues.
-const float kMinimumScale = 1e-4f;
-
-// Returns the transform that should be applied to containers for the slow-close
-// animation.
-gfx::Transform GetSlowCloseTransform() {
- gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
- gfx::Transform transform;
- transform.Translate(
- floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
- floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
- transform.Scale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
- return transform;
-}
-
-// Returns the transform that should be applied to containers for the fast-close
-// animation.
-gfx::Transform GetFastCloseTransform() {
- gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
- gfx::Transform transform;
- transform.Translate(floor(0.5 * root_size.width() + 0.5),
- floor(0.5 * root_size.height() + 0.5));
- transform.Scale(kMinimumScale, kMinimumScale);
- return transform;
-}
-
-// Slowly shrinks |window| to a slightly-smaller size.
-void StartSlowCloseAnimationForWindow(aura::Window* window,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateTransformElement(
- GetSlowCloseTransform(),
- duration));
- if (observer)
- sequence->AddObserver(observer);
- animator->StartAnimation(sequence);
-}
-
-// Quickly undoes the effects of the slow-close animation on |window|.
-void StartUndoSlowCloseAnimationForWindow(
- aura::Window* window,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateTransformElement(
- gfx::Transform(),
- duration));
- if (observer)
- sequence->AddObserver(observer);
- animator->StartAnimation(sequence);
-}
+const int SessionStateAnimator::kAllLockScreenContainersMask =
+ SessionStateAnimator::LOCK_SCREEN_BACKGROUND |
+ SessionStateAnimator::LOCK_SCREEN_CONTAINERS |
+ SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS;
-// Quickly shrinks |window| down to a point in the center of the screen and
-// fades it out to 0 opacity.
-void StartFastCloseAnimationForWindow(aura::Window* window,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- animator->StartAnimation(
- new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateTransformElement(
- GetFastCloseTransform(), duration)));
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(0.0, duration));
- if (observer)
- sequence->AddObserver(observer);
- animator->StartAnimation(sequence);
-}
+const int SessionStateAnimator::kAllNonRootContainersMask =
+ SessionStateAnimator::kAllLockScreenContainersMask |
+ SessionStateAnimator::DESKTOP_BACKGROUND |
+ SessionStateAnimator::LAUNCHER |
+ SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS;
-// Fades |window| to |target_opacity| over |duration|.
-void StartPartialFadeAnimation(aura::Window* window,
- float target_opacity,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(
- target_opacity, duration));
- if (observer)
- sequence->AddObserver(observer);
- animator->StartAnimation(sequence);
+SessionStateAnimator::AnimationSequence::AnimationSequence(
+ base::Closure callback)
+ : sequence_ended_(false),
+ animation_completed_(false),
+ invoke_callback_(false),
+ callback_(callback) {
}
-// Fades |window| to |opacity| over |duration|.
-void StartOpacityAnimationForWindow(aura::Window* window,
- float opacity,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(opacity, duration));
- if (observer)
- sequence->AddObserver(observer);
- animator->StartAnimation(sequence);
+SessionStateAnimator::AnimationSequence::~AnimationSequence() {
}
-// Makes |window| fully transparent instantaneously.
-void HideWindowImmediately(aura::Window* window,
- ui::LayerAnimationObserver* observer) {
- window->layer()->SetOpacity(0.0);
- if (observer)
- observer->OnLayerAnimationEnded(NULL);
+void SessionStateAnimator::AnimationSequence::EndSequence() {
+ sequence_ended_ = true;
+ CleanupIfSequenceCompleted();
}
-// Restores |window| to its original position and scale and full opacity
-// instantaneously.
-void RestoreWindow(aura::Window* window, ui::LayerAnimationObserver* observer) {
- window->layer()->SetTransform(gfx::Transform());
- window->layer()->SetOpacity(1.0);
- if (observer)
- observer->OnLayerAnimationEnded(NULL);
+void SessionStateAnimator::AnimationSequence::OnAnimationCompleted() {
+ animation_completed_ = true;
+ invoke_callback_ = true;
+ CleanupIfSequenceCompleted();
}
-void HideWindow(aura::Window* window,
- base::TimeDelta duration,
- bool above,
- ui::LayerAnimationObserver* observer) {
- ui::Layer* layer = window->layer();
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
-
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- settings.SetTransitionDuration(duration);
-
- settings.SetTweenType(gfx::Tween::EASE_OUT);
- SetTransformForScaleAnimation(layer,
- above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
-
- settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
- layer->SetOpacity(0.0f);
-
- // After the animation completes snap the transform back to the identity,
- // otherwise any one that asks for screen bounds gets a slightly scaled
- // version.
- settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
- settings.SetTransitionDuration(base::TimeDelta());
- layer->SetTransform(gfx::Transform());
-
- // A bit of a dirty trick: we need to catch the end of the animation we don't
- // control. So we use two facts we know: which animator will be used and the
- // target opacity to add "Do nothing" animation sequence.
- // Unfortunately, we can not just use empty LayerAnimationSequence, because
- // it does not call NotifyEnded().
- if (observer) {
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(
- 0.0, base::TimeDelta()));
- sequence->AddObserver(observer);
- layer->GetAnimator()->ScheduleAnimation(sequence);
- }
+void SessionStateAnimator::AnimationSequence::OnAnimationAborted() {
+ animation_completed_ = true;
+ invoke_callback_ = false;
+ CleanupIfSequenceCompleted();
}
-// Animates |window| to identity transform and full opacity over |duration|.
-void TransformWindowToBaseState(aura::Window* window,
- base::TimeDelta duration,
- ui::LayerAnimationObserver* observer) {
- ui::Layer* layer = window->layer();
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
-
- // Animate to target values.
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- settings.SetTransitionDuration(duration);
-
- settings.SetTweenType(gfx::Tween::EASE_OUT);
- layer->SetTransform(gfx::Transform());
-
- settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
- layer->SetOpacity(1.0f);
-
- // A bit of a dirty trick: we need to catch the end of the animation we don't
- // control. So we use two facts we know: which animator will be used and the
- // target opacity to add "Do nothing" animation sequence.
- // Unfortunately, we can not just use empty LayerAnimationSequence, because
- // it does not call NotifyEnded().
- if (observer) {
- ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(
- 1.0, base::TimeDelta()));
- sequence->AddObserver(observer);
- layer->GetAnimator()->ScheduleAnimation(sequence);
- }
-}
-
-void ShowWindow(aura::Window* window,
- base::TimeDelta duration,
- bool above,
- ui::LayerAnimationObserver* observer) {
- ui::Layer* layer = window->layer();
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
-
- // Set initial state of animation
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- settings.SetTransitionDuration(base::TimeDelta());
- SetTransformForScaleAnimation(layer,
- above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
-
- TransformWindowToBaseState(window, duration, observer);
-}
-
-// Starts grayscale/brightness animation for |window| over |duration|. Target
-// value for both grayscale and brightness are specified by |target|.
-void StartGrayscaleBrightnessAnimationForWindow(
- aura::Window* window,
- float target,
- base::TimeDelta duration,
- gfx::Tween::Type tween_type,
- ui::LayerAnimationObserver* observer) {
- ui::LayerAnimator* animator = window->layer()->GetAnimator();
-
- scoped_ptr<ui::LayerAnimationSequence> brightness_sequence(
- new ui::LayerAnimationSequence());
- scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence(
- new ui::LayerAnimationSequence());
-
- scoped_ptr<ui::LayerAnimationElement> brightness_element(
- ui::LayerAnimationElement::CreateBrightnessElement(
- target, duration));
- brightness_element->set_tween_type(tween_type);
- brightness_sequence->AddElement(brightness_element.release());
-
- scoped_ptr<ui::LayerAnimationElement> grayscale_element(
- ui::LayerAnimationElement::CreateGrayscaleElement(
- target, duration));
- grayscale_element->set_tween_type(tween_type);
- grayscale_sequence->AddElement(grayscale_element.release());
-
- std::vector<ui::LayerAnimationSequence*> animations;
- animations.push_back(brightness_sequence.release());
- animations.push_back(grayscale_sequence.release());
-
- if (observer)
- animations[0]->AddObserver(observer);
-
- animator->set_preemption_strategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
-
- animator->StartTogether(animations);
-}
-
-// Animation observer that will drop animated foreground once animation is
-// finished. It is used in when undoing shutdown animation.
-class CallbackAnimationObserver : public ui::LayerAnimationObserver {
- public:
- explicit CallbackAnimationObserver(base::Callback<void(void)> &callback)
- : callback_(callback) {
- }
- virtual ~CallbackAnimationObserver() {
- }
-
- private:
- // Overridden from ui::LayerAnimationObserver:
- virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq)
- OVERRIDE {
- // Drop foreground once animation is over.
- callback_.Run();
- delete this;
- }
-
- virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq)
- OVERRIDE {
- // Drop foreground once animation is over.
- callback_.Run();
+void SessionStateAnimator::AnimationSequence::CleanupIfSequenceCompleted() {
+ if (sequence_ended_ && animation_completed_) {
+ if (invoke_callback_)
+ callback_.Run();
delete this;
}
-
- virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq)
- OVERRIDE {}
-
- base::Callback<void(void)> callback_;
-
- DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver);
-};
-
-
-bool IsLayerAnimated(ui::Layer* layer,
- SessionStateAnimator::AnimationType type) {
- switch (type) {
- case SessionStateAnimator::ANIMATION_PARTIAL_CLOSE:
- if (layer->GetTargetTransform() != GetSlowCloseTransform())
- return false;
- break;
- case SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE:
- if (layer->GetTargetTransform() != gfx::Transform())
- return false;
- break;
- case SessionStateAnimator::ANIMATION_FULL_CLOSE:
- if (layer->GetTargetTransform() != GetFastCloseTransform() ||
- layer->GetTargetOpacity() > 0.0001)
- return false;
- break;
- case SessionStateAnimator::ANIMATION_FADE_IN:
- if (layer->GetTargetOpacity() < 0.9999)
- return false;
- break;
- case SessionStateAnimator::ANIMATION_FADE_OUT:
- if (layer->GetTargetOpacity() > 0.0001)
- return false;
- break;
- case SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY:
- if (layer->GetTargetOpacity() > 0.0001)
- return false;
- break;
- case SessionStateAnimator::ANIMATION_RESTORE:
- if (layer->opacity() < 0.9999 || layer->transform() != gfx::Transform())
- return false;
- break;
- case SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS:
- if ((layer->GetTargetBrightness() < 0.9999) ||
- (layer->GetTargetGrayscale() < 0.9999))
- return false;
- break;
- case SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
- if ((layer->GetTargetBrightness() > 0.0001) ||
- (layer->GetTargetGrayscale() > 0.0001))
- return false;
- break;
- case SessionStateAnimator::ANIMATION_DROP:
- case SessionStateAnimator::ANIMATION_UNDO_LIFT:
- //ToDo(antim) : check other effects
- if (layer->GetTargetOpacity() < 0.9999)
- return false;
- break;
- //ToDo(antim) : check other effects
- case SessionStateAnimator::ANIMATION_LIFT:
- if (layer->GetTargetOpacity() > 0.0001)
- return false;
- break;
- case SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN:
- //ToDo(antim) : check other effects
- if (layer->GetTargetOpacity() < 0.9999)
- return false;
- break;
- //ToDo(antim) : check other effects
- case SessionStateAnimator::ANIMATION_LOWER_BELOW_SCREEN:
- if (layer->GetTargetOpacity() > 0.0001)
- return false;
- break;
- default:
- NOTREACHED() << "Unhandled animation type " << type;
- return false;
- }
- return true;
-}
-
-} // namespace
-
-bool SessionStateAnimator::TestApi::ContainersAreAnimated(
- int container_mask, AnimationType type) const {
- aura::Window::Windows containers;
- animator_->GetContainers(container_mask, &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- aura::Window* window = *it;
- ui::Layer* layer = window->layer();
- if (!IsLayerAnimated(layer, type))
- return false;
- }
- return true;
}
-bool SessionStateAnimator::TestApi::RootWindowIsAnimated(AnimationType type)
- const {
- aura::Window* root_window = Shell::GetPrimaryRootWindow();
- ui::Layer* layer = root_window->layer();
- return IsLayerAnimated(layer, type);
-}
-
-const int SessionStateAnimator::kAllLockScreenContainersMask =
- SessionStateAnimator::LOCK_SCREEN_BACKGROUND |
- SessionStateAnimator::LOCK_SCREEN_CONTAINERS |
- SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS;
-
-const int SessionStateAnimator::kAllContainersMask =
- SessionStateAnimator::kAllLockScreenContainersMask |
- SessionStateAnimator::DESKTOP_BACKGROUND |
- SessionStateAnimator::LAUNCHER |
- SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS;
-
SessionStateAnimator::SessionStateAnimator() {
}
SessionStateAnimator::~SessionStateAnimator() {
}
-base::TimeDelta SessionStateAnimator::GetDuration(AnimationSpeed speed) {
+base::TimeDelta SessionStateAnimator::GetDuration(
+ SessionStateAnimator::AnimationSpeed speed) {
switch (speed) {
case ANIMATION_SPEED_IMMEDIATE:
return base::TimeDelta();
@@ -450,159 +97,4 @@ base::TimeDelta SessionStateAnimator::GetDuration(AnimationSpeed speed) {
return base::TimeDelta();
}
-// Fills |containers| with the containers described by |container_mask|.
-void SessionStateAnimator::GetContainers(int container_mask,
- aura::Window::Windows* containers) {
- aura::Window* root_window = Shell::GetPrimaryRootWindow();
- containers->clear();
-
- if (container_mask & DESKTOP_BACKGROUND) {
- containers->push_back(Shell::GetContainer(
- root_window, kShellWindowId_DesktopBackgroundContainer));
- }
- if (container_mask & LAUNCHER) {
- containers->push_back(
- Shell::GetContainer(root_window, kShellWindowId_ShelfContainer));
- }
- if (container_mask & NON_LOCK_SCREEN_CONTAINERS) {
- // TODO(antrim): Figure out a way to eliminate a need to exclude launcher
- // in such way.
- aura::Window* non_lock_screen_containers = Shell::GetContainer(
- root_window, kShellWindowId_NonLockScreenContainersContainer);
- aura::Window::Windows children = non_lock_screen_containers->children();
-
- for (aura::Window::Windows::const_iterator it = children.begin();
- it != children.end(); ++it) {
- aura::Window* window = *it;
- if (window->id() == kShellWindowId_ShelfContainer)
- continue;
- containers->push_back(window);
- }
- }
- if (container_mask & LOCK_SCREEN_BACKGROUND) {
- containers->push_back(Shell::GetContainer(
- root_window, kShellWindowId_LockScreenBackgroundContainer));
- }
- if (container_mask & LOCK_SCREEN_CONTAINERS) {
- containers->push_back(Shell::GetContainer(
- root_window, kShellWindowId_LockScreenContainersContainer));
- }
- if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) {
- containers->push_back(Shell::GetContainer(
- root_window, kShellWindowId_LockScreenRelatedContainersContainer));
- }
-}
-
-void SessionStateAnimator::StartAnimation(int container_mask,
- AnimationType type,
- AnimationSpeed speed) {
- aura::Window::Windows containers;
- GetContainers(container_mask, &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- RunAnimationForWindow(*it, type, speed, NULL);
- }
-}
-
-void SessionStateAnimator::StartAnimationWithCallback(
- int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- base::Callback<void(void)>& callback) {
- aura::Window::Windows containers;
- GetContainers(container_mask, &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- ui::LayerAnimationObserver* observer =
- new CallbackAnimationObserver(callback);
- RunAnimationForWindow(*it, type, speed, observer);
- }
-}
-
-void SessionStateAnimator::StartAnimationWithObserver(
- int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- ui::LayerAnimationObserver* observer) {
- aura::Window::Windows containers;
- GetContainers(container_mask, &containers);
- for (aura::Window::Windows::const_iterator it = containers.begin();
- it != containers.end(); ++it) {
- RunAnimationForWindow(*it, type, speed, observer);
- }
-}
-
-void SessionStateAnimator::StartGlobalAnimation(AnimationType type,
- AnimationSpeed speed) {
- aura::Window* root_window = Shell::GetPrimaryRootWindow();
- RunAnimationForWindow(root_window, type, speed, NULL);
-}
-
-void SessionStateAnimator::RunAnimationForWindow(
- aura::Window* window,
- AnimationType type,
- AnimationSpeed speed,
- ui::LayerAnimationObserver* observer) {
- base::TimeDelta duration = GetDuration(speed);
-
- switch (type) {
- case ANIMATION_PARTIAL_CLOSE:
- StartSlowCloseAnimationForWindow(window, duration, observer);
- break;
- case ANIMATION_UNDO_PARTIAL_CLOSE:
- StartUndoSlowCloseAnimationForWindow(window, duration, observer);
- break;
- case ANIMATION_FULL_CLOSE:
- StartFastCloseAnimationForWindow(window, duration, observer);
- break;
- case ANIMATION_FADE_IN:
- StartOpacityAnimationForWindow(window, 1.0, duration, observer);
- break;
- case ANIMATION_FADE_OUT:
- StartOpacityAnimationForWindow(window, 0.0, duration, observer);
- break;
- case ANIMATION_HIDE_IMMEDIATELY:
- DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
- HideWindowImmediately(window, observer);
- break;
- case ANIMATION_RESTORE:
- DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
- RestoreWindow(window, observer);
- break;
- case ANIMATION_LIFT:
- HideWindow(window, duration, true, observer);
- break;
- case ANIMATION_DROP:
- ShowWindow(window, duration, true, observer);
- break;
- case ANIMATION_UNDO_LIFT:
- TransformWindowToBaseState(window, duration, observer);
- break;
- case ANIMATION_RAISE_TO_SCREEN:
- ShowWindow(window, duration, false, observer);
- break;
- case ANIMATION_LOWER_BELOW_SCREEN:
- HideWindow(window, duration, false, observer);
- break;
- case ANIMATION_PARTIAL_FADE_IN:
- StartPartialFadeAnimation(
- window, kPartialFadeRatio, duration, observer);
- break;
- case ANIMATION_UNDO_PARTIAL_FADE_IN:
- StartPartialFadeAnimation(window, 0.0, duration, observer);
- break;
- case ANIMATION_FULL_FADE_IN:
- StartPartialFadeAnimation(window, 1.0, duration, observer);
- break;
- case ANIMATION_GRAYSCALE_BRIGHTNESS:
- StartGrayscaleBrightnessAnimationForWindow(
- window, 1.0, duration, gfx::Tween::EASE_IN, observer);
- break;
- case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
- StartGrayscaleBrightnessAnimationForWindow(
- window, 0.0, duration, gfx::Tween::EASE_IN_OUT, observer);
- break;
- }
-}
-
} // namespace ash
diff --git a/ash/wm/session_state_animator.h b/ash/wm/session_state_animator.h
index a9e43db4..b293b47 100644
--- a/ash/wm/session_state_animator.h
+++ b/ash/wm/session_state_animator.h
@@ -7,19 +7,8 @@
#include "ash/ash_export.h"
#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
-#include "ui/aura/window.h"
-#include "ui/compositor/layer_animation_observer.h"
-
-namespace gfx {
-class Rect;
-class Size;
-}
-
-namespace ui {
-class Layer;
-}
+#include "base/callback.h"
+#include "base/time/time.h"
namespace ash {
@@ -98,78 +87,135 @@ class ASH_EXPORT SessionStateAnimator {
// Multiple system layers belong here like status, menu, tooltip
// and overlay layers.
LOCK_SCREEN_RELATED_CONTAINERS = 1 << 5,
+
+ // The primary root window.
+ ROOT_CONTAINER = 1 << 6,
};
- // Helper class used by tests to access internal state.
- class ASH_EXPORT TestApi {
+ // A bitfield mask including LOCK_SCREEN_WALLPAPER,
+ // LOCK_SCREEN_CONTAINERS, and LOCK_SCREEN_RELATED_CONTAINERS.
+ static const int kAllLockScreenContainersMask;
+
+ // A bitfield mask of all containers except the ROOT_CONTAINER.
+ static const int kAllNonRootContainersMask;
+
+ // The AnimationSequence groups together multiple animations and invokes a
+ // callback once all contained animations are completed successfully.
+ // Subclasses of AnimationSequence should call one of OnAnimationCompleted or
+ // OnAnimationAborted once and behaviour is undefined if called multiple
+ // times.
+ // AnimationSequences will destroy themselves once EndSquence and one of
+ // OnAnimationCompleted or OnAnimationAborted has been called.
+ //
+ // Typical usage:
+ // AnimationSequence* animation_sequence =
+ // session_state_animator->BeginAnimationSequence(some_callback);
+ // animation_sequence->StartAnimation(
+ // SessionStateAnimator::LAUNCHER,
+ // SessionStateAnimator::ANIMATION_FADE_IN,
+ // SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
+ // animation_sequence->StartAnimation(
+ // SessionStateAnimator::LAUNCHER,
+ // SessionStateAnimator::ANIMATION_FADE_IN,
+ // SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
+ // animation_sequence->EndSequence();
+ // // some_callback won't be called until here even if the animations
+ // // were completed before the EndSequence call.
+ //
+ class ASH_EXPORT AnimationSequence {
public:
- explicit TestApi(SessionStateAnimator* animator)
- : animator_(animator) {}
+ virtual ~AnimationSequence();
+
+ // Apply animation |type| to all containers included in |container_mask|
+ // with specified |speed|.
+ virtual void StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) = 0;
+
+ // Ends the animation sequence and enables the callback to be invoked
+ // when the animation sequence has completed. No more animations should be
+ // started after EndSequence is called because the AnimationSequenceObserver
+ // may have destroyed itself.
+ // NOTE: Clients of AnimationSequence should not access it after EndSequence
+ // has been called.
+ virtual void EndSequence();
+
+ protected:
+ // AnimationSequence should not be instantiated directly, only through
+ // subclasses.
+ explicit AnimationSequence(base::Closure callback);
+
+ // Subclasses should call this when the contained animations completed
+ // successfully.
+ // NOTE: This should NOT be accessed after OnAnimationCompleted has been
+ // called.
+ virtual void OnAnimationCompleted();
+
+ // Subclasses should call this when the contained animations did NOT
+ // complete successfully.
+ // NOTE: This should NOT be accessed after OnAnimationAborted has been
+ // called.
+ virtual void OnAnimationAborted();
- // Returns true if containers of a given |container_mask|
- // were last animated with |type| (probably; the analysis is fairly ad-hoc).
- // |container_mask| is a bitfield of a Container.
- bool ContainersAreAnimated(int container_mask, AnimationType type) const;
+ private:
+ // Destroys this and calls the callback if the contained animations
+ // completed successfully.
+ void CleanupIfSequenceCompleted();
- // Returns true if root window was last animated with |type| (probably;
- // the analysis is fairly ad-hoc).
- bool RootWindowIsAnimated(AnimationType type) const;
+ // Tracks whether the sequence has ended.
+ bool sequence_ended_;
- private:
- SessionStateAnimator* animator_; // not owned
+ // Track whether the contained animations have completed or not, both
+ // successfully and unsuccessfully.
+ bool animation_completed_;
- DISALLOW_COPY_AND_ASSIGN(TestApi);
- };
+ // Flag to specify whether the callback should be invoked once the sequence
+ // has completed.
+ bool invoke_callback_;
- // A bitfield mask including LOCK_SCREEN_WALLPAPER,
- // LOCK_SCREEN_CONTAINERS, and LOCK_SCREEN_RELATED_CONTAINERS.
- const static int kAllLockScreenContainersMask;
+ // Callback to be called.
+ base::Closure callback_;
- // A bitfield mask of all containers.
- const static int kAllContainersMask;
+ DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
+ };
SessionStateAnimator();
virtual ~SessionStateAnimator();
// Reports animation duration for |speed|.
- static base::TimeDelta GetDuration(AnimationSpeed speed);
-
- // Fills |containers| with the containers included in |container_mask|.
- static void GetContainers(int container_mask,
- aura::Window::Windows* containers);
+ virtual base::TimeDelta GetDuration(AnimationSpeed speed);
// Apply animation |type| to all containers included in |container_mask| with
// specified |speed|.
- void StartAnimation(int container_mask,
- AnimationType type,
- AnimationSpeed speed);
+ virtual void StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) = 0;
// Apply animation |type| to all containers included in |container_mask| with
// specified |speed| and call a |callback| at the end of the animation, if it
// is not null.
- void StartAnimationWithCallback(int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- base::Callback<void(void)>& callback);
-
-// Apply animation |type| to all containers included in |container_mask| with
-// specified |speed| and add |observer| to all animations.
- void StartAnimationWithObserver(int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- ui::LayerAnimationObserver* observer);
-
- // Applies animation |type| whith specified |speed| to the root container.
- void StartGlobalAnimation(AnimationType type,
- AnimationSpeed speed);
-
- // Apply animation |type| to window |window| with |speed| and add |observer|
- // if it is not NULL to the last animation sequence.
- void RunAnimationForWindow(aura::Window* window,
- AnimationType type,
- AnimationSpeed speed,
- ui::LayerAnimationObserver* observer);
+ virtual void StartAnimationWithCallback(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure callback) = 0;
+
+ // Begins an animation sequence. Use this when you need to be notified when
+ // a group of animations are completed. See AnimationSequence documentation
+ // for more details.
+ virtual AnimationSequence* BeginAnimationSequence(
+ base::Closure callback) = 0;
+
+ // Retruns true if the background is hidden.
+ virtual bool IsBackgroundHidden() const = 0;
+
+ // Shows the background immediately.
+ virtual void ShowBackground() = 0;
+
+ // Hides the background immediately.
+ virtual void HideBackground() = 0;
+ private:
DISALLOW_COPY_AND_ASSIGN(SessionStateAnimator);
};
diff --git a/ash/wm/session_state_animator_impl.cc b/ash/wm/session_state_animator_impl.cc
new file mode 100644
index 0000000..4fb0d7b
--- /dev/null
+++ b/ash/wm/session_state_animator_impl.cc
@@ -0,0 +1,669 @@
+// 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/wm/session_state_animator_impl.h"
+
+#include <vector>
+
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/wm/window_animations.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/compositor/layer_animation_sequence.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+namespace {
+
+// Slightly-smaller size that we scale the screen down to for the pre-lock and
+// pre-shutdown states.
+const float kSlowCloseSizeRatio = 0.95f;
+
+// Maximum opacity of white layer when animating pre-shutdown state.
+const float kPartialFadeRatio = 0.3f;
+
+// Minimum size. Not zero as it causes numeric issues.
+const float kMinimumScale = 1e-4f;
+
+// Returns the primary root window's container.
+aura::Window* GetBackground() {
+ aura::Window* root_window = Shell::GetPrimaryRootWindow();
+ return Shell::GetContainer(root_window,
+ kShellWindowId_DesktopBackgroundContainer);
+}
+
+// Returns the transform that should be applied to containers for the slow-close
+// animation.
+gfx::Transform GetSlowCloseTransform() {
+ gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
+ gfx::Transform transform;
+ transform.Translate(
+ floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
+ floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
+ transform.Scale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
+ return transform;
+}
+
+// Returns the transform that should be applied to containers for the fast-close
+// animation.
+gfx::Transform GetFastCloseTransform() {
+ gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
+ gfx::Transform transform;
+
+ transform.Translate(floor(0.5 * root_size.width() + 0.5),
+ floor(0.5 * root_size.height() + 0.5));
+ transform.Scale(kMinimumScale, kMinimumScale);
+ return transform;
+}
+
+// Slowly shrinks |window| to a slightly-smaller size.
+void StartSlowCloseAnimationForWindow(aura::Window* window,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ GetSlowCloseTransform(),
+ duration));
+ if (observer)
+ sequence->AddObserver(observer);
+ animator->StartAnimation(sequence);
+}
+
+// Quickly undoes the effects of the slow-close animation on |window|.
+void StartUndoSlowCloseAnimationForWindow(
+ aura::Window* window,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ gfx::Transform(),
+ duration));
+ if (observer)
+ sequence->AddObserver(observer);
+ animator->StartAnimation(sequence);
+}
+
+// Quickly shrinks |window| down to a point in the center of the screen and
+// fades it out to 0 opacity.
+void StartFastCloseAnimationForWindow(aura::Window* window,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animator->StartAnimation(
+ new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateTransformElement(
+ GetFastCloseTransform(), duration)));
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(0.0, duration));
+ if (observer)
+ sequence->AddObserver(observer);
+ animator->StartAnimation(sequence);
+}
+
+// Fades |window| to |target_opacity| over |duration|.
+void StartPartialFadeAnimation(aura::Window* window,
+ float target_opacity,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(
+ target_opacity, duration));
+ if (observer)
+ sequence->AddObserver(observer);
+ animator->StartAnimation(sequence);
+}
+
+// Fades |window| to |opacity| over |duration|.
+void StartOpacityAnimationForWindow(aura::Window* window,
+ float opacity,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(opacity, duration));
+ if (observer)
+ sequence->AddObserver(observer);
+ animator->StartAnimation(sequence);
+}
+
+// Makes |window| fully transparent instantaneously.
+void HideWindowImmediately(aura::Window* window,
+ ui::LayerAnimationObserver* observer) {
+ window->layer()->SetOpacity(0.0);
+ if (observer)
+ observer->OnLayerAnimationEnded(NULL);
+}
+
+// Restores |window| to its original position and scale and full opacity
+// instantaneously.
+void RestoreWindow(aura::Window* window, ui::LayerAnimationObserver* observer) {
+ window->layer()->SetTransform(gfx::Transform());
+ window->layer()->SetOpacity(1.0);
+ if (observer)
+ observer->OnLayerAnimationEnded(NULL);
+}
+
+void HideWindow(aura::Window* window,
+ base::TimeDelta duration,
+ bool above,
+ ui::LayerAnimationObserver* observer) {
+ ui::Layer* layer = window->layer();
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTransitionDuration(duration);
+
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ SetTransformForScaleAnimation(layer,
+ above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
+
+ settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
+ layer->SetOpacity(0.0f);
+
+ // After the animation completes snap the transform back to the identity,
+ // otherwise any one that asks for screen bounds gets a slightly scaled
+ // version.
+ settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
+ settings.SetTransitionDuration(base::TimeDelta());
+ layer->SetTransform(gfx::Transform());
+
+ // A bit of a dirty trick: we need to catch the end of the animation we don't
+ // control. So we use two facts we know: which animator will be used and the
+ // target opacity to add "Do nothing" animation sequence.
+ // Unfortunately, we can not just use empty LayerAnimationSequence, because
+ // it does not call NotifyEnded().
+ if (observer) {
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(
+ 0.0, base::TimeDelta()));
+ sequence->AddObserver(observer);
+ layer->GetAnimator()->ScheduleAnimation(sequence);
+ }
+}
+
+// Animates |window| to identity transform and full opacity over |duration|.
+void TransformWindowToBaseState(aura::Window* window,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::Layer* layer = window->layer();
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+
+ // Animate to target values.
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTransitionDuration(duration);
+
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ layer->SetTransform(gfx::Transform());
+
+ settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
+ layer->SetOpacity(1.0f);
+
+ // A bit of a dirty trick: we need to catch the end of the animation we don't
+ // control. So we use two facts we know: which animator will be used and the
+ // target opacity to add "Do nothing" animation sequence.
+ // Unfortunately, we can not just use empty LayerAnimationSequence, because
+ // it does not call NotifyEnded().
+ if (observer) {
+ ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
+ ui::LayerAnimationElement::CreateOpacityElement(
+ 1.0, base::TimeDelta()));
+ sequence->AddObserver(observer);
+ layer->GetAnimator()->ScheduleAnimation(sequence);
+ }
+}
+
+void ShowWindow(aura::Window* window,
+ base::TimeDelta duration,
+ bool above,
+ ui::LayerAnimationObserver* observer) {
+ ui::Layer* layer = window->layer();
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+
+ // Set initial state of animation
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTransitionDuration(base::TimeDelta());
+ SetTransformForScaleAnimation(layer,
+ above ? LAYER_SCALE_ANIMATION_ABOVE : LAYER_SCALE_ANIMATION_BELOW);
+
+ TransformWindowToBaseState(window, duration, observer);
+}
+
+// Starts grayscale/brightness animation for |window| over |duration|. Target
+// value for both grayscale and brightness are specified by |target|.
+void StartGrayscaleBrightnessAnimationForWindow(
+ aura::Window* window,
+ float target,
+ base::TimeDelta duration,
+ gfx::Tween::Type tween_type,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+
+ scoped_ptr<ui::LayerAnimationSequence> brightness_sequence(
+ new ui::LayerAnimationSequence());
+ scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence(
+ new ui::LayerAnimationSequence());
+
+ scoped_ptr<ui::LayerAnimationElement> brightness_element(
+ ui::LayerAnimationElement::CreateBrightnessElement(
+ target, duration));
+ brightness_element->set_tween_type(tween_type);
+ brightness_sequence->AddElement(brightness_element.release());
+
+ scoped_ptr<ui::LayerAnimationElement> grayscale_element(
+ ui::LayerAnimationElement::CreateGrayscaleElement(
+ target, duration));
+ grayscale_element->set_tween_type(tween_type);
+ grayscale_sequence->AddElement(grayscale_element.release());
+
+ std::vector<ui::LayerAnimationSequence*> animations;
+ animations.push_back(brightness_sequence.release());
+ animations.push_back(grayscale_sequence.release());
+
+ if (observer)
+ animations[0]->AddObserver(observer);
+
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+
+ animator->StartTogether(animations);
+}
+
+// Animation observer that will drop animated foreground once animation is
+// finished. It is used in when undoing shutdown animation.
+class CallbackAnimationObserver : public ui::LayerAnimationObserver {
+ public:
+ explicit CallbackAnimationObserver(base::Closure callback)
+ : callback_(callback) {
+ }
+ virtual ~CallbackAnimationObserver() {
+ }
+
+ private:
+ // Overridden from ui::LayerAnimationObserver:
+ virtual void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq)
+ OVERRIDE {
+ // Drop foreground once animation is over.
+ callback_.Run();
+ delete this;
+ }
+
+ virtual void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq)
+ OVERRIDE {
+ // Drop foreground once animation is over.
+ callback_.Run();
+ delete this;
+ }
+
+ virtual void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq)
+ OVERRIDE {}
+
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver);
+};
+
+
+bool IsLayerAnimated(ui::Layer* layer,
+ SessionStateAnimator::AnimationType type) {
+ switch (type) {
+ case SessionStateAnimator::ANIMATION_PARTIAL_CLOSE:
+ if (layer->GetTargetTransform() != GetSlowCloseTransform())
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE:
+ if (layer->GetTargetTransform() != gfx::Transform())
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_FULL_CLOSE:
+ if (layer->GetTargetTransform() != GetFastCloseTransform() ||
+ layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_FADE_IN:
+ if (layer->GetTargetOpacity() < 0.9999)
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_FADE_OUT:
+ if (layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY:
+ if (layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_RESTORE:
+ if (layer->opacity() < 0.9999 || layer->transform() != gfx::Transform())
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS:
+ if ((layer->GetTargetBrightness() < 0.9999) ||
+ (layer->GetTargetGrayscale() < 0.9999))
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
+ if ((layer->GetTargetBrightness() > 0.0001) ||
+ (layer->GetTargetGrayscale() > 0.0001))
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_DROP:
+ case SessionStateAnimator::ANIMATION_UNDO_LIFT:
+ //ToDo(antim) : check other effects
+ if (layer->GetTargetOpacity() < 0.9999)
+ return false;
+ break;
+ //ToDo(antim) : check other effects
+ case SessionStateAnimator::ANIMATION_LIFT:
+ if (layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ case SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN:
+ //ToDo(antim) : check other effects
+ if (layer->GetTargetOpacity() < 0.9999)
+ return false;
+ break;
+ //ToDo(antim) : check other effects
+ case SessionStateAnimator::ANIMATION_LOWER_BELOW_SCREEN:
+ if (layer->GetTargetOpacity() > 0.0001)
+ return false;
+ break;
+ default:
+ NOTREACHED() << "Unhandled animation type " << type;
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+// This observer is intended to use in cases when some action has to be taken
+// once some animation successfully completes (i.e. it was not aborted).
+// Observer will count a number of sequences it is attached to, and a number of
+// finished sequences (either Ended or Aborted). Once these two numbers are
+// equal, observer will delete itself, calling callback passed to constructor if
+// there were no aborted animations.
+// This way it can be either used to wait for some animation to be finished in
+// multiple layers, to wait once a sequence of animations is finished in one
+// layer or the mixture of both.
+class SessionStateAnimatorImpl::AnimationSequence
+ : public SessionStateAnimator::AnimationSequence,
+ public ui::LayerAnimationObserver {
+ public:
+ explicit AnimationSequence(
+ SessionStateAnimatorImpl* animator,
+ base::Closure callback)
+ : SessionStateAnimator::AnimationSequence(callback),
+ animator_(animator),
+ sequences_attached_(0),
+ sequences_completed_(0) {
+ }
+
+ // SessionStateAnimator::AnimationSequence:
+ virtual void StartAnimation(
+ int container_mask,
+ SessionStateAnimator::AnimationType type,
+ SessionStateAnimator::AnimationSpeed speed) OVERRIDE {
+ animator_->StartAnimationInSequence(container_mask, type, speed, this);
+ }
+
+ private:
+ virtual ~AnimationSequence() {}
+
+ // ui::LayerAnimationObserver:
+ virtual void OnLayerAnimationEnded(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {
+ sequences_completed_++;
+ if (sequences_completed_ == sequences_attached_)
+ OnAnimationCompleted();
+ }
+
+ virtual void OnLayerAnimationAborted(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {
+ sequences_completed_++;
+ if (sequences_completed_ == sequences_attached_)
+ OnAnimationAborted();
+ }
+
+ virtual void OnLayerAnimationScheduled(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {}
+
+ virtual void OnAttachedToSequence(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {
+ LayerAnimationObserver::OnAttachedToSequence(sequence);
+ sequences_attached_++;
+ }
+
+ SessionStateAnimatorImpl* animator_; // not owned
+
+ // Number of sequences this observer was attached to.
+ int sequences_attached_;
+
+ // Number of sequences either ended or aborted.
+ int sequences_completed_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
+};
+
+bool SessionStateAnimatorImpl::TestApi::ContainersAreAnimated(
+ int container_mask, AnimationType type) const {
+ aura::Window::Windows containers;
+ animator_->GetContainers(container_mask, &containers);
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ aura::Window* window = *it;
+ ui::Layer* layer = window->layer();
+ if (!IsLayerAnimated(layer, type))
+ return false;
+ }
+ return true;
+}
+
+bool SessionStateAnimatorImpl::TestApi::RootWindowIsAnimated(AnimationType type)
+ const {
+ aura::Window* root_window = Shell::GetPrimaryRootWindow();
+ ui::Layer* layer = root_window->layer();
+ return IsLayerAnimated(layer, type);
+}
+
+SessionStateAnimatorImpl::SessionStateAnimatorImpl() {
+}
+
+SessionStateAnimatorImpl::~SessionStateAnimatorImpl() {
+}
+
+// Fills |containers| with the containers described by |container_mask|.
+void SessionStateAnimatorImpl::GetContainers(int container_mask,
+ aura::Window::Windows* containers) {
+ aura::Window* root_window = Shell::GetPrimaryRootWindow();
+ containers->clear();
+
+ if (container_mask & ROOT_CONTAINER) {
+ containers->push_back(Shell::GetPrimaryRootWindow());
+ }
+
+ if (container_mask & DESKTOP_BACKGROUND) {
+ containers->push_back(Shell::GetContainer(
+ root_window, kShellWindowId_DesktopBackgroundContainer));
+ }
+ if (container_mask & LAUNCHER) {
+ containers->push_back(
+ Shell::GetContainer(root_window, kShellWindowId_ShelfContainer));
+ }
+ if (container_mask & NON_LOCK_SCREEN_CONTAINERS) {
+ // TODO(antrim): Figure out a way to eliminate a need to exclude launcher
+ // in such way.
+ aura::Window* non_lock_screen_containers = Shell::GetContainer(
+ root_window, kShellWindowId_NonLockScreenContainersContainer);
+ aura::Window::Windows children = non_lock_screen_containers->children();
+
+ for (aura::Window::Windows::const_iterator it = children.begin();
+ it != children.end(); ++it) {
+ aura::Window* window = *it;
+ if (window->id() == kShellWindowId_ShelfContainer)
+ continue;
+ containers->push_back(window);
+ }
+ }
+ if (container_mask & LOCK_SCREEN_BACKGROUND) {
+ containers->push_back(Shell::GetContainer(
+ root_window, kShellWindowId_LockScreenBackgroundContainer));
+ }
+ if (container_mask & LOCK_SCREEN_CONTAINERS) {
+ containers->push_back(Shell::GetContainer(
+ root_window, kShellWindowId_LockScreenContainersContainer));
+ }
+ if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) {
+ containers->push_back(Shell::GetContainer(
+ root_window, kShellWindowId_LockScreenRelatedContainersContainer));
+ }
+}
+
+void SessionStateAnimatorImpl::StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) {
+ aura::Window::Windows containers;
+ GetContainers(container_mask, &containers);
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ RunAnimationForWindow(*it, type, speed, NULL);
+ }
+}
+
+void SessionStateAnimatorImpl::StartAnimationWithCallback(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure callback) {
+ aura::Window::Windows containers;
+ GetContainers(container_mask, &containers);
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ ui::LayerAnimationObserver* observer =
+ new CallbackAnimationObserver(callback);
+ RunAnimationForWindow(*it, type, speed, observer);
+ }
+}
+
+SessionStateAnimator::AnimationSequence*
+ SessionStateAnimatorImpl::BeginAnimationSequence(base::Closure callback) {
+ return new AnimationSequence(this, callback);
+}
+
+bool SessionStateAnimatorImpl::IsBackgroundHidden() const {
+ return !GetBackground()->IsVisible();
+}
+
+void SessionStateAnimatorImpl::ShowBackground() {
+ ui::ScopedLayerAnimationSettings settings(
+ GetBackground()->layer()->GetAnimator());
+ settings.SetTransitionDuration(base::TimeDelta());
+ GetBackground()->Show();
+}
+
+void SessionStateAnimatorImpl::HideBackground() {
+ ui::ScopedLayerAnimationSettings settings(
+ GetBackground()->layer()->GetAnimator());
+ settings.SetTransitionDuration(base::TimeDelta());
+ GetBackground()->Hide();
+}
+
+void SessionStateAnimatorImpl::StartAnimationInSequence(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ AnimationSequence* observer) {
+ aura::Window::Windows containers;
+ GetContainers(container_mask, &containers);
+ for (aura::Window::Windows::const_iterator it = containers.begin();
+ it != containers.end(); ++it) {
+ RunAnimationForWindow(*it, type, speed, observer);
+ }
+}
+
+void SessionStateAnimatorImpl::RunAnimationForWindow(
+ aura::Window* window,
+ AnimationType type,
+ AnimationSpeed speed,
+ ui::LayerAnimationObserver* observer) {
+ base::TimeDelta duration = GetDuration(speed);
+
+ switch (type) {
+ case ANIMATION_PARTIAL_CLOSE:
+ StartSlowCloseAnimationForWindow(window, duration, observer);
+ break;
+ case ANIMATION_UNDO_PARTIAL_CLOSE:
+ StartUndoSlowCloseAnimationForWindow(window, duration, observer);
+ break;
+ case ANIMATION_FULL_CLOSE:
+ StartFastCloseAnimationForWindow(window, duration, observer);
+ break;
+ case ANIMATION_FADE_IN:
+ StartOpacityAnimationForWindow(window, 1.0, duration, observer);
+ break;
+ case ANIMATION_FADE_OUT:
+ StartOpacityAnimationForWindow(window, 0.0, duration, observer);
+ break;
+ case ANIMATION_HIDE_IMMEDIATELY:
+ DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
+ HideWindowImmediately(window, observer);
+ break;
+ case ANIMATION_RESTORE:
+ DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
+ RestoreWindow(window, observer);
+ break;
+ case ANIMATION_LIFT:
+ HideWindow(window, duration, true, observer);
+ break;
+ case ANIMATION_DROP:
+ ShowWindow(window, duration, true, observer);
+ break;
+ case ANIMATION_UNDO_LIFT:
+ TransformWindowToBaseState(window, duration, observer);
+ break;
+ case ANIMATION_RAISE_TO_SCREEN:
+ ShowWindow(window, duration, false, observer);
+ break;
+ case ANIMATION_LOWER_BELOW_SCREEN:
+ HideWindow(window, duration, false, observer);
+ break;
+ case ANIMATION_PARTIAL_FADE_IN:
+ StartPartialFadeAnimation(
+ window, kPartialFadeRatio, duration, observer);
+ break;
+ case ANIMATION_UNDO_PARTIAL_FADE_IN:
+ StartPartialFadeAnimation(window, 0.0, duration, observer);
+ break;
+ case ANIMATION_FULL_FADE_IN:
+ StartPartialFadeAnimation(window, 1.0, duration, observer);
+ break;
+ case ANIMATION_GRAYSCALE_BRIGHTNESS:
+ StartGrayscaleBrightnessAnimationForWindow(
+ window, 1.0, duration, gfx::Tween::EASE_IN, observer);
+ break;
+ case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
+ StartGrayscaleBrightnessAnimationForWindow(
+ window, 0.0, duration, gfx::Tween::EASE_IN_OUT, observer);
+ break;
+ }
+}
+
+} // namespace ash
diff --git a/ash/wm/session_state_animator_impl.h b/ash/wm/session_state_animator_impl.h
new file mode 100644
index 0000000..bad7103
--- /dev/null
+++ b/ash/wm/session_state_animator_impl.h
@@ -0,0 +1,88 @@
+// 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.
+
+#ifndef ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_
+#define ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_
+
+#include "ash/ash_export.h"
+#include "ash/wm/session_state_animator.h"
+#include "base/basictypes.h"
+#include "ui/aura/window.h"
+
+namespace ui {
+class LayerAnimationObserver;
+}
+
+namespace ash {
+
+// Displays onscreen animations for session state changes (lock/unlock, sign
+// out, shut down).
+class ASH_EXPORT SessionStateAnimatorImpl : public SessionStateAnimator {
+ public:
+ // Helper class used by tests to access internal state.
+ class ASH_EXPORT TestApi {
+ public:
+ explicit TestApi(SessionStateAnimatorImpl* animator)
+ : animator_(animator) {}
+
+ // Returns true if containers of a given |container_mask|
+ // were last animated with |type| (probably; the analysis is fairly ad-hoc).
+ // |container_mask| is a bitfield of a Container.
+ bool ContainersAreAnimated(int container_mask,
+ SessionStateAnimator::AnimationType type) const;
+
+ // Returns true if root window was last animated with |type| (probably;
+ // the analysis is fairly ad-hoc).
+ bool RootWindowIsAnimated(SessionStateAnimator::AnimationType type) const;
+
+ private:
+ SessionStateAnimatorImpl* animator_; // not owned
+
+ DISALLOW_COPY_AND_ASSIGN(TestApi);
+ };
+
+ SessionStateAnimatorImpl();
+ virtual ~SessionStateAnimatorImpl();
+
+ // Fills |containers| with the containers included in |container_mask|.
+ static void GetContainers(int container_mask,
+ aura::Window::Windows* containers);
+
+ // ash::SessionStateAnimator:
+ virtual void StartAnimation(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed) OVERRIDE;
+ virtual void StartAnimationWithCallback(
+ int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ base::Closure callback) OVERRIDE;
+ virtual AnimationSequence* BeginAnimationSequence(
+ base::Closure callback) OVERRIDE;
+ virtual bool IsBackgroundHidden() const OVERRIDE;
+ virtual void ShowBackground() OVERRIDE;
+ virtual void HideBackground() OVERRIDE;
+
+ private:
+ class AnimationSequence;
+ friend class AnimationSequence;
+
+ virtual void StartAnimationInSequence(int container_mask,
+ AnimationType type,
+ AnimationSpeed speed,
+ AnimationSequence* observer);
+
+ // Apply animation |type| to window |window| with |speed| and add |observer|
+ // if it is not NULL to the last animation sequence.
+ void RunAnimationForWindow(aura::Window* window,
+ SessionStateAnimator::AnimationType type,
+ SessionStateAnimator::AnimationSpeed speed,
+ ui::LayerAnimationObserver* observer);
+
+ DISALLOW_COPY_AND_ASSIGN(SessionStateAnimatorImpl);
+};
+
+} // namespace ash
+
+#endif // ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_
diff --git a/chrome/browser/chromeos/power/power_button_observer.cc b/chrome/browser/chromeos/power/power_button_observer.cc
index 8a74cae..e7a2718 100644
--- a/chrome/browser/chromeos/power/power_button_observer.cc
+++ b/chrome/browser/chromeos/power/power_button_observer.cc
@@ -15,6 +15,10 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/notification_service.h"
+namespace ash {
+class LockStateControllerDelegate;
+}
+
namespace chromeos {
namespace {
@@ -30,7 +34,8 @@ ash::user::LoginStatus GetCurrentLoginStatus() {
PowerButtonObserver::PowerButtonObserver() {
ash::Shell::GetInstance()->lock_state_controller()->
- SetDelegate(new SessionStateControllerDelegateChromeos);
+ SetDelegate(scoped_ptr<ash::LockStateControllerDelegate>(
+ new SessionStateControllerDelegateChromeos));
registrar_.Add(
this,