| Index: ash/test/test_session_state_animator.cc
|
| diff --git a/ash/test/test_session_state_animator.cc b/ash/test/test_session_state_animator.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b1d5b47c4aa22b26ef46445b0759fa832f12200e
|
| --- /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
|
|
|