• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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