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