1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_SHELF_HOTSEAT_TRANSITION_ANIMATOR_H_
6 #define ASH_SHELF_HOTSEAT_TRANSITION_ANIMATOR_H_
7 
8 #include "ash/ash_export.h"
9 #include "ash/public/cpp/shelf_types.h"
10 #include "base/callback.h"
11 #include "base/observer_list.h"
12 #include "base/observer_list_types.h"
13 #include "ui/compositor/layer_animation_observer.h"
14 
15 namespace ash {
16 class ShelfWidget;
17 
18 // Makes it appear that the background of the shelf and hotseat animate to/from
19 // one another.
20 class ASH_EXPORT HotseatTransitionAnimator
21     : public ui::ImplicitAnimationObserver {
22  public:
23   class TestObserver {
24    public:
25     virtual ~TestObserver() = default;
26     virtual void OnTransitionTestAnimationEnded() = 0;
27   };
28 
29   class Observer : public base::CheckedObserver {
30    public:
31     // Called before hotseat transition animations begin.
OnHotseatTransitionAnimationWillStart(HotseatState from_state,HotseatState to_start)32     virtual void OnHotseatTransitionAnimationWillStart(HotseatState from_state,
33                                                        HotseatState to_start) {}
34     // Called when hotseat transition animations end.
OnHotseatTransitionAnimationEnded(HotseatState from_state,HotseatState to_start)35     virtual void OnHotseatTransitionAnimationEnded(HotseatState from_state,
36                                                    HotseatState to_start) {}
37     // Called when hotseat transition animations was aborted.
OnHotseatTransitionAnimationAborted()38     virtual void OnHotseatTransitionAnimationAborted() {}
39   };
40 
41   explicit HotseatTransitionAnimator(ShelfWidget* shelf_widget);
42   ~HotseatTransitionAnimator() override;
43 
44   // Called when the hotseat state changes.
45   void OnHotseatStateChanged(HotseatState old_state, HotseatState new_state);
46 
47   void AddObserver(Observer* observer);
48   void RemoveObserver(Observer* observer);
49 
50   // ui::ImplicitAnimationObserver:
51   void OnImplicitAnimationsCompleted() override;
52   void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override;
53 
54   // Enables or enables animations. Disabling the animations will stop in-flight
55   // animations.
56   void SetAnimationsEnabledInSessionState(bool enabled);
57 
58   // Set the test observer to watch for animations completed.
59   void SetTestObserver(TestObserver* test_observer);
60 
61  private:
62   // Starts the animation between |old_state| and |target_state|.
63   void DoAnimation(HotseatState old_state, HotseatState new_state);
64 
65   // Whether an animation should occur between |old_state| and |new_state|.
66   bool ShouldDoAnimation(HotseatState old_state, HotseatState new_state);
67 
68   // Notifies observers of animation completion.
69   void NotifyHotseatTransitionAnimationEnded(HotseatState old_state,
70                                              HotseatState new_state);
71 
72   // The widget which owns the HotseatWidget. Owned by Shelf.
73   ShelfWidget* const shelf_widget_;
74 
75   // Whether hotseat animations should be animated for the current session
76   // state.
77   bool animations_enabled_for_current_session_state_ = false;
78 
79   // Callback used to notify observers of animation completion.
80   base::OnceClosure animation_complete_callback_;
81 
82   base::ObserverList<Observer> observers_;
83 
84   // A test observer used to wait for the hotseat transition animation.
85   TestObserver* test_observer_ = nullptr;
86 
87   base::WeakPtrFactory<HotseatTransitionAnimator> weak_ptr_factory_{this};
88 };
89 
90 }  // namespace ash
91 
92 #endif  // ASH_SHELF_HOTSEAT_TRANSITION_ANIMATOR_H_
93