• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "sandbox_utils.h"
19 
20 #include "animation/rs_animation_callback.h"
21 #include "animation/rs_animation_common.h"
22 #include "animation/rs_animation_trace_utils.h"
23 #include "animation/rs_render_animation.h"
24 #include "command/rs_animation_command.h"
25 #include "modifier/rs_modifier_manager.h"
26 #include "modifier/rs_modifier_manager_map.h"
27 #include "platform/common/rs_log.h"
28 #include "rs_trace.h"
29 #include "transaction/rs_transaction_proxy.h"
30 #include "ui/rs_node.h"
31 #include "ui/rs_ui_context.h"
32 
33 namespace OHOS {
34 namespace Rosen {
35 
GenerateId()36 AnimationId RSAnimation::GenerateId()
37 {
38     static pid_t pid_ = GetRealPid();
39     static std::atomic<uint32_t> currentId_ = 0;
40 
41     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
42     if (currentId == UINT32_MAX) {
43         ROSEN_LOGE("Animation Id overflow");
44     }
45 
46     // concat two 32-bit numbers to one 64-bit number
47     return ((AnimationId)pid_ << 32) | (currentId);
48 }
49 
RSAnimation()50 RSAnimation::RSAnimation() : id_(GenerateId()) {}
51 
~RSAnimation()52 RSAnimation::~RSAnimation()
53 {
54     RSNodeMap::MutableInstance().UnregisterAnimation(id_);
55 }
56 
SetFinishCallback(const std::function<void ()> & finishCallback)57 void RSAnimation::SetFinishCallback(const std::function<void()>& finishCallback)
58 {
59     if (finishCallback == nullptr) {
60         ROSEN_LOGE("Failed to set finish callback, callback is null!");
61         return;
62     }
63 
64     SetFinishCallback(std::make_shared<AnimationFinishCallback>(finishCallback));
65 }
66 
SetFinishCallback(const std::shared_ptr<AnimationFinishCallback> & finishCallback)67 void RSAnimation::SetFinishCallback(const std::shared_ptr<AnimationFinishCallback>& finishCallback)
68 {
69     finishCallback_ = finishCallback;
70     auto target = target_.lock();
71     if (target != nullptr) {
72         RSAnimationTraceUtils::GetInstance().AddAnimationFinishTrace(
73             "Animation Set FinishCallback", target->GetId(), id_, true);
74     }
75 }
76 
SetRepeatCallback(const std::shared_ptr<AnimationRepeatCallback> & repeatCallback)77 void RSAnimation::SetRepeatCallback(const std::shared_ptr<AnimationRepeatCallback>& repeatCallback)
78 {
79     repeatCallback_ = repeatCallback;
80 }
81 
SetInteractiveFinishCallback(const std::shared_ptr<InteractiveAnimatorFinishCallback> & finishCallback)82 void RSAnimation::SetInteractiveFinishCallback(
83     const std::shared_ptr<InteractiveAnimatorFinishCallback>& finishCallback)
84 {
85     interactiveFinishCallback_ = finishCallback;
86 }
87 
CallFinishCallback()88 void RSAnimation::CallFinishCallback()
89 {
90     finishCallback_.reset();
91     interactiveFinishCallback_.reset();
92     state_ = AnimationState::FINISHED;
93     OnCallFinishCallback();
94     auto target = target_.lock();
95     if (target == nullptr) {
96         return;
97     }
98     RSAnimationTraceUtils::GetInstance().AddAnimationCallFinishTrace(target->GetId(), id_, GetPropertyType(), true);
99 }
100 
CallRepeatCallback()101 void RSAnimation::CallRepeatCallback()
102 {
103     if (repeatCallback_ == nullptr) {
104         return;
105     }
106     repeatCallback_->Execute();
107 }
108 
CallLogicallyFinishCallback()109 void RSAnimation::CallLogicallyFinishCallback()
110 {
111     finishCallback_.reset();
112 }
113 
GetId() const114 AnimationId RSAnimation::GetId() const
115 {
116     return id_;
117 }
118 
IsStarted() const119 bool RSAnimation::IsStarted() const
120 {
121     return state_ != AnimationState::INITIALIZED;
122 }
123 
IsRunning() const124 bool RSAnimation::IsRunning() const
125 {
126     return state_ == AnimationState::RUNNING;
127 }
128 
IsPaused() const129 bool RSAnimation::IsPaused() const
130 {
131     return state_ == AnimationState::PAUSED;
132 }
133 
IsFinished() const134 bool RSAnimation::IsFinished() const
135 {
136     return state_ == AnimationState::FINISHED;
137 }
138 
Start(const std::shared_ptr<RSNode> & target)139 void RSAnimation::Start(const std::shared_ptr<RSNode>& target)
140 {
141     if (state_ != AnimationState::INITIALIZED) {
142         ROSEN_LOGD("State error, animation is in [%{public}d] when start.", state_);
143         return;
144     }
145 
146     if (target == nullptr) {
147         ROSEN_LOGE("Failed to start animation, target is null!");
148         return;
149     }
150 
151     target->AddAnimation(shared_from_this());
152 }
153 
StartInner(const std::shared_ptr<RSNode> & target)154 void RSAnimation::StartInner(const std::shared_ptr<RSNode>& target)
155 {
156     if (target == nullptr) {
157         ROSEN_LOGE("Failed to start animation, target is null!");
158         return;
159     }
160 
161     target_ = target;
162     state_ = AnimationState::RUNNING;
163     OnStart();
164     UpdateStagingValue(true);
165 }
166 
IsReversed() const167 bool RSAnimation::IsReversed() const
168 {
169     return isReversed_;
170 }
171 
GetTarget() const172 const std::weak_ptr<RSNode> RSAnimation::GetTarget() const
173 {
174     return target_;
175 }
176 
Pause()177 void RSAnimation::Pause()
178 {
179     if (state_ != AnimationState::RUNNING) {
180         ROSEN_LOGD("State error, animation is in [%{public}d] when pause", state_);
181         return;
182     }
183 
184     auto target = target_.lock();
185     if (target == nullptr) {
186         ROSEN_LOGE("Failed to pause animation, target is null!");
187         return;
188     }
189 
190     state_ = AnimationState::PAUSED;
191     OnPause();
192 }
193 
OnPause()194 void RSAnimation::OnPause()
195 {
196     if (uiAnimation_ != nullptr) {
197         uiAnimation_->Pause();
198         return;
199     }
200 
201     auto target = target_.lock();
202     if (target == nullptr) {
203         ROSEN_LOGE("Failed to pause animation, target is null!");
204         return;
205     }
206     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] send pause", id_);
207     RS_TRACE_NAME_FMT("Animation[%llu] send pause", id_);
208     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationPause>(target->GetId(), id_);
209     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
210     if (target->NeedForcedSendToRemote()) {
211         std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSAnimationPause>(target->GetId(), id_);
212         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
213     }
214     if (finishCallback_) {
215         finishCallback_->SetAnimationBeenPaused();
216     }
217 }
218 
IsUiAnimation() const219 bool RSAnimation::IsUiAnimation() const
220 {
221     return uiAnimation_ != nullptr;
222 }
223 
InteractivePause()224 void RSAnimation::InteractivePause()
225 {
226     if (state_ != AnimationState::RUNNING) {
227         ROSEN_LOGD("State error, animation is in [%{public}d] when pause", state_);
228         return;
229     }
230 
231     auto target = target_.lock();
232     if (target == nullptr) {
233         ROSEN_LOGE("Failed to interactive pause animation, target is null!");
234         return;
235     }
236 
237     state_ = AnimationState::PAUSED;
238 
239     if (uiAnimation_ != nullptr) {
240         uiAnimation_->Pause();
241     }
242     if (finishCallback_) {
243         finishCallback_->SetAnimationBeenPaused();
244     }
245 }
246 
InteractiveContinue()247 void RSAnimation::InteractiveContinue()
248 {
249     if (state_ != AnimationState::PAUSED) {
250         ROSEN_LOGD("State error, animation is in [%{public}d] when continue", state_);
251         return;
252     }
253 
254     auto target = target_.lock();
255     if (target == nullptr) {
256         ROSEN_LOGE("Failed to interactive continue animation, target is null!");
257         return;
258     }
259 
260     state_ = AnimationState::RUNNING;
261 
262     if (uiAnimation_ != nullptr) {
263         uiAnimation_->Resume();
264     }
265 }
266 
InteractiveFinish(RSInteractiveAnimationPosition pos)267 void RSAnimation::InteractiveFinish(RSInteractiveAnimationPosition pos)
268 {
269     if (state_ != AnimationState::RUNNING && state_ != AnimationState::PAUSED) {
270         ROSEN_LOGD("Animation is in [%{public}d] when Finish", state_);
271         return;
272     }
273     auto target = target_.lock();
274     if (target == nullptr) {
275         ROSEN_LOGE("Failed to interactive finish animation, target is null!");
276         return;
277     }
278     state_ = AnimationState::FINISHED;
279 
280     if (uiAnimation_ != nullptr) {
281         uiAnimation_->FinishOnPosition(pos);
282     }
283     UpdateStagingValueOnInteractiveFinish(pos);
284 }
285 
InteractiveReverse()286 void RSAnimation::InteractiveReverse()
287 {
288     if (state_ != AnimationState::PAUSED) {
289         ROSEN_LOGD("Animation is in [%{public}d] when Reverse", state_);
290         return;
291     }
292 
293     auto target = target_.lock();
294     if (target == nullptr) {
295         ROSEN_LOGE("Failed to pause animation, target is null!");
296         return;
297     }
298     isReversed_ = true;
299     state_ = AnimationState::RUNNING;
300 
301     OnUpdateStagingValue(false);
302 
303     if (uiAnimation_ != nullptr) {
304         uiAnimation_->SetReversedAndContinue();
305         return;
306     }
307 }
308 
InteractiveSetFraction(float fraction)309 void RSAnimation::InteractiveSetFraction(float fraction)
310 {
311     if (state_ != AnimationState::PAUSED) {
312         ROSEN_LOGD("State error, animation is in [%{public}d] when pause", state_);
313         return;
314     }
315 
316     auto target = target_.lock();
317     if (target == nullptr) {
318         ROSEN_LOGE("Failed to pause animation, target is null!");
319         return;
320     }
321 
322     if (uiAnimation_ != nullptr) {
323         uiAnimation_->SetFraction(fraction);
324     }
325 }
326 
Resume()327 void RSAnimation::Resume()
328 {
329     if (state_ != AnimationState::PAUSED) {
330         ROSEN_LOGD("State error, animation is in [%{public}d] when Resume", state_);
331         return;
332     }
333 
334     auto target = target_.lock();
335     if (target == nullptr) {
336         ROSEN_LOGE("Failed to resume animation, target is null!");
337         return;
338     }
339 
340     state_ = AnimationState::RUNNING;
341     OnResume();
342 }
343 
OnResume()344 void RSAnimation::OnResume()
345 {
346     if (uiAnimation_ != nullptr) {
347         uiAnimation_->Resume();
348         return;
349     }
350 
351     auto target = target_.lock();
352     if (target == nullptr) {
353         ROSEN_LOGE("Failed to resume animation, target is null!");
354         return;
355     }
356     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] send resume", id_);
357     RS_TRACE_NAME_FMT("Animation[%llu] send resume", id_);
358 
359     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationResume>(target->GetId(), id_);
360     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
361     if (target->NeedForcedSendToRemote()) {
362         std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSAnimationResume>(target->GetId(), id_);
363         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
364     }
365 }
366 
Finish()367 void RSAnimation::Finish()
368 {
369     if (state_ != AnimationState::RUNNING && state_ != AnimationState::PAUSED) {
370         ROSEN_LOGD("Animation is in [%{public}d] when Finish", state_);
371         return;
372     }
373 
374     auto target = target_.lock();
375     if (target == nullptr) {
376         ROSEN_LOGE("Failed to finish animation, target is null!");
377         return;
378     }
379 
380     state_ = AnimationState::FINISHED;
381     OnFinish();
382 }
383 
OnFinish()384 void RSAnimation::OnFinish()
385 {
386     if (uiAnimation_ != nullptr) {
387         uiAnimation_->Finish();
388         return;
389     }
390 
391     auto target = target_.lock();
392     if (target == nullptr) {
393         ROSEN_LOGE("Failed to finish animation, target is null!");
394         return;
395     }
396     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] send finish", id_);
397     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationFinish>(target->GetId(), id_);
398     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
399     if (target->NeedForcedSendToRemote()) {
400         std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSAnimationFinish>(target->GetId(), id_);
401         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
402     }
403 }
404 
Reverse()405 void RSAnimation::Reverse()
406 {
407     if (state_ != AnimationState::RUNNING && state_ != AnimationState::PAUSED) {
408         ROSEN_LOGD("State error, animation is in [%{public}d] when Reverse", state_);
409         return;
410     }
411 
412     auto target = target_.lock();
413     if (target == nullptr) {
414         ROSEN_LOGE("Failed to reverse animation, target is null!");
415         return;
416     }
417 
418     isReversed_ = !isReversed_;
419     OnReverse();
420     UpdateStagingValue(false);
421 }
422 
OnReverse()423 void RSAnimation::OnReverse()
424 {
425     if (uiAnimation_ != nullptr) {
426         uiAnimation_->SetReversed(isReversed_);
427         return;
428     }
429 
430     auto target = target_.lock();
431     if (target == nullptr) {
432         ROSEN_LOGE("Failed to reverse animation, target is null!");
433         return;
434     }
435     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationReverse>(target->GetId(), id_, isReversed_);
436     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
437     if (target->NeedForcedSendToRemote()) {
438         std::unique_ptr<RSCommand> commandForRemote =
439             std::make_unique<RSAnimationReverse>(target->GetId(), id_, isReversed_);
440         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
441     }
442 }
443 
SetFraction(float fraction)444 void RSAnimation::SetFraction(float fraction)
445 {
446     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX) {
447         ROSEN_LOGE("Fraction[%{public}f] is invalid!", fraction);
448         return;
449     }
450 
451     if (state_ != AnimationState::PAUSED) {
452         ROSEN_LOGD("State error, animation is in [%{public}d] when SetFraction", state_);
453         return;
454     }
455 
456     auto target = target_.lock();
457     if (target == nullptr) {
458         ROSEN_LOGE("Failed to set fraction, target is null!");
459         return;
460     }
461 
462     OnSetFraction(fraction);
463 }
464 
OnSetFraction(float fraction)465 void RSAnimation::OnSetFraction(float fraction)
466 {
467     if (uiAnimation_ != nullptr) {
468         uiAnimation_->SetFraction(fraction);
469         return;
470     }
471 
472     auto target = target_.lock();
473     if (target == nullptr) {
474         ROSEN_LOGE("Failed to set fraction, target is null!");
475         return;
476     }
477 
478     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationSetFraction>(target->GetId(), id_, fraction);
479     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
480     if (target->NeedForcedSendToRemote()) {
481         std::unique_ptr<RSCommand> commandForRemote =
482             std::make_unique<RSAnimationSetFraction>(target->GetId(), id_, fraction);
483         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
484     }
485 }
486 
GetPropertyId() const487 PropertyId RSAnimation::GetPropertyId() const
488 {
489     return 0;
490 }
491 
UpdateStagingValue(bool isFirstStart)492 void RSAnimation::UpdateStagingValue(bool isFirstStart)
493 {
494     OnUpdateStagingValue(isFirstStart);
495 }
496 
UpdateParamToRenderAnimation(const std::shared_ptr<RSRenderAnimation> & animation)497 void RSAnimation::UpdateParamToRenderAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
498 {
499     if (animation == nullptr) {
500         ROSEN_LOGD("Animation is null, failed to update param.");
501         return;
502     }
503     animation->SetDuration(GetDuration());
504     animation->SetStartDelay(GetStartDelay());
505     animation->SetRepeatCount(GetRepeatCount());
506     animation->SetAutoReverse(GetAutoReverse());
507     animation->SetSpeed(GetSpeed());
508     animation->SetDirection(GetDirection());
509     animation->SetFillMode(GetFillMode());
510     animation->SetRepeatCallbackEnable(repeatCallback_ != nullptr);
511     // only process FrameRateRange(rs) here
512     if (uiAnimation_ == nullptr) {
513         auto range = GetFrameRateRange();
514         // Transfer frame rate and component informations
515         if (range.IsValid() || range.componentScene_ != ComponentScene::UNKNOWN_SCENE) {
516             animation->SetFrameRateRange(range);
517         }
518     }
519     // set token to RSRenderAnimation
520     if (auto target = target_.lock()) {
521         if (auto context = target->GetRSUIContext()) {
522             animation->SetToken(context->GetToken());
523         }
524     } else {
525         ROSEN_LOGE("multi-instance, RSAnimation::UpdateParamToRenderAnimation, target is null!");
526     }
527 }
528 
StartCustomAnimation(const std::shared_ptr<RSRenderAnimation> & animation)529 void RSAnimation::StartCustomAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
530 {
531     auto target = target_.lock();
532     if (target == nullptr) {
533         ROSEN_LOGE("multi-instance, RSAnimation::StartCustomAnimation, target is null!");
534         return;
535     }
536     auto rsUIContext = target->GetRSUIContext();
537     auto modifierManager = rsUIContext ? rsUIContext->GetRSModifierManager()
538                                        : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
539     if (modifierManager == nullptr || animation == nullptr) {
540         ROSEN_LOGE("Failed to start custom animation, modifier manager is null  animationId: %{public}" PRIu64 "!",
541             GetId());
542         return;
543     }
544 
545     uiAnimation_ = animation;
546     animation->targetId_ = target->GetId();
547     animation->Start();
548     modifierManager->AddAnimation(animation);
549 }
550 
DumpAnimation() const551 std::string RSAnimation::DumpAnimation() const
552 {
553     std::string dumpInfo;
554     dumpInfo.append("[id:").append(std::to_string(GetId()));
555     dumpInfo.append(", AnimationState:").append(std::to_string(static_cast<int>(state_)));
556     DumpAnimationInfo(dumpInfo);
557     dumpInfo.append(", Duration:").append(std::to_string(GetDuration()));
558     dumpInfo.append(", StartDelay:").append(std::to_string(GetStartDelay()));
559     dumpInfo.append(", RepeatCount:").append(std::to_string(GetRepeatCount())).append("]");
560     return dumpInfo;
561 }
562 
563 } // namespace Rosen
564 } // namespace OHOS
565