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