123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- // 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/wm/test_session_state_animator.h"
- #include <utility>
- #include <vector>
- #include "base/barrier_closure.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- namespace ash {
- const SessionStateAnimator::Container
- TestSessionStateAnimator::kAllContainers[] = {
- SessionStateAnimator::WALLPAPER,
- SessionStateAnimator::SHELF,
- SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- SessionStateAnimator::LOCK_SCREEN_WALLPAPER,
- 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(AnimationCallback callback,
- TestSessionStateAnimator* animator)
- : SessionStateAnimator::AnimationSequence(std::move(callback)),
- sequence_count_(0),
- sequence_aborted_(false),
- animator_(animator) {}
- AnimationSequence(const AnimationSequence&) = delete;
- AnimationSequence& operator=(const AnimationSequence&) = delete;
- ~AnimationSequence() override = default;
- 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:
- 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_;
- };
- TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
- int animation_epoch,
- base::TimeDelta duration,
- SessionStateAnimator::Container container,
- AnimationType type,
- AnimationSpeed speed,
- base::OnceClosure success_callback,
- base::OnceClosure failed_callback)
- : animation_epoch(animation_epoch),
- remaining_duration(duration),
- container(container),
- type(type),
- speed(speed),
- success_callback(std::move(success_callback)),
- failed_callback(std::move(failed_callback)) {}
- TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
- ActiveAnimation&& other) = default;
- TestSessionStateAnimator::ActiveAnimation&
- TestSessionStateAnimator::ActiveAnimation::operator=(ActiveAnimation&& other) =
- default;
- TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() = default;
- TestSessionStateAnimator::TestSessionStateAnimator()
- : last_animation_epoch_(0), is_wallpaper_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()) {
- // Save callback and erase animation, then run the callback afterwards
- // to avoid running the callback twice for animations that start other
- // animations on their same container. This is because the second
- // animation will call the first's animation callback when being added
- // to the animations list by aborting it, as we don't support 2
- // animations on the same container in this object.
- auto success_callback = std::move(active_animation.success_callback);
- animation_iter = (*container_iter).second.erase(animation_iter);
- std::move(success_callback).Run();
- } 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)
- std::move(active_animation.success_callback).Run();
- else
- std::move(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 < std::size(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 < std::size(kAllContainers); ++i) {
- if (container_mask & kAllContainers[i]) {
- AddAnimation(kAllContainers[i], type, speed, base::DoNothing(),
- base::DoNothing());
- }
- }
- }
- void TestSessionStateAnimator::StartAnimationWithCallback(
- int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- base::OnceClosure callback) {
- ++last_animation_epoch_;
- int container_count = 0;
- for (size_t i = 0; i < std::size(kAllContainers); ++i) {
- if (container_mask & kAllContainers[i])
- ++container_count;
- }
- base::RepeatingClosure completion_callback =
- base::BarrierClosure(container_count, std::move(callback));
- for (size_t i = 0; i < std::size(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, completion_callback,
- completion_callback);
- }
- }
- }
- SessionStateAnimator::AnimationSequence*
- TestSessionStateAnimator::BeginAnimationSequence(AnimationCallback callback) {
- return new AnimationSequence(std::move(callback), this);
- }
- bool TestSessionStateAnimator::IsWallpaperHidden() const {
- return is_wallpaper_hidden_;
- }
- void TestSessionStateAnimator::ShowWallpaper() {
- is_wallpaper_hidden_ = false;
- }
- void TestSessionStateAnimator::HideWallpaper() {
- is_wallpaper_hidden_ = true;
- }
- void TestSessionStateAnimator::AbortAnimations(int container_mask) {
- for (size_t i = 0; i < std::size(kAllContainers); ++i) {
- if (container_mask & kAllContainers[i])
- AbortAnimation(kAllContainers[i]);
- }
- }
- void TestSessionStateAnimator::StartAnimationInSequence(
- int container_mask,
- AnimationType type,
- AnimationSpeed speed,
- AnimationSequence* animation_sequence) {
- ++last_animation_epoch_;
- for (size_t i = 0; i < std::size(kAllContainers); ++i) {
- if (container_mask & kAllContainers[i]) {
- base::OnceClosure success_callback =
- base::BindOnce(&AnimationSequence::SequenceFinished,
- base::Unretained(animation_sequence), true);
- base::OnceClosure failed_callback =
- base::BindOnce(&AnimationSequence::SequenceFinished,
- base::Unretained(animation_sequence), false);
- animation_sequence->SequenceAttached();
- AddAnimation(kAllContainers[i], type, speed, std::move(success_callback),
- std::move(failed_callback));
- }
- }
- }
- void TestSessionStateAnimator::AddAnimation(
- SessionStateAnimator::Container container,
- AnimationType type,
- AnimationSpeed speed,
- base::OnceClosure success_callback,
- base::OnceClosure failed_callback) {
- base::TimeDelta duration = GetDuration(speed);
- ActiveAnimation active_animation(last_animation_epoch_, duration, container,
- type, speed, std::move(success_callback),
- std::move(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(std::move(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;
- std::move(active_animation.failed_callback).Run();
- animation_iter = (*container_iter).second.erase(animation_iter);
- }
- }
- }
- } // namespace ash
|