• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 
16 #include "animation/rs_animation.h"
17 
18 #include "animation/rs_animation_callback.h"
19 #include "animation/rs_animation_common.h"
20 #include "animation/rs_render_animation.h"
21 #include "command/rs_animation_command.h"
22 #include "platform/common/rs_log.h"
23 #include "transaction/rs_transaction_proxy.h"
24 #include "ui/rs_node.h"
25 #include "sandbox_utils.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 
GenerateId()30 AnimationId RSAnimation::GenerateId()
31 {
32     static pid_t pid_ = GetRealPid();
33     static std::atomic<uint32_t> currentId_ = 0;
34 
35     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
36     if (currentId == UINT32_MAX) {
37         ROSEN_LOGE("Animation Id overflow");
38     }
39 
40     // concat two 32-bit numbers to one 64-bit number
41     return ((AnimationId)pid_ << 32) | (currentId);
42 }
43 
RSAnimation()44 RSAnimation::RSAnimation() : id_(GenerateId()) {}
45 
SetFinishCallback(const std::function<void ()> & finishCallback)46 void RSAnimation::SetFinishCallback(const std::function<void()>& finishCallback)
47 {
48     if (finishCallback == nullptr) {
49         ROSEN_LOGE("Failed to set finish callback, callback is null!");
50         return;
51     }
52 
53     SetFinishCallback(std::make_shared<AnimationFinishCallback>(finishCallback));
54 }
55 
SetFinishCallback(const std::shared_ptr<AnimationFinishCallback> & finishCallback)56 void RSAnimation::SetFinishCallback(const std::shared_ptr<AnimationFinishCallback>& finishCallback)
57 {
58     finishCallback_ = finishCallback;
59 }
60 
CallFinishCallback()61 void RSAnimation::CallFinishCallback()
62 {
63     finishCallback_.reset();
64     state_ = AnimationState::FINISHED;
65     OnCallFinishCallback();
66 }
67 
UIAnimationFinish()68 void RSAnimation::UIAnimationFinish()
69 {
70     auto target = GetTarget().lock();
71     if (target != nullptr) {
72         target->AnimationFinish(GetId());
73     }
74 }
75 
GetId() const76 AnimationId RSAnimation::GetId() const
77 {
78     return id_;
79 }
80 
IsStarted() const81 bool RSAnimation::IsStarted() const
82 {
83     return state_ != AnimationState::INITIALIZED;
84 }
85 
IsRunning() const86 bool RSAnimation::IsRunning() const
87 {
88     return state_ == AnimationState::RUNNING;
89 }
90 
IsPaused() const91 bool RSAnimation::IsPaused() const
92 {
93     return state_ == AnimationState::PAUSED;
94 }
95 
IsFinished() const96 bool RSAnimation::IsFinished() const
97 {
98     return state_ == AnimationState::FINISHED;
99 }
100 
Start(const std::shared_ptr<RSNode> & target)101 void RSAnimation::Start(const std::shared_ptr<RSNode>& target)
102 {
103     if (state_ != AnimationState::INITIALIZED) {
104         ROSEN_LOGE("State error, animation is in [%d] when start.", state_);
105         return;
106     }
107 
108     if (target == nullptr) {
109         ROSEN_LOGE("Failed to start animation, target is null!");
110         return;
111     }
112 
113     target->AddAnimation(shared_from_this());
114 }
115 
StartInner(const std::shared_ptr<RSNode> & target)116 void RSAnimation::StartInner(const std::shared_ptr<RSNode>& target)
117 {
118     if (target == nullptr) {
119         ROSEN_LOGE("Failed to start animation, target is null!");
120         return;
121     }
122 
123     target_ = target;
124     state_ = AnimationState::RUNNING;
125     OnStart();
126     UpdateStagingValue(true);
127 }
128 
IsReversed() const129 bool RSAnimation::IsReversed() const
130 {
131     return isReversed_;
132 }
133 
GetTarget() const134 const std::weak_ptr<RSNode> RSAnimation::GetTarget() const
135 {
136     return target_;
137 }
138 
Pause()139 void RSAnimation::Pause()
140 {
141     if (state_ != AnimationState::RUNNING) {
142         ROSEN_LOGE("State error, animation is in [%d] when pause", state_);
143         return;
144     }
145 
146     auto target = target_.lock();
147     if (target == nullptr) {
148         ROSEN_LOGE("Failed to pause animation, target is null!");
149         return;
150     }
151 
152     state_ = AnimationState::PAUSED;
153     OnPause();
154 }
155 
OnPause()156 void RSAnimation::OnPause()
157 {
158     auto target = target_.lock();
159     if (target == nullptr) {
160         ROSEN_LOGE("Failed to pause animation, target is null!");
161         return;
162     }
163 
164     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationPause>(target->GetId(), id_);
165     auto transactionProxy = RSTransactionProxy::GetInstance();
166     if (transactionProxy != nullptr) {
167         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
168         if (target->NeedForcedSendToRemote()) {
169             std::unique_ptr<RSCommand> commandForRemote =
170                 std::make_unique<RSAnimationPause>(target->GetId(), id_);
171             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
172         }
173         if (target->NeedSendExtraCommand()) {
174             std::unique_ptr<RSCommand> extraCommand =
175                 std::make_unique<RSAnimationPause>(target->GetId(), id_);
176             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
177                 target->GetId());
178         }
179     }
180 }
181 
Resume()182 void RSAnimation::Resume()
183 {
184     if (state_ != AnimationState::PAUSED) {
185         ROSEN_LOGE("State error, animation is in [%d] when Resume", state_);
186         return;
187     }
188 
189     auto target = target_.lock();
190     if (target == nullptr) {
191         ROSEN_LOGE("Failed to resume animation, target is null!");
192         return;
193     }
194 
195     state_ = AnimationState::RUNNING;
196     OnResume();
197 }
198 
OnResume()199 void RSAnimation::OnResume()
200 {
201     auto target = target_.lock();
202     if (target == nullptr) {
203         ROSEN_LOGE("Failed to resume animation, target is null!");
204         return;
205     }
206 
207     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationResume>(target->GetId(), id_);
208     auto transactionProxy = RSTransactionProxy::GetInstance();
209     if (transactionProxy != nullptr) {
210         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
211         if (target->NeedForcedSendToRemote()) {
212             std::unique_ptr<RSCommand> commandForRemote =
213                 std::make_unique<RSAnimationResume>(target->GetId(), id_);
214             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
215         }
216         if (target->NeedSendExtraCommand()) {
217             std::unique_ptr<RSCommand> extraCommand =
218                 std::make_unique<RSAnimationResume>(target->GetId(), id_);
219             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
220                 target->GetId());
221         }
222     }
223 }
224 
Finish()225 void RSAnimation::Finish()
226 {
227     if (state_ != AnimationState::RUNNING && state_ != AnimationState::PAUSED) {
228         ROSEN_LOGE("State error, animation is in [%d] when Finish", state_);
229         return;
230     }
231 
232     auto target = target_.lock();
233     if (target == nullptr) {
234         ROSEN_LOGE("Failed to finish animation, target is null!");
235         return;
236     }
237 
238     state_ = AnimationState::FINISHED;
239     OnFinish();
240 }
241 
OnFinish()242 void RSAnimation::OnFinish()
243 {
244     auto target = target_.lock();
245     if (target == nullptr) {
246         ROSEN_LOGE("Failed to finish animation, target is null!");
247         return;
248     }
249 
250     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationFinish>(target->GetId(), id_);
251     auto transactionProxy = RSTransactionProxy::GetInstance();
252     if (transactionProxy != nullptr) {
253         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
254         if (target->NeedForcedSendToRemote()) {
255             std::unique_ptr<RSCommand> commandForRemote =
256                 std::make_unique<RSAnimationFinish>(target->GetId(), id_);
257             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
258         }
259         if (target->NeedSendExtraCommand()) {
260             std::unique_ptr<RSCommand> extraCommand =
261                 std::make_unique<RSAnimationFinish>(target->GetId(), id_);
262             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
263                 target->GetId());
264         }
265     }
266 }
267 
Reverse()268 void RSAnimation::Reverse()
269 {
270     if (state_ != AnimationState::RUNNING && state_ != AnimationState::PAUSED) {
271         ROSEN_LOGE("State error, animation is in [%d] when Reverse", state_);
272         return;
273     }
274 
275     auto target = target_.lock();
276     if (target == nullptr) {
277         ROSEN_LOGE("Failed to reverse animation, target is null!");
278         return;
279     }
280 
281     isReversed_ = !isReversed_;
282     OnReverse();
283     UpdateStagingValue(false);
284 }
285 
OnReverse()286 void RSAnimation::OnReverse()
287 {
288     auto target = target_.lock();
289     if (target == nullptr) {
290         ROSEN_LOGE("Failed to reverse animation, target is null!");
291         return;
292     }
293 
294     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationReverse>(target->GetId(), id_, isReversed_);
295     auto transactionProxy = RSTransactionProxy::GetInstance();
296     if (transactionProxy != nullptr) {
297         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
298         if (target->NeedForcedSendToRemote()) {
299             std::unique_ptr<RSCommand> commandForRemote =
300                 std::make_unique<RSAnimationReverse>(target->GetId(), id_, isReversed_);
301             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
302         }
303         if (target->NeedSendExtraCommand()) {
304             std::unique_ptr<RSCommand> extraCommand =
305                 std::make_unique<RSAnimationReverse>(target->GetId(), id_, isReversed_);
306             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
307                 target->GetId());
308         }
309     }
310 }
311 
SetFraction(float fraction)312 void RSAnimation::SetFraction(float fraction)
313 {
314     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX) {
315         ROSEN_LOGE("Fraction[%f] is invalid!", fraction);
316         return;
317     }
318 
319     if (state_ != AnimationState::PAUSED) {
320         ROSEN_LOGE("State error, animation is in [%d] when SetFraction", state_);
321         return;
322     }
323 
324     auto target = target_.lock();
325     if (target == nullptr) {
326         ROSEN_LOGE("Failed to set fraction, target is null!");
327         return;
328     }
329 
330     OnSetFraction(fraction);
331 }
332 
OnSetFraction(float fraction)333 void RSAnimation::OnSetFraction(float fraction)
334 {
335     auto target = target_.lock();
336     if (target == nullptr) {
337         ROSEN_LOGE("Failed to set fraction, target is null!");
338         return;
339     }
340 
341     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationSetFraction>(target->GetId(), id_, fraction);
342     auto transactionProxy = RSTransactionProxy::GetInstance();
343     if (transactionProxy != nullptr) {
344         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
345         if (target->NeedForcedSendToRemote()) {
346             std::unique_ptr<RSCommand> commandForRemote =
347                 std::make_unique<RSAnimationSetFraction>(target->GetId(), id_, fraction);
348             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
349         }
350         if (target->NeedSendExtraCommand()) {
351             std::unique_ptr<RSCommand> extraCommand =
352                 std::make_unique<RSAnimationSetFraction>(target->GetId(), id_, fraction);
353             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
354                 target->GetId());
355         }
356     }
357 }
358 
GetPropertyId() const359 PropertyId RSAnimation::GetPropertyId() const
360 {
361     return 0;
362 }
363 
UpdateStagingValue(bool isFirstStart)364 void RSAnimation::UpdateStagingValue(bool isFirstStart)
365 {
366     OnUpdateStagingValue(isFirstStart);
367 }
368 
UpdateParamToRenderAnimation(const std::shared_ptr<RSRenderAnimation> & animation)369 void RSAnimation::UpdateParamToRenderAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
370 {
371     animation->SetDuration(GetDuration());
372     animation->SetStartDelay(GetStartDelay());
373     animation->SetRepeatCount(GetRepeatCount());
374     animation->SetAutoReverse(GetAutoReverse());
375     animation->SetSpeed(GetSpeed());
376     animation->SetDirection(GetDirection());
377     animation->SetFillMode(GetFillMode());
378 }
379 } // namespace Rosen
380 } // namespace OHOS
381