1 /*
2 * Copyright (c) 2022-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 "render_service_client/core/animation/rs_interactive_implict_animator.h"
17
18 #include "core/animation/native_curve_helper.h"
19 #include "core/common/container.h"
20 #include "frameworks/core/pipeline_ng/pipeline_context.h"
21
22 namespace OHOS::Ace {
23
24 namespace {
ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)25 Rosen::FinishCallbackType ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)
26 {
27 if (finishCallbackType == FinishCallbackType::LOGICALLY) {
28 return Rosen::FinishCallbackType::LOGICALLY;
29 } else if (finishCallbackType == FinishCallbackType::REMOVED) {
30 return Rosen::FinishCallbackType::TIME_SENSITIVE;
31 } else {
32 return Rosen::FinishCallbackType::TIME_SENSITIVE;
33 }
34 }
OptionToTimingProtocol(const AnimationOption & option)35 Rosen::RSAnimationTimingProtocol OptionToTimingProtocol(const AnimationOption& option)
36 {
37 Rosen::RSAnimationTimingProtocol timingProtocol;
38 timingProtocol.SetDuration(option.GetDuration());
39 timingProtocol.SetStartDelay(option.GetDelay());
40 timingProtocol.SetSpeed(option.GetTempo());
41 timingProtocol.SetRepeatCount(option.GetIteration());
42 timingProtocol.SetDirection(option.GetAnimationDirection() == AnimationDirection::NORMAL ||
43 option.GetAnimationDirection() == AnimationDirection::ALTERNATE);
44 timingProtocol.SetAutoReverse(option.GetAnimationDirection() == AnimationDirection::ALTERNATE ||
45 option.GetAnimationDirection() == AnimationDirection::ALTERNATE_REVERSE);
46 timingProtocol.SetFillMode(static_cast<Rosen::FillMode>(option.GetFillMode()));
47 timingProtocol.SetFinishCallbackType(ToAnimationFinishCallbackType(option.GetFinishCallbackType()));
48 auto rateRange = option.GetFrameRateRange();
49 if (rateRange) {
50 timingProtocol.SetFrameRateRange({ rateRange->min_, rateRange->max_, rateRange->preferred_, 0,
51 static_cast<Rosen::ComponentScene>(rateRange->componentScene_) });
52 }
53 return timingProtocol;
54 }
GetWrappedCallback(const std::function<void ()> & callback)55 std::function<void()> GetWrappedCallback(const std::function<void()>& callback)
56 {
57 if (!callback) {
58 return nullptr;
59 }
60 auto wrappedOnFinish = [onFinish = callback, instanceId = Container::CurrentIdSafelyWithCheck()]() {
61 ContainerScope scope(instanceId);
62 auto taskExecutor = Container::CurrentTaskExecutor();
63 if (!taskExecutor) {
64 TAG_LOGW(AceLogTag::ACE_ANIMATION, "taskExecutor is nullptr");
65 return;
66 }
67 if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
68 onFinish();
69 return;
70 }
71 taskExecutor->PostTask([onFinish]() { onFinish(); }, TaskExecutor::TaskType::UI,
72 "ArkUIAnimationGetWrappedCallback", PriorityType::HIGH);
73 };
74 return wrappedOnFinish;
75 }
76 } // namespace
77
78 class AnimationUtils::Animation {
79 private:
80 std::vector<std::shared_ptr<OHOS::Rosen::RSAnimation>> animations_;
81
82 friend AnimationUtils;
83 };
84
85 class AnimationUtils::InteractiveAnimation {
86 private:
87 std::shared_ptr<Rosen::RSInteractiveImplictAnimator> interactiveAnimation_;
88 friend AnimationUtils;
89 };
90
SetNavGroupNodeTransAnimationCallback()91 void AnimationUtils::SetNavGroupNodeTransAnimationCallback()
92 {
93 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
94 CHECK_NULL_VOID(pipelineContext);
95 auto navigationManger = pipelineContext->GetNavigationManager();
96 CHECK_NULL_VOID(navigationManger);
97 navigationManger->SetNodeAddAnimation(true);
98 }
99
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)100 void AnimationUtils::OpenImplicitAnimation(
101 const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
102 {
103 const auto& timingProtocol = OptionToTimingProtocol(option);
104 auto wrappedOnFinish = GetWrappedCallback(finishCallback);
105 Rosen::RSNode::OpenImplicitAnimation(timingProtocol, NativeCurveHelper::ToNativeCurve(curve), wrappedOnFinish);
106 }
107
CloseImplicitAnimation()108 bool AnimationUtils::CloseImplicitAnimation()
109 {
110 auto animations = Rosen::RSNode::CloseImplicitAnimation();
111 auto pipeline = PipelineBase::GetCurrentContext();
112 SetNavGroupNodeTransAnimationCallback();
113 if (pipeline && !pipeline->GetOnShow()) {
114 pipeline->FlushMessages();
115 }
116 return !animations.empty();
117 }
118
CloseImplicitCancelAnimation()119 bool AnimationUtils::CloseImplicitCancelAnimation()
120 {
121 return Rosen::RSNode::CloseImplicitCancelAnimation();
122 }
123
IsImplicitAnimationOpen()124 bool AnimationUtils::IsImplicitAnimationOpen()
125 {
126 return Rosen::RSNode::IsImplicitAnimationOpen();
127 }
128
Animate(const AnimationOption & option,const PropertyCallback & callback,const FinishCallback & finishCallback,const RepeatCallback & repeatCallback)129 void AnimationUtils::Animate(const AnimationOption& option, const PropertyCallback& callback,
130 const FinishCallback& finishCallback, const RepeatCallback& repeatCallback)
131 {
132 const auto& timingProtocol = OptionToTimingProtocol(option);
133 auto wrappedOnFinish = GetWrappedCallback(finishCallback);
134 auto wrappedOnRepeat = GetWrappedCallback(repeatCallback);
135 Rosen::RSNode::Animate(timingProtocol, NativeCurveHelper::ToNativeCurve(option.GetCurve()), callback,
136 wrappedOnFinish, wrappedOnRepeat);
137 auto pipeline = PipelineBase::GetCurrentContext();
138 SetNavGroupNodeTransAnimationCallback();
139 if (pipeline && !pipeline->GetOnShow()) {
140 pipeline->FlushMessages();
141 }
142 }
143
AnimateWithCurrentOptions(const PropertyCallback & callback,const FinishCallback & finishCallback,bool timingSensitive)144 void AnimationUtils::AnimateWithCurrentOptions(
145 const PropertyCallback& callback, const FinishCallback& finishCallback, bool timingSensitive)
146 {
147 auto wrappedOnFinish = GetWrappedCallback(finishCallback);
148 Rosen::RSNode::AnimateWithCurrentOptions(callback, wrappedOnFinish, timingSensitive);
149 }
150
AnimateWithCurrentCallback(const AnimationOption & option,const PropertyCallback & callback)151 void AnimationUtils::AnimateWithCurrentCallback(const AnimationOption& option, const PropertyCallback& callback)
152 {
153 const auto& timingProtocol = OptionToTimingProtocol(option);
154 Rosen::RSNode::AnimateWithCurrentCallback(
155 timingProtocol, NativeCurveHelper::ToNativeCurve(option.GetCurve()), callback);
156 }
157
AddKeyFrame(float fraction,const RefPtr<Curve> & curve,const PropertyCallback & callback)158 void AnimationUtils::AddKeyFrame(float fraction, const RefPtr<Curve>& curve, const PropertyCallback& callback)
159 {
160 Rosen::RSNode::AddKeyFrame(fraction, NativeCurveHelper::ToNativeCurve(curve), callback);
161 }
162
AddKeyFrame(float fraction,const PropertyCallback & callback)163 void AnimationUtils::AddKeyFrame(float fraction, const PropertyCallback& callback)
164 {
165 Rosen::RSNode::AddKeyFrame(fraction, callback);
166 }
167
AddDurationKeyFrame(int duration,const RefPtr<Curve> & curve,const PropertyCallback & callback)168 void AnimationUtils::AddDurationKeyFrame(int duration, const RefPtr<Curve>& curve, const PropertyCallback& callback)
169 {
170 Rosen::RSNode::AddDurationKeyFrame(duration, NativeCurveHelper::ToNativeCurve(curve), callback);
171 }
172
StartAnimation(const AnimationOption & option,const PropertyCallback & callback,const FinishCallback & finishCallback,const RepeatCallback & repeatCallback)173 std::shared_ptr<AnimationUtils::Animation> AnimationUtils::StartAnimation(const AnimationOption& option,
174 const PropertyCallback& callback, const FinishCallback& finishCallback, const RepeatCallback& repeatCallback)
175 {
176 std::shared_ptr<AnimationUtils::Animation> animation = std::make_shared<AnimationUtils::Animation>();
177 CHECK_NULL_RETURN(animation, nullptr);
178 const auto& timingProtocol = OptionToTimingProtocol(option);
179 auto wrappedOnFinish = GetWrappedCallback(finishCallback);
180 auto wrappedOnRepeat = GetWrappedCallback(repeatCallback);
181 animation->animations_ = Rosen::RSNode::Animate(timingProtocol, NativeCurveHelper::ToNativeCurve(option.GetCurve()),
182 callback, wrappedOnFinish, wrappedOnRepeat);
183 auto pipeline = PipelineBase::GetCurrentContext();
184 if (pipeline && !pipeline->GetOnShow()) {
185 pipeline->FlushMessages();
186 }
187 if (!animation->animations_.empty()) {
188 return animation;
189 }
190 return nullptr;
191 }
192
StopAnimation(const std::shared_ptr<AnimationUtils::Animation> & animation)193 void AnimationUtils::StopAnimation(const std::shared_ptr<AnimationUtils::Animation>& animation)
194 {
195 CHECK_NULL_VOID(animation);
196 if (!animation->animations_.empty()) {
197 for (auto& ani : animation->animations_) {
198 ani->Finish();
199 }
200 animation->animations_.clear();
201 }
202 }
203
BlendBgColorAnimation(RefPtr<NG::RenderContext> & renderContext,const Color & endColor,int32_t duration,const RefPtr<Curve> & curve)204 void AnimationUtils::BlendBgColorAnimation(
205 RefPtr<NG::RenderContext>& renderContext, const Color& endColor, int32_t duration, const RefPtr<Curve>& curve)
206 {
207 AnimationOption option = AnimationOption();
208 option.SetCurve(curve);
209 option.SetDuration(duration);
210 AnimationUtils::Animate(option, [context = renderContext, color = endColor]() { context->BlendBgColor(color); });
211 }
212
PauseAnimation(const std::shared_ptr<AnimationUtils::Animation> & animation)213 void AnimationUtils::PauseAnimation(const std::shared_ptr<AnimationUtils::Animation>& animation)
214 {
215 CHECK_NULL_VOID(animation);
216 for (auto& ani : animation->animations_) {
217 ani->Pause();
218 }
219 auto pipeline = PipelineBase::GetCurrentContext();
220 if (pipeline && !pipeline->GetOnShow()) {
221 pipeline->FlushMessages();
222 }
223 }
224
ResumeAnimation(const std::shared_ptr<AnimationUtils::Animation> & animation)225 void AnimationUtils::ResumeAnimation(const std::shared_ptr<AnimationUtils::Animation>& animation)
226 {
227 CHECK_NULL_VOID(animation);
228 if (animation->animations_.empty()) {
229 return;
230 }
231 auto pipeline = PipelineBase::GetCurrentContext();
232 if (pipeline) {
233 pipeline->RequestFrame();
234 }
235 for (auto& ani : animation->animations_) {
236 ani->Resume();
237 }
238 }
239
ExecuteWithoutAnimation(const PropertyCallback & callback)240 void AnimationUtils::ExecuteWithoutAnimation(const PropertyCallback& callback)
241 {
242 Rosen::RSNode::ExecuteWithoutAnimation(callback);
243 }
244
CreateInteractiveAnimation(const InteractiveAnimationCallback & addCallback,const FinishCallback & callback)245 std::shared_ptr<AnimationUtils::InteractiveAnimation> AnimationUtils::CreateInteractiveAnimation(
246 const InteractiveAnimationCallback& addCallback, const FinishCallback& callback)
247 {
248 std::shared_ptr<AnimationUtils::InteractiveAnimation> interactiveAnimation =
249 std::make_shared<AnimationUtils::InteractiveAnimation>();
250 CHECK_NULL_RETURN(interactiveAnimation, nullptr);
251 auto wrappedOnFinish = GetWrappedCallback(callback);
252 Rosen::RSAnimationTimingProtocol timingProtocol;
253 Rosen::RSAnimationTimingCurve curve;
254 interactiveAnimation->interactiveAnimation_ =
255 Rosen::RSInteractiveImplictAnimator::Create(timingProtocol, curve);
256 CHECK_NULL_RETURN(interactiveAnimation->interactiveAnimation_, nullptr);
257 if (addCallback) {
258 interactiveAnimation->interactiveAnimation_->AddAnimation(addCallback);
259 }
260 interactiveAnimation->interactiveAnimation_->SetFinishCallBack(wrappedOnFinish);
261 return interactiveAnimation;
262 }
263
StartInteractiveAnimation(const std::shared_ptr<AnimationUtils::InteractiveAnimation> & interactiveAnimation)264 int32_t AnimationUtils::StartInteractiveAnimation(
265 const std::shared_ptr<AnimationUtils::InteractiveAnimation>& interactiveAnimation)
266 {
267 CHECK_NULL_RETURN(interactiveAnimation, -1);
268 CHECK_NULL_RETURN(interactiveAnimation->interactiveAnimation_, -1);
269 return interactiveAnimation->interactiveAnimation_->StartAnimation();
270 }
271
ContinueInteractiveAnimation(const std::shared_ptr<AnimationUtils::InteractiveAnimation> & interactiveAnimation)272 void AnimationUtils::ContinueInteractiveAnimation(
273 const std::shared_ptr<AnimationUtils::InteractiveAnimation>& interactiveAnimation)
274 {
275 CHECK_NULL_VOID(interactiveAnimation);
276 CHECK_NULL_VOID(interactiveAnimation->interactiveAnimation_);
277 interactiveAnimation->interactiveAnimation_->ContinueAnimation();
278 }
279
ReverseInteractiveAnimation(const std::shared_ptr<AnimationUtils::InteractiveAnimation> & interactiveAnimation)280 void AnimationUtils::ReverseInteractiveAnimation(
281 const std::shared_ptr<AnimationUtils::InteractiveAnimation>& interactiveAnimation)
282 {
283 CHECK_NULL_VOID(interactiveAnimation);
284 CHECK_NULL_VOID(interactiveAnimation->interactiveAnimation_);
285 interactiveAnimation->interactiveAnimation_->ReverseAnimation();
286 }
287
UpdateInteractiveAnimation(const std::shared_ptr<AnimationUtils::InteractiveAnimation> & interactiveAnimation,float progress)288 void AnimationUtils::UpdateInteractiveAnimation(
289 const std::shared_ptr<AnimationUtils::InteractiveAnimation>& interactiveAnimation, float progress)
290 {
291 CHECK_NULL_VOID(interactiveAnimation);
292 CHECK_NULL_VOID(interactiveAnimation->interactiveAnimation_);
293 interactiveAnimation->interactiveAnimation_->PauseAnimation();
294 interactiveAnimation->interactiveAnimation_->SetFraction(progress);
295 }
296
AddInteractiveAnimation(const std::shared_ptr<AnimationUtils::InteractiveAnimation> & interactiveAnimation,const std::function<void ()> & callback)297 void AnimationUtils::AddInteractiveAnimation(
298 const std::shared_ptr<AnimationUtils::InteractiveAnimation>& interactiveAnimation,
299 const std::function<void()>& callback)
300 {
301 CHECK_NULL_VOID(interactiveAnimation);
302 CHECK_NULL_VOID(interactiveAnimation->interactiveAnimation_);
303 interactiveAnimation->interactiveAnimation_->AddAnimation(callback);
304 }
305 } // namespace OHOS::Ace
306