1 // Copyright 2015 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 CC_TEST_ANIMATION_TIMELINES_TEST_COMMON_H_
6 #define CC_TEST_ANIMATION_TIMELINES_TEST_COMMON_H_
7 
8 #include <memory>
9 #include <unordered_map>
10 
11 #include "cc/animation/animation_delegate.h"
12 #include "cc/animation/animation_host.h"
13 #include "cc/animation/keyframe_model.h"
14 #include "cc/trees/mutator_host_client.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gfx/geometry/scroll_offset.h"
17 #include "ui/gfx/transform.h"
18 
19 namespace cc {
20 
21 class Animation;
22 class KeyframeEffect;
23 
24 class TestLayer {
25  public:
26   static std::unique_ptr<TestLayer> Create();
27   ~TestLayer();
28 
29   void ClearMutatedProperties();
30 
31   int transform_x() const;
32   int transform_y() const;
33   float brightness() const;
34   float invert() const;
35 
transform()36   const gfx::Transform& transform() const { return transform_; }
set_transform(const gfx::Transform & transform)37   void set_transform(const gfx::Transform& transform) {
38     transform_ = transform;
39     mutated_properties_[TargetProperty::TRANSFORM] = true;
40   }
41 
opacity()42   float opacity() const { return opacity_; }
set_opacity(float opacity)43   void set_opacity(float opacity) {
44     opacity_ = opacity;
45     mutated_properties_[TargetProperty::OPACITY] = true;
46   }
47 
filters()48   FilterOperations filters() const { return filters_; }
set_filters(const FilterOperations & filters)49   void set_filters(const FilterOperations& filters) {
50     filters_ = filters;
51     mutated_properties_[TargetProperty::FILTER] = true;
52   }
53 
backdrop_filters()54   FilterOperations backdrop_filters() const { return backdrop_filters_; }
set_backdrop_filters(const FilterOperations & backdrop_filters)55   void set_backdrop_filters(const FilterOperations& backdrop_filters) {
56     backdrop_filters_ = backdrop_filters;
57     mutated_properties_[TargetProperty::BACKDROP_FILTER] = true;
58   }
59 
scroll_offset()60   gfx::ScrollOffset scroll_offset() const { return scroll_offset_; }
set_scroll_offset(const gfx::ScrollOffset & scroll_offset)61   void set_scroll_offset(const gfx::ScrollOffset& scroll_offset) {
62     scroll_offset_ = scroll_offset;
63     mutated_properties_[TargetProperty::SCROLL_OFFSET] = true;
64   }
65 
is_currently_animating(TargetProperty::Type property)66   bool is_currently_animating(TargetProperty::Type property) const {
67     return is_currently_animating_[property];
68   }
set_is_currently_animating(TargetProperty::Type property,bool is_animating)69   void set_is_currently_animating(TargetProperty::Type property,
70                                   bool is_animating) {
71     is_currently_animating_[property] = is_animating;
72   }
73 
has_potential_animation(TargetProperty::Type property)74   bool has_potential_animation(TargetProperty::Type property) const {
75     return has_potential_animation_[property];
76   }
set_has_potential_animation(TargetProperty::Type property,bool is_animating)77   void set_has_potential_animation(TargetProperty::Type property,
78                                    bool is_animating) {
79     has_potential_animation_[property] = is_animating;
80   }
81 
is_property_mutated(TargetProperty::Type property)82   bool is_property_mutated(TargetProperty::Type property) const {
83     return mutated_properties_[property];
84   }
85 
86  private:
87   TestLayer();
88 
89   gfx::Transform transform_;
90   float opacity_;
91   FilterOperations filters_;
92   FilterOperations backdrop_filters_;
93   gfx::ScrollOffset scroll_offset_;
94 
95   TargetProperties has_potential_animation_;
96   TargetProperties is_currently_animating_;
97   TargetProperties mutated_properties_;
98 };
99 
100 class TestHostClient : public MutatorHostClient {
101  public:
102   explicit TestHostClient(ThreadInstance thread_instance);
103   ~TestHostClient();
104 
105   void ClearMutatedProperties();
106 
107   bool IsElementInPropertyTrees(ElementId element_id,
108                                 ElementListType list_type) const override;
109 
110   void SetMutatorsNeedCommit() override;
111   void SetMutatorsNeedRebuildPropertyTrees() override;
112 
113   void SetElementFilterMutated(ElementId element_id,
114                                ElementListType list_type,
115                                const FilterOperations& filters) override;
116 
117   void SetElementBackdropFilterMutated(
118       ElementId element_id,
119       ElementListType list_type,
120       const FilterOperations& backdrop_filters) override;
121 
122   void SetElementOpacityMutated(ElementId element_id,
123                                 ElementListType list_type,
124                                 float opacity) override;
125 
126   void SetElementTransformMutated(ElementId element_id,
127                                   ElementListType list_type,
128                                   const gfx::Transform& transform) override;
129 
130   void SetElementScrollOffsetMutated(
131       ElementId element_id,
132       ElementListType list_type,
133       const gfx::ScrollOffset& scroll_offset) override;
134 
135   void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
136                                  ElementListType list_type,
137                                  const PropertyAnimationState& mask,
138                                  const PropertyAnimationState& state) override;
139   void AnimationScalesChanged(ElementId element_id,
140                               ElementListType list_type,
141                               float maximum_scale,
142                               float starting_scale) override;
143 
ScrollOffsetAnimationFinished()144   void ScrollOffsetAnimationFinished() override {}
145 
146   void SetScrollOffsetForAnimation(const gfx::ScrollOffset& scroll_offset);
147   gfx::ScrollOffset GetScrollOffsetForAnimation(
148       ElementId element_id) const override;
149 
NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,ElementListType tree_type)150   void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
151                                          ElementListType tree_type) override {}
152 
OnCustomPropertyMutated(ElementId element_id,const std::string & custom_property_name,PaintWorkletInput::PropertyValue custom_property_value)153   void OnCustomPropertyMutated(
154       ElementId element_id,
155       const std::string& custom_property_name,
156       PaintWorkletInput::PropertyValue custom_property_value) override {}
157 
mutators_need_commit()158   bool mutators_need_commit() const { return mutators_need_commit_; }
set_mutators_need_commit(bool need)159   void set_mutators_need_commit(bool need) { mutators_need_commit_ = need; }
160 
161   void RegisterElementId(ElementId element_id, ElementListType list_type);
162   void UnregisterElementId(ElementId element_id, ElementListType list_type);
163 
host()164   AnimationHost* host() {
165     DCHECK(host_);
166     return host_.get();
167   }
168 
169   bool IsPropertyMutated(ElementId element_id,
170                          ElementListType list_type,
171                          TargetProperty::Type property) const;
172 
173   FilterOperations GetFilters(ElementId element_id,
174                               ElementListType list_type) const;
175   FilterOperations GetBackdropFilters(ElementId element_id,
176                                       ElementListType list_type) const;
177   float GetOpacity(ElementId element_id, ElementListType list_type) const;
178   gfx::Transform GetTransform(ElementId element_id,
179                               ElementListType list_type) const;
180   gfx::ScrollOffset GetScrollOffset(ElementId element_id,
181                                     ElementListType list_type) const;
182   bool GetHasPotentialTransformAnimation(ElementId element_id,
183                                          ElementListType list_type) const;
184   bool GetTransformIsCurrentlyAnimating(ElementId element_id,
185                                         ElementListType list_type) const;
186   bool GetOpacityIsCurrentlyAnimating(ElementId element_id,
187                                       ElementListType list_type) const;
188   bool GetHasPotentialOpacityAnimation(ElementId element_id,
189                                        ElementListType list_type) const;
190   bool GetHasPotentialFilterAnimation(ElementId element_id,
191                                       ElementListType list_type) const;
192   bool GetFilterIsCurrentlyAnimating(ElementId element_id,
193                                      ElementListType list_type) const;
194   bool GetHasPotentialBackdropFilterAnimation(ElementId element_id,
195                                               ElementListType list_type) const;
196   bool GetBackdropFilterIsCurrentlyAnimating(ElementId element_id,
197                                              ElementListType list_type) const;
198 
199   void ExpectFilterPropertyMutated(ElementId element_id,
200                                    ElementListType list_type,
201                                    float brightness) const;
202   void ExpectBackdropFilterPropertyMutated(ElementId element_id,
203                                            ElementListType list_type,
204                                            float invert) const;
205   void ExpectOpacityPropertyMutated(ElementId element_id,
206                                     ElementListType list_type,
207                                     float opacity) const;
208   void ExpectTransformPropertyMutated(ElementId element_id,
209                                       ElementListType list_type,
210                                       int transform_x,
211                                       int transform_y) const;
212 
213   TestLayer* FindTestLayer(ElementId element_id,
214                            ElementListType list_type) const;
215 
216  private:
217   std::unique_ptr<AnimationHost> host_;
218 
219   using ElementIdToTestLayer =
220       std::unordered_map<ElementId, std::unique_ptr<TestLayer>, ElementIdHash>;
221   ElementIdToTestLayer layers_in_active_tree_;
222   ElementIdToTestLayer layers_in_pending_tree_;
223 
224   gfx::ScrollOffset scroll_offset_;
225   bool mutators_need_commit_;
226 };
227 
228 class TestAnimationDelegate : public AnimationDelegate {
229  public:
230   TestAnimationDelegate();
231 
232   void NotifyAnimationStarted(base::TimeTicks monotonic_time,
233                               int target_property,
234                               int group) override;
235   void NotifyAnimationFinished(base::TimeTicks monotonic_time,
236                                int target_property,
237                                int group) override;
238   void NotifyAnimationAborted(base::TimeTicks monotonic_time,
239                               int target_property,
240                               int group) override;
241   void NotifyAnimationTakeover(base::TimeTicks monotonic_time,
242                                int target_property,
243                                base::TimeTicks animation_start_time,
244                                std::unique_ptr<AnimationCurve> curve) override;
245   void NotifyLocalTimeUpdated(
246       base::Optional<base::TimeDelta> local_time) override;
247 
started()248   bool started() { return started_; }
249 
finished()250   bool finished() { return finished_; }
251 
aborted()252   bool aborted() { return aborted_; }
253 
takeover()254   bool takeover() { return takeover_; }
255 
start_time()256   base::TimeTicks start_time() { return start_time_; }
257 
258  private:
259   bool started_;
260   bool finished_;
261   bool aborted_;
262   bool takeover_;
263   base::TimeTicks start_time_;
264 };
265 
266 class AnimationTimelinesTest : public testing::Test {
267  public:
268   AnimationTimelinesTest();
269   ~AnimationTimelinesTest() override;
270 
271  protected:
272   void SetUp() override;
273   void TearDown() override;
274 
275   void GetImplTimelineAndAnimationByID();
276 
277   void CreateTestLayer(bool needs_active_value_observations,
278                        bool needs_pending_value_observations);
279   void AttachTimelineAnimationLayer();
280   virtual void CreateImplTimelineAndAnimation();
281 
282   void CreateTestMainLayer();
283   void DestroyTestMainLayer();
284   void CreateTestImplLayer(ElementListType element_list_type);
285 
286   void ReleaseRefPtrs();
287 
288   void TickAnimationsTransferEvents(base::TimeTicks time,
289                                     unsigned expect_events);
290 
291   KeyframeEffect* GetKeyframeEffectForElementId(ElementId element_id);
292   KeyframeEffect* GetImplKeyframeEffectForLayerId(ElementId element_id);
293 
294   int NextTestLayerId();
295 
296   bool CheckKeyframeEffectTimelineNeedsPushProperties(
297       bool needs_push_properties) const;
298 
299   void PushProperties();
300 
301   TestHostClient client_;
302   TestHostClient client_impl_;
303 
304   AnimationHost* host_;
305   AnimationHost* host_impl_;
306 
307   const int timeline_id_;
308   const int animation_id_;
309   ElementId element_id_;
310 
311   int next_test_layer_id_;
312 
313   scoped_refptr<AnimationTimeline> timeline_;
314   scoped_refptr<Animation> animation_;
315   scoped_refptr<ElementAnimations> element_animations_;
316 
317   scoped_refptr<AnimationTimeline> timeline_impl_;
318   scoped_refptr<Animation> animation_impl_;
319   scoped_refptr<ElementAnimations> element_animations_impl_;
320 };
321 
322 }  // namespace cc
323 
324 #endif  // CC_TEST_ANIMATION_TIMELINES_TEST_COMMON_H_
325