• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 #include <meta/api/animation.h>
19 #include <meta/api/property/property_event_handler.h>
20 #include <meta/api/util.h>
21 #include <meta/base/namespace.h>
22 #include <meta/interface/animation/builtin_animations.h>
23 #include <meta/interface/animation/intf_animation_controller.h>
24 #include <meta/interface/property/construct_property.h>
25 
26 #include "TestRunner.h"
27 #include "helpers/animation_test_base.h"
28 #include "helpers/serialisation_utils.h"
29 #include "helpers/testing_objects.h"
30 
31 using namespace testing;
32 using namespace testing::ext;
33 
34 META_BEGIN_NAMESPACE()
35 
36 class AnimationControllerTest : public AnimationTestBase {
37 public:
SetUpTestSuite()38     static void SetUpTestSuite()
39     {
40         SetTest();
41     }
TearDownTestSuite()42     static void TearDownTestSuite()
43     {
44         TearDownTest();
45     }
SetUp()46     void SetUp() override
47     {
48         AnimationTestBase::SetUp();
49 
50         property_ = META_NS::ConstructProperty<float>("prop", 0.f);
51         sutAnimationCtrl_ = META_NS::GetAnimationController();
52         ASSERT_THAT(sutAnimationCtrl_, testing::NotNull());
53     }
54 
TearDown()55     void TearDown() override
56     {
57         auto count = GetValue(sutAnimationCtrl_->Count());
58 
59         sutAnimationCtrl_->Clear();
60 
61         count = GetValue(sutAnimationCtrl_->Count());
62 
63         ASSERT_EQ(sutAnimationCtrl_->GetRunning().size(), 0);
64         AnimationTestBase::TearDown();
65     }
66 
CreateAnimation()67     META_NS::KeyframeAnimation<float> CreateAnimation()
68     {
69         auto animation = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
70         animation.SetProperty(property_);
71         animation.SetFrom(0.f);
72         animation.SetTo(10.f);
73         animation.SetDuration(ANIMATION_LENGTH);
74         animation.SetController(sutAnimationCtrl_);
75         return animation;
76     }
77 
78     static constexpr auto ANIMATION_LENGTH = TimeSpan::Milliseconds(100);
79 
80     META_NS::Property<float> property_;
81     META_NS::IAnimationController::Ptr sutAnimationCtrl_;
82 };
83 
84 /**
85  * @tc.name: RunningAnimationListContainsStartedAnimations
86  * @tc.desc: test RunningAnimationListContainsStartedAnimations
87  * @tc.type: FUNC
88  */
89 HWTEST_F(AnimationControllerTest, RunningAnimationListContainsStartedAnimations, TestSize.Level1)
90 {
91     // given
92     auto anim = CreateAnimation();
93 
94     // when
95     anim.Start();
96 
97     // expected
98     ASSERT_EQ(anim.GetRunning(), true);
99     const auto runningAnimations = sutAnimationCtrl_->GetRunning();
100     ASSERT_THAT(runningAnimations.size(), testing::Eq(1));
101     EXPECT_THAT(runningAnimations[0].lock(), testing::Eq(anim));
102 }
103 
104 /**
105  * @tc.name: RunningAnimationListIsEmptyWhenAllAnimationsWereStopped
106  * @tc.desc: test RunningAnimationListIsEmptyWhenAllAnimationsWereStopped
107  * @tc.type: FUNC
108  */
109 HWTEST_F(AnimationControllerTest, RunningAnimationListIsEmptyWhenAllAnimationsWereStopped, TestSize.Level1)
110 {
111     // given
112     auto anim = CreateAnimation();
113 
114     // when
115     anim.Start();
116     anim.Stop();
117 
118     // expected
119     ASSERT_EQ(anim.GetRunning(), false);
120     EXPECT_TRUE(sutAnimationCtrl_->GetRunning().empty());
121 }
122 
123 /**
124  * @tc.name: RunningAnimationListContainsResumedAnimations
125  * @tc.desc: test RunningAnimationListContainsResumedAnimations
126  * @tc.type: FUNC
127  */
128 HWTEST_F(AnimationControllerTest, RunningAnimationListContainsResumedAnimations, TestSize.Level1)
129 {
130     // given
131     auto anim = CreateAnimation();
132 
133     // when
134     anim.Start();
135     anim.Pause();
136     anim.Start();
137 
138     // expected
139     ASSERT_EQ(anim.GetRunning(), true);
140     const auto runningAnimations = sutAnimationCtrl_->GetRunning();
141     ASSERT_THAT(runningAnimations.size(), testing::Eq(1));
142     EXPECT_THAT(runningAnimations[0].lock(), testing::Eq(anim));
143 }
144 
145 /**
146  * @tc.name: RunningAnimationListIsEmptyWhenAllAnimationsWereFinished
147  * @tc.desc: test RunningAnimationListIsEmptyWhenAllAnimationsWereFinished
148  * @tc.type: FUNC
149  */
150 HWTEST_F(AnimationControllerTest, RunningAnimationListIsEmptyWhenAllAnimationsWereFinished, TestSize.Level1)
151 {
152     // given
153     auto anim = CreateAnimation();
154 
155     // when
156     anim.Start();
157     StepAnimationController(0);
158     StepAnimationController(ANIMATION_LENGTH.ToMilliseconds());
159 
160     // expected
161     ASSERT_EQ(anim.GetRunning(), false);
162     ASSERT_EQ(anim.GetProgress(), 1.f);
163     EXPECT_TRUE(sutAnimationCtrl_->GetRunning().empty());
164 }
165 
166 /**
167  * @tc.name: AnimationControllerUpdatesControllerPropOfAddedAnimation
168  * @tc.desc: test AnimationControllerUpdatesControllerPropOfAddedAnimation
169  * @tc.type: FUNC
170  */
171 HWTEST_F(AnimationControllerTest, AnimationControllerUpdatesControllerPropOfAddedAnimation, TestSize.Level1)
172 {
173     // given
174     auto anim = CreateAnimation();
175     anim.SetController({});
176     ASSERT_TRUE(anim.GetController().expired());
177 
178     // when
179     sutAnimationCtrl_->AddAnimation(anim);
180 
181     // expected
182     ASSERT_FALSE(anim.GetController().expired());
183     EXPECT_THAT(anim.GetController().lock(), testing::Eq(sutAnimationCtrl_));
184 }
185 
186 /**
187  * @tc.name: Serialization
188  * @tc.desc: test Serialization
189  * @tc.type: FUNC
190  */
191 HWTEST_F(AnimationControllerTest, Serialization, TestSize.Level1)
192 {
193     TestSerialiser ser;
194     static constexpr auto implicitPropertyName = "ImplicitProperty";
195     static constexpr auto keyframePropertyName = "KeyframeProperty";
196 
197     {
198         auto controller = GetObjectRegistry().Create<IAnimationController>(META_NS::ClassId::AnimationController);
199 
200         auto implicitProp = ConstructProperty<float>(implicitPropertyName, 0);
201         auto keyframeProp = ConstructProperty<float>(keyframePropertyName, 0);
202 
203         Object object(CreateInstance(ClassId::Object));
204         Metadata(object).AddProperty(implicitProp);
205         Metadata(object).AddProperty(keyframeProp);
206 
207         auto implicitAnim = PropertyAnimation(CreateInstance(ClassId::PropertyAnimation))
208                                 .SetProperty(implicitProp)
209                                 .SetController(controller);
210         auto keyframeAnim = SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
211         keyframeAnim.SetController(controller);
212         keyframeAnim.Add(KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation))
213                              .SetFrom(0)
214                              .SetTo(10)
215                              .SetProperty(keyframeProp)
216                              .SetDuration(TimeSpan::Milliseconds(100)));
217         keyframeAnim.Add(KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation))
218                              .SetFrom(10)
219                              .SetTo(0)
220                              .SetProperty(keyframeProp)
221                              .SetDuration(TimeSpan::Milliseconds(100)));
222 
223         AttachmentContainer(object).Attach(implicitAnim);
224         AttachmentContainer(object).Attach(keyframeAnim);
225         AttachmentContainer(object).Attach(controller);
226 
227         ASSERT_TRUE(ser.Export(object));
228         ser.Dump("app://animation_ser.ui");
229     }
230 
231     auto obj = ser.Import();
232     ASSERT_TRUE(obj);
233     Object imported(obj);
234     ASSERT_TRUE(imported);
235 
236     auto controllers =
237         AttachmentContainer(imported).GetAttachments({ TypeId(META_NS::InterfaceId::IAnimationController) });
238     ASSERT_EQ(controllers.size(), 1);
239 
240     auto importedController = interface_pointer_cast<IAnimationController>(controllers[0]);
241     EXPECT_EQ(importedController->Count()->GetValue(), 2);
242 
243     auto animations = importedController->GetAnimations();
244     ASSERT_EQ(animations.size(), 2);
245 
246     for (const auto& anim : animations) {
247         auto animation = anim.lock();
248         ASSERT_TRUE(animation);
249         auto controller = animation->Controller()->GetValue().lock();
250         EXPECT_EQ(controller, importedController);
251     }
252 
253     // Check that we got the same animation hierarchy back
254     PropertyAnimation implicitAnim(animations[0].lock());
255     SequentialAnimation seqAnim(animations[1].lock());
256     ASSERT_TRUE(implicitAnim);
257     ASSERT_TRUE(seqAnim);
258     auto children = seqAnim.GetAnimations();
259     ASSERT_EQ(children.size(), 2);
260     KeyframeAnimation<float> segment1(children[0]);
261     ASSERT_TRUE(segment1);
262     EXPECT_TRUE(segment1.GetValid());
263 
264     // Start the sequential animation and check that it works
265     seqAnim.Start();
266     importedController->Step(GetTestClock());
267 
268     EXPECT_TRUE(seqAnim.GetRunning());
269     EXPECT_EQ(seqAnim.GetProgress(), 0);
270     auto progress = seqAnim.GetProgress();
271 
272     for (auto i = 0; i < 5; i++) {
273         IncrementClockTime(TimeSpan::Milliseconds(10));
274         importedController->Step(GetTestClock());
275         auto current = seqAnim.GetProgress();
276         EXPECT_GT(current, progress);
277         progress = current;
278     }
279 }
280 
281 META_END_NAMESPACE()
282