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