1 // Copyright 2020 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_WM_DESKS_DESK_ANIMATION_BASE_H_
6 #define ASH_WM_DESKS_DESK_ANIMATION_BASE_H_
7 
8 #include "ash/ash_export.h"
9 #include "ash/public/cpp/metrics_util.h"
10 #include "ash/wm/desks/desks_histogram_enums.h"
11 #include "ash/wm/desks/root_window_desk_switch_animator.h"
12 #include "ui/compositor/throughput_tracker.h"
13 
14 namespace ash {
15 
16 class DesksController;
17 
18 // An abstract class that handles the shared operations need to be performed
19 // when doing an animation that causes a desk switch animation. Subclasses
20 // such as DeskActivationAnimation and DeskRemovalAnimation implement the
21 // abstract interface of this class to handle the unique operations specific to
22 // each animation type.
23 class ASH_EXPORT DeskAnimationBase
24     : public RootWindowDeskSwitchAnimator::Delegate {
25  public:
26   DeskAnimationBase(DesksController* controller,
27                     int ending_desk_index,
28                     bool is_continuous_gesture_animation);
29   DeskAnimationBase(const DeskAnimationBase&) = delete;
30   DeskAnimationBase& operator=(const DeskAnimationBase&) = delete;
31   ~DeskAnimationBase() override;
32 
ending_desk_index()33   int ending_desk_index() const { return ending_desk_index_; }
visible_desk_changes()34   int visible_desk_changes() const { return visible_desk_changes_; }
35 
36   // Launches the animation. This should be done once all animators
37   // are created and added to `desk_switch_animators_`. This is to avoid any
38   // potential race conditions that might happen if one animator finished phase
39   // (1) of the animation while other animators are still being constructed.
40   void Launch();
41 
42   // Replaces a current animation with an animation to an adjacent desk. By
43   // default returns false as most animations do not support replacing.
44   virtual bool Replace(bool moving_left, DesksSwitchSource source);
45 
46   // Updates a current animation by shifting its animating layer.
47   // |scroll_delta_x| is the amount of scroll change since the last scroll
48   // update event. Returns false if the animation does not support updating.
49   virtual bool UpdateSwipeAnimation(float scroll_delta_x);
50 
51   // Ends a current animation, animating to a desk determined by the
52   // implementation. Returns false if the animation does not support ending.
53   virtual bool EndSwipeAnimation();
54 
55   // RootWindowDeskSwitchAnimator::Delegate:
56   void OnStartingDeskScreenshotTaken(int ending_desk_index) override;
57   void OnEndingDeskScreenshotTaken() override;
58   void OnDeskSwitchAnimationFinished() override;
59   void OnVisibleDeskChanged() override;
60 
set_skip_notify_controller_on_animation_finished_for_testing(bool val)61   void set_skip_notify_controller_on_animation_finished_for_testing(bool val) {
62     skip_notify_controller_on_animation_finished_for_testing_ = val;
63   }
64 
65   RootWindowDeskSwitchAnimator* GetDeskSwitchAnimatorAtIndexForTesting(
66       size_t index) const;
67 
68  protected:
69   // Abstract functions that can be overridden by child classes to do different
70   // things when phase (1), and phase (3) completes. Note that
71   // `OnDeskSwitchAnimationFinishedInternal()` will be called before the desks
72   // screenshot layers, stored in `desk_switch_animators_`, are destroyed.
73   virtual void OnStartingDeskScreenshotTakenInternal(int ending_desk_index) = 0;
74   virtual void OnDeskSwitchAnimationFinishedInternal() = 0;
75 
76   // Since performance here matters, we have to use the UMA histograms macros to
77   // report the smoothness histograms, but each macro use has to be associated
78   // with exactly one histogram name. This function allows subclasses to return
79   // a callback that reports the histogram using the macro with their desired
80   // name.
81   virtual metrics_util::ReportCallback GetReportCallback() const = 0;
82 
83   DesksController* const controller_;
84 
85   // An animator object per each root. Once all the animations are complete,
86   // this list is cleared.
87   std::vector<std::unique_ptr<RootWindowDeskSwitchAnimator>>
88       desk_switch_animators_;
89 
90   // The index of the desk that will be active after this animation ends.
91   int ending_desk_index_;
92 
93   // True if this animation is a continuous gesture animation. Update and End
94   // only work when this is true, and we do not start the animation when
95   // OnEndingDeskScreenshotTaken is called.
96   const bool is_continuous_gesture_animation_;
97 
98   // Used for metrics collection to track how many desks changes a user has seen
99   // during the animation. This is different from the number of desk activations
100   // as the user may switch desks but not activate it if the desk already has a
101   // screenshot taken. This will only change for an activation animation, not a
102   // remove animation.
103   int visible_desk_changes_ = 0;
104 
105   // ThroughputTracker used for measuring this animation smoothness.
106   ui::ThroughputTracker throughput_tracker_;
107 
108   // If true, do not notify |controller_| when
109   // OnDeskSwitchAnimationFinished() is called. This class and
110   // DeskController are tied together in production code, but may not be in a
111   // test scenario.
112   bool skip_notify_controller_on_animation_finished_for_testing_ = false;
113 };
114 
115 }  // namespace ash
116 
117 #endif  // ASH_WM_DESKS_DESK_ANIMATION_BASE_H_
118