• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "remote_animation.h"
17 
18 #include <ability_manager_client.h>
19 #include <common/rs_rect.h>
20 #include <hitrace_meter.h>
21 #include <string>
22 #include <transaction/rs_transaction.h>
23 #include "minimize_app.h"
24 #include "parameters.h"
25 #include "surface_draw.h"
26 #include "window_helper.h"
27 #include "window_inner_manager.h"
28 #include "window_manager_hilog.h"
29 #include "zidl/ressched_report.h"
30 
31 namespace OHOS {
32 namespace Rosen {
33 namespace {
34     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "RemoteAnimation"};
35     const std::string ANIMATION_TIME_OUT_TASK = "remote_animation_time_out_task";
36     constexpr int64_t ANIMATION_TIME_OUT_MILLISECONDS = 3000; // 3000 is max time
37 }
38 bool RemoteAnimation::isRemoteAnimationEnable_ = true;
39 std::atomic<uint32_t> RemoteAnimation::allocationId_ = 0;
40 sptr<RSIWindowAnimationController> RemoteAnimation::windowAnimationController_ = nullptr;
41 std::weak_ptr<AppExecFwk::EventHandler> RemoteAnimation::wmsTaskHandler_;
42 wptr<WindowRoot> RemoteAnimation::windowRoot_;
43 bool RemoteAnimation::animationFirst_ = false;
44 wptr<WindowController> RemoteAnimation::windowController_ = nullptr;
45 
46 std::map<TransitionReason, TransitionEvent> eventMap_ = {
47     {TransitionReason::CLOSE, TransitionEvent::CLOSE},
48     {TransitionReason::MINIMIZE, TransitionEvent::MINIMIZE},
49     {TransitionReason::BACK_TRANSITION, TransitionEvent::BACK_TRANSITION}
50 };
51 
SetAnimationFirst(bool animationFirst)52 void RemoteAnimation::SetAnimationFirst(bool animationFirst)
53 {
54     animationFirst_ = animationFirst;
55     WLOGFI("RSWindowAnimation:animationFirst: %{public}u!", static_cast<uint32_t>(animationFirst_));
56 }
57 
IsRemoteAnimationEnabledAndFirst(DisplayId displayId)58 bool RemoteAnimation::IsRemoteAnimationEnabledAndFirst(DisplayId displayId)
59 {
60     return animationFirst_ && CheckRemoteAnimationEnabled(displayId);
61 }
62 
SetWindowAnimationController(const sptr<RSIWindowAnimationController> & controller)63 WMError RemoteAnimation::SetWindowAnimationController(const sptr<RSIWindowAnimationController>& controller)
64 {
65     WLOGFI("RSWindowAnimation: set window animation controller!");
66     if (!isRemoteAnimationEnable_) {
67         WLOGE("RSWindowAnimation: failed to set window animation controller, remote animation is not enabled");
68         return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
69     }
70     if (controller == nullptr) {
71         WLOGFE("RSWindowAnimation: failed to set window animation controller, controller is null!");
72         return WMError::WM_ERROR_NULLPTR;
73     }
74 
75     if (windowAnimationController_ != nullptr) {
76         WLOGFI("RSWindowAnimation: maybe user switch!");
77     }
78 
79     windowAnimationController_ = controller;
80     return WMError::WM_OK;
81 }
82 
SetMainTaskHandler(std::shared_ptr<AppExecFwk::EventHandler> handler)83 void RemoteAnimation::SetMainTaskHandler(std::shared_ptr<AppExecFwk::EventHandler> handler)
84 {
85     wmsTaskHandler_ = handler;
86 }
87 
SetWindowControllerAndRoot(const sptr<WindowController> & windowController,const sptr<WindowRoot> & windowRoot)88 void RemoteAnimation::SetWindowControllerAndRoot(const sptr<WindowController>& windowController,
89     const sptr<WindowRoot>& windowRoot)
90 {
91     windowController_ = windowController;
92     windowRoot_ = windowRoot;
93 }
94 
CheckAnimationController()95 bool RemoteAnimation::CheckAnimationController()
96 {
97     if (windowAnimationController_ == nullptr) {
98         WLOGFD("RSWindowAnimation: windowAnimationController_ null!");
99         return false;
100     }
101     return true;
102 }
103 
CheckRemoteAnimationEnabled(DisplayId displayId)104 bool RemoteAnimation::CheckRemoteAnimationEnabled(DisplayId displayId)
105 {
106     // When the screen is locked, remote animation cannot take effect because the launcher is frozen.
107     auto winRoot = windowRoot_.promote();
108     if (winRoot == nullptr) {
109         return false;
110     }
111     auto container = winRoot->GetOrCreateWindowNodeContainer(displayId);
112     if (container == nullptr || container->IsScreenLocked()) {
113         return false;
114     }
115     return CheckAnimationController();
116 }
117 
CheckTransition(sptr<WindowTransitionInfo> srcInfo,const sptr<WindowNode> & srcNode,sptr<WindowTransitionInfo> dstInfo,const sptr<WindowNode> & dstNode)118 bool RemoteAnimation::CheckTransition(sptr<WindowTransitionInfo> srcInfo, const sptr<WindowNode>& srcNode,
119     sptr<WindowTransitionInfo> dstInfo, const sptr<WindowNode>& dstNode)
120 {
121     if (srcNode == nullptr && dstNode == nullptr) {
122         WLOGFE("RSWindowAnimation: srcNode and dstNode are nullptr");
123         return false;
124     }
125 
126     if (srcNode != nullptr && !srcNode->leashWinSurfaceNode_ && !srcNode->surfaceNode_) {
127         WLOGFE("RSWindowAnimation: srcNode has no surface, winId: %{public}u", srcNode->GetWindowId());
128         return false;
129     }
130 
131     if (dstNode != nullptr && !dstNode->leashWinSurfaceNode_ && !dstNode->surfaceNode_) {
132         WLOGFE("RSWindowAnimation: dstNode has no surface, winId: %{public}u", dstNode->GetWindowId());
133         return false;
134     }
135 
136     // check support window mode when one app starts another app
137     if ((dstNode != nullptr && dstInfo != nullptr) &&
138         !WindowHelper::CheckSupportWindowMode(dstNode->GetWindowMode(), dstNode->GetModeSupportInfo(), dstInfo)) {
139         WLOGFE("RSWindowAnimation: the mode of dstNode isn't supported, winId: %{public}u, mode: %{public}u, "
140             "modeSupportInfo: %{public}u", dstNode->GetWindowId(), dstNode->GetWindowMode(),
141             dstNode->GetModeSupportInfo());
142         return false;
143     }
144 
145     auto node = (dstNode != nullptr ? dstNode : srcNode);
146     return CheckRemoteAnimationEnabled(node->GetDisplayId());
147 }
148 
OnRemoteDie(const sptr<IRemoteObject> & remoteObject)149 void RemoteAnimation::OnRemoteDie(const sptr<IRemoteObject>& remoteObject)
150 {
151     WLOGFI("RSWindowAnimation: OnRemoteDie!");
152     if (windowAnimationController_ != nullptr && windowAnimationController_->AsObject() == remoteObject) {
153         windowAnimationController_ = nullptr;
154     }
155     if (animationFirst_) {
156         CallbackTimeOutProcess();
157     }
158 }
159 
GetAndDrawSnapShot(const sptr<WindowNode> & srcNode)160 static void GetAndDrawSnapShot(const sptr<WindowNode>& srcNode)
161 {
162     if (srcNode == nullptr || srcNode->leashWinSurfaceNode_ == nullptr) {
163         WLOGFD("srcNode or srcNode->leashWinSurfaceNode_ is empty");
164         return;
165     }
166     if (srcNode->firstFrameAvaliable_) {
167         std::shared_ptr<Media::PixelMap> pixelMap;
168         // snapshot time out 2000ms
169         bool snapSucc = SurfaceDraw::GetSurfaceSnapshot(srcNode->surfaceNode_, pixelMap, 2000, 1.0, 1.0);
170         if (!snapSucc) {
171             // need to draw starting window when get pixelmap failed
172             WLOGFE("get surfaceSnapshot failed for window:%{public}u", srcNode->GetWindowId());
173             return;
174         }
175         struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
176         rsSurfaceNodeConfig.SurfaceNodeName = "startingWindow" + std::to_string(srcNode->GetWindowId());
177         srcNode->startingWinSurfaceNode_ = RSSurfaceNode::Create(rsSurfaceNodeConfig,
178             RSSurfaceNodeType::STARTING_WINDOW_NODE);
179         auto rect = srcNode->GetWindowRect();
180         srcNode->startingWinSurfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
181         SurfaceDraw::DrawImageRect(srcNode->startingWinSurfaceNode_, srcNode->GetWindowRect(),
182             pixelMap, 0x00ffffff, true);
183         srcNode->leashWinSurfaceNode_->RemoveChild(srcNode->surfaceNode_);
184         srcNode->leashWinSurfaceNode_->AddChild(srcNode->startingWinSurfaceNode_, -1);
185         RSTransaction::FlushImplicitTransaction();
186         WLOGFI("Draw surface snapshot in starting window for window:%{public}u", srcNode->GetWindowId());
187     } else if (srcNode->surfaceNode_) {
188         srcNode->surfaceNode_->SetIsNotifyUIBufferAvailable(true);
189         WLOGFI("Draw startingWindow in starting window for window:%{public}u", srcNode->GetWindowId());
190     }
191 }
192 
GetTransitionEvent(sptr<WindowTransitionInfo> srcInfo,sptr<WindowTransitionInfo> dstInfo,const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode)193 TransitionEvent RemoteAnimation::GetTransitionEvent(sptr<WindowTransitionInfo> srcInfo,
194     sptr<WindowTransitionInfo> dstInfo, const sptr<WindowNode>& srcNode, const sptr<WindowNode>& dstNode)
195 {
196     auto transitionReason = srcInfo->GetTransitionReason(); // src reason same as dst reason
197     if (srcNode != nullptr && eventMap_.find(transitionReason) != eventMap_.end()) {
198         WLOGFI("current window:%{public}u state: %{public}u", srcNode->GetWindowId(),
199             static_cast<uint32_t>(srcNode->stateMachine_.GetCurrentState()));
200         if (srcNode->stateMachine_.IsWindowNodeHiddenOrHiding()) {
201             WLOGFE("srcNode is hiding or hidden id: %{public}u!", srcNode->GetWindowId());
202             return TransitionEvent::UNKNOWN;
203         }
204         return eventMap_[transitionReason];
205     }
206     WLOGFI("Ability Transition");
207     if (dstNode == nullptr) {
208         if (dstInfo->GetAbilityToken() == nullptr) {
209             WLOGFE("target window abilityToken is null");
210         }
211         return TransitionEvent::UNKNOWN;
212     } else {
213         WLOGFI("current window:%{public}u state: %{public}u", dstNode->GetWindowId(),
214             static_cast<uint32_t>(dstNode->stateMachine_.GetCurrentState()));
215         if (WindowHelper::IsMainWindow(dstInfo->GetWindowType())) {
216             if (dstNode->stateMachine_.IsWindowNodeShownOrShowing()) {
217                 WLOGFE("dstNode is showing or shown id: %{public}d state:%{public}u!",
218                     dstNode->GetWindowId(), static_cast<uint32_t>(dstNode->stateMachine_.GetCurrentState()));
219                 return TransitionEvent::UNKNOWN;
220             }
221             return TransitionEvent::APP_TRANSITION;
222         } else if (dstInfo->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
223             return TransitionEvent::HOME;
224         }
225     }
226     return TransitionEvent::UNKNOWN;
227 }
228 
GetTransitionFinishedCallback(const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode)229 sptr<RSWindowAnimationFinishedCallback> RemoteAnimation::GetTransitionFinishedCallback(
230     const sptr<WindowNode>& srcNode, const sptr<WindowNode>& dstNode)
231 {
232     wptr<WindowNode> weak = dstNode;
233     wptr<WindowNode> weakSrc = srcNode;
234     auto callback = [weakSrc, weak]() {
235         WLOGFI("RSWindowAnimation: on finish transition with minimize pre fullscreen!");
236         auto weakNode = weak.promote();
237         if (weakNode == nullptr) {
238             WLOGFE("dst windowNode is nullptr!");
239             return;
240         }
241         FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
242             "wms:async:ShowRemoteAnimation");
243         if (!weakNode->stateMachine_.IsWindowNodeShownOrShowing()) {
244             WLOGFI("node:%{public}u is not play show animation with state:%{public}u!", weakNode->GetWindowId(),
245                 static_cast<uint32_t>(weakNode->stateMachine_.GetCurrentState()));
246             return;
247         }
248         MinimizeApp::ExecuteMinimizeAll(); // minimize execute in show animation
249         RSAnimationTimingProtocol timingProtocol(200); // animation time
250         RSNode::Animate(timingProtocol, RSAnimationTimingCurve::EASE_OUT, [weakNode]() {
251             auto winRect = weakNode->GetWindowRect();
252             WLOGFD("name:%{public}s id:%{public}u winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
253                 weakNode->GetWindowName().c_str(), weakNode->GetWindowId(),
254                 winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
255             if (!weakNode->leashWinSurfaceNode_) {
256                 return;
257             }
258             weakNode->leashWinSurfaceNode_->SetBounds(
259                 winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
260             RSTransaction::FlushImplicitTransaction();
261             weakNode->stateMachine_.TransitionTo(WindowNodeState::SHOW_ANIMATION_DONE);
262         });
263     };
264     return CreateAnimationFinishedCallback(callback);
265 }
266 
NotifyAnimationStartApp(sptr<WindowTransitionInfo> srcInfo,const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode,sptr<RSWindowAnimationTarget> & dstTarget,sptr<RSWindowAnimationFinishedCallback> & finishedCallback)267 WMError RemoteAnimation::NotifyAnimationStartApp(sptr<WindowTransitionInfo> srcInfo,
268     const sptr<WindowNode>& srcNode, const sptr<WindowNode>& dstNode,
269     sptr<RSWindowAnimationTarget>& dstTarget, sptr<RSWindowAnimationFinishedCallback>& finishedCallback)
270 {
271     if (animationFirst_) {
272         // From Recent also need to minimize window
273         MinimizeApp::ExecuteMinimizeAll();
274     }
275     // start app from launcher
276     if (srcNode != nullptr && srcNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
277         WLOGFI("RSWindowAnimation: start app id:%{public}u from launcher!", dstNode->GetWindowId());
278         windowAnimationController_->OnStartApp(StartingAppType::FROM_LAUNCHER, dstTarget, finishedCallback);
279         return WMError::WM_OK;
280     }
281     // start app from recent
282     if (srcInfo != nullptr && srcInfo->GetIsRecent()) {
283         WLOGFI("RSWindowAnimation: start app id:%{public}u from recent!", dstNode->GetWindowId());
284         windowAnimationController_->OnStartApp(StartingAppType::FROM_RECENT, dstTarget, finishedCallback);
285         return WMError::WM_OK;
286     }
287     // start app from other
288     WLOGFI("RSWindowAnimation: start app id:%{public}u from other!", dstNode->GetWindowId());
289     windowAnimationController_->OnStartApp(StartingAppType::FROM_OTHER, dstTarget, finishedCallback);
290     return WMError::WM_OK;
291 }
292 
GetExpectRect(const sptr<WindowNode> & dstNode,const sptr<RSWindowAnimationTarget> & dstTarget)293 void RemoteAnimation::GetExpectRect(const sptr<WindowNode>& dstNode, const sptr<RSWindowAnimationTarget>& dstTarget)
294 {
295     // when exit immersive, startingWindow (0,0,w,h), but app need avoid
296     bool needAvoid = (dstNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
297     auto winRoot = windowRoot_.promote();
298     if (needAvoid && winRoot) {
299         auto avoidRect = winRoot->GetDisplayRectWithoutSystemBarAreas(dstNode->GetDisplayId());
300         if (WindowHelper::IsEmptyRect(avoidRect)) {
301             return;
302         }
303         WLOGFI("name:%{public}s id:%{public}u avoidRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
304             dstNode->GetWindowName().c_str(), dstNode->GetWindowId(),
305             avoidRect.posX_, avoidRect.posY_, avoidRect.width_, avoidRect.height_);
306         if (WindowHelper::IsMainFullScreenWindow(dstNode->GetWindowType(), dstNode->GetWindowMode())) {
307             auto& stagingProperties = dstTarget->surfaceNode_->GetStagingProperties();
308             auto boundsRect = RectF(avoidRect.posX_, avoidRect.posY_, avoidRect.width_, avoidRect.height_);
309             dstTarget->windowBounds_ = RRect(boundsRect, stagingProperties.GetCornerRadius());
310             if (dstNode->leashWinSurfaceNode_) {
311                 dstNode->leashWinSurfaceNode_->SetBounds(avoidRect.posX_, avoidRect.posY_,
312                     avoidRect.width_, avoidRect.height_);
313             }
314         }
315     }
316 }
317 
NotifyAnimationTransition(sptr<WindowTransitionInfo> srcInfo,sptr<WindowTransitionInfo> dstInfo,const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode)318 WMError RemoteAnimation::NotifyAnimationTransition(sptr<WindowTransitionInfo> srcInfo,
319     sptr<WindowTransitionInfo> dstInfo, const sptr<WindowNode>& srcNode,
320     const sptr<WindowNode>& dstNode)
321 {
322     if (!dstNode) {
323         return WMError::WM_ERROR_NULLPTR;
324     }
325     WLOGFI("RSWindowAnimation: notify animation transition with dst currId:%{public}u!", dstNode->GetWindowId());
326     bool needMinimizeSrcNode = MinimizeApp::IsNodeNeedMinimizeWithReason(srcNode, MinimizeReason::OTHER_WINDOW);
327     auto finishedCallback = CreateShowAnimationFinishedCallback(srcNode, dstNode, needMinimizeSrcNode);
328     if (finishedCallback == nullptr) {
329         return WMError::WM_ERROR_NO_MEM;
330     }
331     auto dstTarget = CreateWindowAnimationTarget(dstInfo, dstNode);
332     if (dstTarget == nullptr) {
333         WLOGFE("RSWindowAnimation: Failed to create dst target!");
334         finishedCallback->OnAnimationFinished();
335         return WMError::WM_ERROR_NO_MEM;
336     }
337 
338     std::unordered_map<std::string, std::string> payload;
339     if (srcNode) {
340         payload["srcPid"] = std::to_string(srcNode->GetCallingPid());
341     }
342     ResSchedReport::GetInstance().ResSchedDataReport(
343         Rosen::RES_TYPE_SHOW_REMOTE_ANIMATION, Rosen::REMOTE_ANIMATION_BEGIN, payload);
344     // when exit immersive, startingWindow (0,0,w,h), but app need avoid
345     GetExpectRect(dstNode, dstTarget);
346     dstNode->isPlayAnimationShow_ = true;
347     // Transition to next state and update task count will success when enable animationFirst_
348     dstNode->stateMachine_.TransitionTo(WindowNodeState::SHOW_ANIMATION_PLAYING);
349     dstNode->stateMachine_.UpdateAnimationTaskCount(true);
350     // from app to app
351     if (needMinimizeSrcNode && srcNode != nullptr) {
352         auto srcTarget = CreateWindowAnimationTarget(srcInfo, srcNode);
353         // to avoid normal animation
354         srcNode->isPlayAnimationHide_ = true;
355         srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
356         srcNode->stateMachine_.UpdateAnimationTaskCount(true);
357         auto winController = windowController_.promote();
358         if (winController) {
359             winController->RemoveWindowNode(srcNode->GetWindowId(), true);
360         }
361         if (animationFirst_) {
362             // Notify minimize before animation when animationFirst is enable.
363             // Or notify minimize in animation finished callback.
364             MinimizeApp::ExecuteMinimizeAll();
365         }
366         WLOGFI("RSWindowAnimation: app transition from id:%{public}u to id:%{public}u!",
367             srcNode->GetWindowId(), dstNode->GetWindowId());
368         windowAnimationController_->OnAppTransition(srcTarget, dstTarget, finishedCallback);
369         return WMError::WM_OK;
370     }
371     return NotifyAnimationStartApp(srcInfo, srcNode, dstNode, dstTarget, finishedCallback);
372 }
373 
NotifyAnimationMinimize(sptr<WindowTransitionInfo> srcInfo,const sptr<WindowNode> & srcNode)374 WMError RemoteAnimation::NotifyAnimationMinimize(sptr<WindowTransitionInfo> srcInfo, const sptr<WindowNode>& srcNode)
375 {
376     sptr<RSWindowAnimationTarget> srcTarget = CreateWindowAnimationTarget(srcInfo, srcNode);
377     if (srcTarget == nullptr) {
378         return WMError::WM_ERROR_NO_MEM;
379     }
380     WLOGFI("RSWindowAnimation: notify animation minimize Id:%{public}u!", srcNode->GetWindowId());
381     srcNode->isPlayAnimationHide_ = true;
382     srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
383     auto winController = windowController_.promote();
384     if (winController) {
385         winController->RemoveWindowNode(srcNode->GetWindowId(), true);
386     }
387     sptr<RSWindowAnimationFinishedCallback> finishedCallback = CreateHideAnimationFinishedCallback(
388         srcNode, TransitionEvent::MINIMIZE);
389     if (finishedCallback == nullptr) {
390         WLOGFE("New RSIWindowAnimationFinishedCallback failed");
391         return WMError::WM_ERROR_NO_MEM;
392     }
393 
394     srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
395     srcNode->stateMachine_.UpdateAnimationTaskCount(true);
396     windowAnimationController_->OnMinimizeWindow(srcTarget, finishedCallback);
397     return WMError::WM_OK;
398 }
399 
NotifyAnimationClose(sptr<WindowTransitionInfo> srcInfo,const sptr<WindowNode> & srcNode,TransitionEvent event)400 WMError RemoteAnimation::NotifyAnimationClose(sptr<WindowTransitionInfo> srcInfo, const sptr<WindowNode>& srcNode,
401     TransitionEvent event)
402 {
403     sptr<RSWindowAnimationTarget> srcTarget = CreateWindowAnimationTarget(srcInfo, srcNode);
404     if (srcTarget == nullptr) {
405         return WMError::WM_ERROR_NO_MEM;
406     }
407     WLOGFI("RSWindowAnimation: notify animation close id:%{public}u!", srcNode->GetWindowId());
408     srcNode->isPlayAnimationHide_ = true;
409     auto winController = windowController_.promote();
410     if (winController) {
411         winController->RemoveWindowNode(srcNode->GetWindowId(), true);
412     }
413     sptr<RSWindowAnimationFinishedCallback> finishedCallback = CreateHideAnimationFinishedCallback(srcNode, event);
414     if (finishedCallback == nullptr) {
415         WLOGFE("New RSIWindowAnimationFinishedCallback failed");
416         return WMError::WM_ERROR_NO_MEM;
417     }
418     srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
419     srcNode->stateMachine_.UpdateAnimationTaskCount(true);
420     windowAnimationController_->OnCloseWindow(srcTarget, finishedCallback);
421     return WMError::WM_OK;
422 }
423 
NotifyAnimationBackTransition(sptr<WindowTransitionInfo> srcInfo,sptr<WindowTransitionInfo> dstInfo,const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode)424 WMError RemoteAnimation::NotifyAnimationBackTransition(sptr<WindowTransitionInfo> srcInfo,
425     sptr<WindowTransitionInfo> dstInfo, const sptr<WindowNode>& srcNode,
426     const sptr<WindowNode>& dstNode)
427 {
428     if (!animationFirst_) {
429         WLOGFE("not animation first!");
430         return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
431     }
432     if (!dstNode || !srcNode) {
433         WLOGFE("dstNode or srcNode is nullptr, no need transition animation");
434         return WMError::WM_ERROR_NULLPTR;
435     }
436     WLOGFI("RSWindowAnimation: app back transition from id:%{public}u to id:%{public}u!",
437         srcNode->GetWindowId(), dstNode->GetWindowId());
438     sptr<RSWindowAnimationTarget> srcTarget = CreateWindowAnimationTarget(srcInfo, srcNode);
439     sptr<RSWindowAnimationTarget> dstTarget = CreateWindowAnimationTarget(dstInfo, dstNode);
440     if (srcTarget == nullptr || dstTarget == nullptr) {
441         return WMError::WM_ERROR_NO_MEM;
442     }
443     srcNode->isPlayAnimationHide_ = true;
444     srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
445     srcNode->stateMachine_.UpdateAnimationTaskCount(true);
446     auto winController = windowController_.promote();
447     if (winController) {
448         winController->RemoveWindowNode(srcNode->GetWindowId(), true);
449         GetAndDrawSnapShot(srcNode);
450     }
451     dstNode->isPlayAnimationShow_ = true;
452     dstNode->stateMachine_.TransitionTo(WindowNodeState::SHOW_ANIMATION_PLAYING);
453     dstNode->stateMachine_.UpdateAnimationTaskCount(true);
454     wptr<WindowNode> srcNodeWptr = srcNode;
455     wptr<WindowNode> dstNodeWptr = dstNode;
456     auto func = [srcNodeWptr, dstNodeWptr]() {
457         WLOGFI("RSWindowAnimation: animationFirst use state machine process AnimationBackTransition!");
458         auto srcNodeSptr = srcNodeWptr.promote();
459         auto dstNodeSptr = dstNodeWptr.promote();
460         ProcessNodeStateTask(srcNodeSptr);
461         ProcessNodeStateTask(dstNodeSptr);
462         FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
463             "wms:async:ShowRemoteAnimation");
464     };
465     sptr<RSWindowAnimationFinishedCallback> finishedCallback = CreateAnimationFinishedCallback(func);
466     if (finishedCallback == nullptr) {
467         return WMError::WM_ERROR_NO_MEM;
468     }
469     windowAnimationController_->OnAppTransition(srcTarget, dstTarget, finishedCallback);
470     return WMError::WM_OK;
471 }
472 
GetAnimationTargetsForHome(std::vector<sptr<RSWindowAnimationTarget>> & animationTargets,std::vector<wptr<WindowNode>> needMinimizeAppNodes)473 void RemoteAnimation::GetAnimationTargetsForHome(std::vector<sptr<RSWindowAnimationTarget>>& animationTargets,
474     std::vector<wptr<WindowNode>> needMinimizeAppNodes)
475 {
476     for (auto& weakNode : needMinimizeAppNodes) {
477         auto srcNode = weakNode.promote();
478         sptr<WindowTransitionInfo> srcInfo = new(std::nothrow) WindowTransitionInfo();
479         sptr<RSWindowAnimationTarget> srcTarget = CreateWindowAnimationTarget(srcInfo, srcNode);
480         if (srcTarget == nullptr) {
481             continue;
482         }
483         WLOGFI("notify animation by home, need minimize id%{public}u", srcNode->GetWindowId());
484         if (!WindowHelper::IsMainWindow(srcNode->GetWindowType()) ||
485             srcNode->stateMachine_.IsWindowNodeHiddenOrHiding()) {
486             WLOGFE("srcNode is already hiding or hidden id: %{public}d!", srcNode->GetWindowId());
487             continue;
488         }
489         srcNode->isPlayAnimationHide_ = true;
490         srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_PLAYING);
491         srcNode->stateMachine_.UpdateAnimationTaskCount(true);
492         auto winController = windowController_.promote();
493         if (winController) {
494             winController->RemoveWindowNode(srcNode->GetWindowId(), true);
495         }
496         animationTargets.emplace_back(srcTarget);
497     }
498 }
499 
GetAnimationHomeFinishCallback(std::function<void (void)> & func,std::vector<wptr<WindowNode>> needMinimizeAppNodes)500 static void GetAnimationHomeFinishCallback(std::function<void(void)>& func,
501     std::vector<wptr<WindowNode>> needMinimizeAppNodes)
502 {
503     func = [needMinimizeAppNodes]() {
504         WLOGFI("NotifyAnimationByHome in animation callback not animationFirst");
505         for (auto& weakNode : needMinimizeAppNodes) {
506             auto srcNode = weakNode.promote();
507             if (srcNode == nullptr || !srcNode->stateMachine_.IsWindowNodeHiddenOrHiding()) {
508                 WLOGFE("windowNode is nullptr or is not play hide animation!");
509                 continue;
510             }
511             srcNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_DONE);
512         }
513         MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::MINIMIZE_ALL);
514         FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
515             "wms:async:ShowRemoteAnimation");
516     };
517 }
518 
NotifyAnimationByHome()519 WMError RemoteAnimation::NotifyAnimationByHome()
520 {
521     if (!CheckAnimationController()) {
522         return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
523     }
524     auto needMinimizeAppNodes = MinimizeApp::GetNeedMinimizeAppNodesWithReason(MinimizeReason::MINIMIZE_ALL);
525     WLOGFI("RSWindowAnimation: notify animation by home, need minimize size: %{public}u",
526         static_cast<uint32_t>(needMinimizeAppNodes.size()));
527     std::vector<sptr<RSWindowAnimationTarget>> animationTargets;
528     GetAnimationTargetsForHome(animationTargets, needMinimizeAppNodes);
529     std::function<void(void)> func;
530     if (animationFirst_) {
531         MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::MINIMIZE_ALL);
532         FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
533             "wms:async:ShowRemoteAnimation");
534         func = [needMinimizeAppNodes]() {
535             WLOGFI("NotifyAnimationByHome in animation callback in animationFirst with size:%{public}u",
536                 static_cast<uint32_t>(needMinimizeAppNodes.size()));
537             for (auto& weakNode : needMinimizeAppNodes) {
538                 auto srcNode = weakNode.promote();
539                 ProcessNodeStateTask(srcNode);
540             }
541             FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
542                 "wms:async:ShowRemoteAnimation");
543         };
544     } else {
545         GetAnimationHomeFinishCallback(func, needMinimizeAppNodes);
546     }
547     sptr<RSWindowAnimationFinishedCallback> finishedCallback = CreateAnimationFinishedCallback(func);
548     if (finishedCallback == nullptr) {
549         return WMError::WM_ERROR_NO_MEM;
550     }
551     // need use OnMinimizeWindows with controller
552     windowAnimationController_->OnMinimizeAllWindow(animationTargets, finishedCallback);
553     return WMError::WM_OK;
554 }
555 
NotifyAnimationTargetsUpdate(std::vector<uint32_t> & fullScreenWinIds,std::vector<uint32_t> & floatWinIds)556 void RemoteAnimation::NotifyAnimationTargetsUpdate(std::vector<uint32_t>& fullScreenWinIds,
557     std::vector<uint32_t>& floatWinIds)
558 {
559     auto handler = wmsTaskHandler_.lock();
560     if (handler == nullptr) {
561         WLOGFE("wmsTaskHandler_ is nullptr");
562         return;
563     }
564     // need post task when visit windowRoot node map
565     auto task = [fullScreenWinIds, floatWinIds]() {
566         if (!CheckAnimationController()) {
567             return;
568         }
569         auto winRoot = windowRoot_.promote();
570         if (winRoot == nullptr) {
571             WLOGFE("window root is nullptr");
572             return;
573         }
574         std::vector<sptr<RSWindowAnimationTarget>> floatAnimationTargets;
575         std::vector<sptr<RSWindowAnimationTarget>> fullScreenAnimationTargets;
576         for (auto& id : fullScreenWinIds) {
577             auto fullScreenNode = winRoot->GetWindowNode(id);
578             sptr<RSWindowAnimationTarget> fullScreenTarget = CreateWindowAnimationTarget(nullptr, fullScreenNode);
579             if (fullScreenTarget != nullptr) {
580                 fullScreenAnimationTargets.emplace_back(fullScreenTarget);
581             }
582         }
583         for (auto& id : floatWinIds) {
584             auto floatNode = winRoot->GetWindowNode(id);
585             sptr<RSWindowAnimationTarget> floatTarget = CreateWindowAnimationTarget(nullptr, floatNode);
586             if (floatTarget != nullptr) {
587                 floatAnimationTargets.emplace_back(floatTarget);
588             }
589         }
590         // delete when need all fullscreen targets
591         sptr<RSWindowAnimationTarget> fullScreenAnimationTarget = nullptr;
592         if (!fullScreenAnimationTargets.empty()) {
593             fullScreenAnimationTarget = fullScreenAnimationTargets[0];
594         }
595         windowAnimationController_->OnWindowAnimationTargetsUpdate(fullScreenAnimationTarget,
596             floatAnimationTargets);
597     };
598     bool ret = handler->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
599     if (!ret) {
600         WLOGFE("EventHandler PostTask Failed");
601         task();
602     }
603 }
604 
NotifyAnimationScreenUnlock(std::function<void (void)> callback)605 WMError RemoteAnimation::NotifyAnimationScreenUnlock(std::function<void(void)> callback)
606 {
607     if (!CheckAnimationController()) {
608         return WMError::WM_ERROR_NO_REMOTE_ANIMATION;
609     }
610     WLOGFI("NotifyAnimationScreenUnlock");
611     sptr<RSWindowAnimationFinishedCallback> finishedCallback = CreateAnimationFinishedCallback(callback);
612     if (finishedCallback == nullptr) {
613         return WMError::WM_ERROR_NO_MEM;
614     }
615 
616     windowAnimationController_->OnScreenUnlock(finishedCallback);
617     return WMError::WM_OK;
618 }
619 
CreateWindowAnimationTarget(sptr<WindowTransitionInfo> info,const sptr<WindowNode> & windowNode)620 sptr<RSWindowAnimationTarget> RemoteAnimation::CreateWindowAnimationTarget(sptr<WindowTransitionInfo> info,
621     const sptr<WindowNode>& windowNode)
622 {
623     if (windowNode == nullptr) {
624         WLOGFW("Failed to create window animation target, window node is null!");
625         return nullptr;
626     }
627 
628     sptr<RSWindowAnimationTarget> windowAnimationTarget = new(std::nothrow) RSWindowAnimationTarget();
629     if (windowAnimationTarget == nullptr) {
630         WLOGFE("New RSWindowAnimationTarget failed");
631         return nullptr;
632     }
633 
634     if (WindowHelper::IsMainWindow(windowNode->GetWindowType())) { // only starting window has abilityInfo
635         windowAnimationTarget->bundleName_ = windowNode->abilityInfo_.bundleName_;
636         windowAnimationTarget->abilityName_ = windowNode->abilityInfo_.abilityName_;
637     } else if (info) { // use for back, minimize, close
638         windowAnimationTarget->bundleName_ = info->GetBundleName();
639         windowAnimationTarget->abilityName_ = info->GetAbilityName();
640     }
641 
642     windowAnimationTarget->missionId_ = windowNode->abilityInfo_.missionId_;
643     windowAnimationTarget->windowId_ = windowNode->GetWindowId();
644     windowAnimationTarget->displayId_ = windowNode->GetDisplayId();
645     if (WindowHelper::IsAppWindow(windowNode->GetWindowType())) {
646         windowAnimationTarget->surfaceNode_ = windowNode->leashWinSurfaceNode_;
647     } else {
648         windowAnimationTarget->surfaceNode_ = windowNode->surfaceNode_;
649     }
650     if (windowAnimationTarget->surfaceNode_ == nullptr) {
651         WLOGFE("Window surface node is null!");
652         return nullptr;
653     }
654 
655     auto& stagingProperties = windowAnimationTarget->surfaceNode_->GetStagingProperties();
656     auto rect = windowNode->GetWindowRect();
657     // 0, 1, 2, 3: convert bounds to RectF
658     auto boundsRect = RectF(rect.posX_, rect.posY_, rect.width_, rect.height_);
659     windowAnimationTarget->windowBounds_ = RRect(boundsRect, stagingProperties.GetCornerRadius());
660     return windowAnimationTarget;
661 }
662 
PostProcessShowCallback(const sptr<WindowNode> & node)663 void RemoteAnimation::PostProcessShowCallback(const sptr<WindowNode>& node)
664 {
665     if (node == nullptr) {
666         WLOGFD("windowNode is nullptr!");
667         return;
668     }
669     auto winRect = node->GetWindowRect();
670     if (!node->leashWinSurfaceNode_) {
671         WLOGFD("leashWinSurfaceNode_ is nullptr with id: %{public}u!", node->GetWindowId());
672         return;
673     }
674     WLOGFD("name:%{public}s id:%{public}u winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
675         node->GetWindowName().c_str(), node->GetWindowId(),
676         winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
677     node->leashWinSurfaceNode_->SetBounds(
678         winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
679     RSTransaction::FlushImplicitTransaction();
680 }
681 
ExecuteFinalStateTask(sptr<WindowNode> & node)682 void RemoteAnimation::ExecuteFinalStateTask(sptr<WindowNode>& node)
683 {
684     StateTask destroyTask = nullptr;
685     auto winRoot = windowRoot_.promote();
686     if (winRoot == nullptr || node == nullptr) {
687         WLOGFE("windowRoot or node is nullptr");
688         return;
689     }
690     if (node->stateMachine_.IsWindowNodeHiddenOrHiding()) {
691         WLOGFI("execute task removing from rs tree id:%{public}u!", node->GetWindowId());
692         winRoot->UpdateRsTree(node->GetWindowId(), false);
693     } else if (node->stateMachine_.IsWindowNodeShownOrShowing()) {
694         WLOGFI("execute task layout after show animation id:%{public}u!", node->GetWindowId());
695         winRoot->LayoutWhenAddWindowNode(node, true);
696     } else {
697         WLOGFD("current State:%{public}u invalid", static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
698     }
699 
700     if (node->stateMachine_.GetDestroyTask(destroyTask)) {
701         destroyTask();
702     }
703 }
704 
CallbackTimeOutProcess()705 void RemoteAnimation::CallbackTimeOutProcess()
706 {
707     auto winRoot = windowRoot_.promote();
708     if (winRoot == nullptr) {
709         WLOGFE("windowRoot is nullptr");
710         return;
711     }
712     std::vector<wptr<WindowNode>> animationPlayingNodes;
713     winRoot->GetAllAnimationPlayingNodes(animationPlayingNodes);
714     WLOGFI("CallbackTimeOutProcess playingNodes:%{public}u", static_cast<uint32_t>(animationPlayingNodes.size()));
715     for (auto& weakNode : animationPlayingNodes) {
716         auto node = weakNode.promote();
717         if (node == nullptr) {
718             continue;
719         }
720         WLOGFI("callback timeout process windowId:%{public}u", node->GetWindowId());
721         node->stateMachine_.ResetAnimationTaskCount(1);
722         ProcessNodeStateTask(node);
723     }
724 }
725 
ProcessNodeStateTask(sptr<WindowNode> & node)726 void RemoteAnimation::ProcessNodeStateTask(sptr<WindowNode>& node)
727 {
728     // when callback come, node maybe destroyed
729     if (node == nullptr) {
730         WLOGFI("node is nullptr!");
731         return;
732     }
733     int32_t taskCount = node->stateMachine_.GetAnimationCount();
734     if (taskCount <= 0) { // no animation task but finishCallback come
735         WLOGFE("ProcessNodeStateTask failed with windowId: %{public}u, name:%{public}s taskCount:%{public}d",
736             node->GetWindowId(), node->GetWindowName().c_str(), taskCount);
737         return;
738     }
739     node->stateMachine_.UpdateAnimationTaskCount(false);
740     taskCount = node->stateMachine_.GetAnimationCount();
741     WLOGFI("ProcessNodeStateTask windowId: %{public}u, name:%{public}s state: %{public}u, taskCount:%{public}d",
742         node->GetWindowId(), node->GetWindowName().c_str(),
743         static_cast<uint32_t>(node->stateMachine_.GetCurrentState()), taskCount);
744     if (taskCount > 0 || taskCount < 0) {
745         WLOGFI("not last state task of window: %{public}d, %{public}d callback left not be executed!",
746             node->GetWindowId(), taskCount);
747         return;
748     }
749     ExecuteFinalStateTask(node);
750     if (node->stateMachine_.IsWindowNodeShownOrShowing()) {
751         // delete when immersive solution change
752         PostProcessShowCallback(node);
753         node->stateMachine_.TransitionTo(WindowNodeState::SHOW_ANIMATION_DONE);
754     } else if (node->stateMachine_.IsWindowNodeHiddenOrHiding()) {
755         node->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_DONE);
756     }
757 }
758 
CreateShowAnimationFinishedCallback(const sptr<WindowNode> & srcNode,const sptr<WindowNode> & dstNode,bool needMinimizeSrcNode)759 sptr<RSWindowAnimationFinishedCallback> RemoteAnimation::CreateShowAnimationFinishedCallback(
760     const sptr<WindowNode>& srcNode, const sptr<WindowNode>& dstNode, bool needMinimizeSrcNode)
761 {
762     wptr<WindowNode> srcNodeWptr = srcNode;
763     wptr<WindowNode> dstNodeWptr = dstNode;
764     // need add timeout check
765     std::function<void(void)> func;
766     if (!animationFirst_) {
767         WLOGFI("RSWindowAnimation: not animationFirst use default callback!");
768         return GetTransitionFinishedCallback(srcNode, dstNode);
769     } else {
770         func = [srcNodeWptr, dstNodeWptr, needMinimizeSrcNode]() {
771             WLOGFI("RSWindowAnimation: animationFirst use state machine process ShowAnimationFinishedCallback!");
772             auto srcNodeSptr = srcNodeWptr.promote();
773             auto dstNodeSptr = dstNodeWptr.promote();
774             if (dstNodeSptr == nullptr) {
775                 WLOGFE("dstNode is nullptr!");
776                 return;
777             }
778             ProcessNodeStateTask(dstNodeSptr);
779             // launcher not do this
780             if (needMinimizeSrcNode) {
781                 ProcessNodeStateTask(srcNodeSptr);
782             }
783             if (dstNodeSptr->stateMachine_.GetCurrentState() == WindowNodeState::SHOW_ANIMATION_DONE &&
784                 dstNodeSptr->leashWinSurfaceNode_) {
785                 dstNodeSptr->leashWinSurfaceNode_->SetAnimationFinished();
786             }
787             WLOGFI("current window:%{public}u state: %{public}u", dstNodeSptr->GetWindowId(),
788                 static_cast<uint32_t>(dstNodeSptr->stateMachine_.GetCurrentState()));
789             FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
790                 "wms:async:ShowRemoteAnimation");
791             std::unordered_map<std::string, std::string> payload;
792             if (srcNodeWptr != nullptr) {
793                 payload["srcPid"] = std::to_string(srcNodeWptr->GetCallingPid());
794             }
795             ResSchedReport::GetInstance().ResSchedDataReport(
796                     Rosen::RES_TYPE_SHOW_REMOTE_ANIMATION, Rosen::REMOTE_ANIMATION_END, payload);
797         };
798     }
799     return CreateAnimationFinishedCallback(func);
800 }
801 
ProcessAbility(const sptr<WindowNode> & srcNode,TransitionEvent event)802 static void ProcessAbility(const sptr<WindowNode>& srcNode, TransitionEvent event)
803 {
804     if (srcNode == nullptr) {
805         return;
806     }
807     switch (event) {
808         case TransitionEvent::CLOSE: {
809             WLOGFI("close windowId: %{public}u, name:%{public}s",
810                 srcNode->GetWindowId(), srcNode->GetWindowName().c_str());
811             WindowInnerManager::GetInstance().CloseAbility(srcNode);
812             break;
813         }
814         case TransitionEvent::MINIMIZE: {
815             WLOGFI("minimize windowId: %{public}u, name:%{public}s",
816                 srcNode->GetWindowId(), srcNode->GetWindowName().c_str());
817             WindowInnerManager::GetInstance().MinimizeAbility(srcNode, true);
818             break;
819         }
820         default:
821             break;
822     }
823 }
824 
NotifyAnimationUpdateWallpaper(sptr<WindowNode> node)825 void RemoteAnimation::NotifyAnimationUpdateWallpaper(sptr<WindowNode> node)
826 {
827     if (!CheckAnimationController()) {
828         return;
829     }
830     WLOGFI("NotifyAnimationUpdateWallpaper");
831     sptr<RSWindowAnimationTarget> srcTarget = CreateWindowAnimationTarget(nullptr, node);
832     // when wallpaper destroy, update with nullptr
833     windowAnimationController_->OnWallpaperUpdate(srcTarget);
834 }
835 
CreateHideAnimationFinishedCallback(const sptr<WindowNode> & srcNode,TransitionEvent event)836 sptr<RSWindowAnimationFinishedCallback> RemoteAnimation::CreateHideAnimationFinishedCallback(
837     const sptr<WindowNode>& srcNode, TransitionEvent event)
838 {
839     wptr<WindowNode> srcNodeWptr = srcNode;
840     // need add timeout check
841     std::function<void(void)> func;
842     if (!animationFirst_) {
843         func = [srcNodeWptr, event]() {
844             WLOGFI("RSWindowAnimation: not animationFirst use default callback!");
845             auto weakNode = srcNodeWptr.promote();
846             if (weakNode == nullptr || weakNode->abilityToken_ == nullptr) {
847                 WLOGFE("window node or ability token is nullptr");
848                 return;
849             }
850             if (!weakNode->stateMachine_.IsWindowNodeHiddenOrHiding()) {
851                 WLOGFE("window is not playing hide animation");
852                 return;
853             }
854             ProcessAbility(weakNode, event);
855             weakNode->stateMachine_.TransitionTo(WindowNodeState::HIDE_ANIMATION_DONE);
856             FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
857                 "wms:async:ShowRemoteAnimation");
858         };
859     } else {
860         if (event != TransitionEvent::MINIMIZE) {
861             GetAndDrawSnapShot(srcNode);
862         }
863         ProcessAbility(srcNode, event); // execute first when animationFirst
864         func = [srcNodeWptr]() {
865             WLOGFI("RSWindowAnimation: animationFirst use state machine process HideAnimationFinishedCallback!");
866             auto srcNodeSptr = srcNodeWptr.promote();
867             ProcessNodeStateTask(srcNodeSptr);
868             FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::REMOTE_ANIMATION),
869                 "wms:async:ShowRemoteAnimation");
870         };
871     }
872     return CreateAnimationFinishedCallback(func);
873 }
874 
CreateAnimationFinishedCallback(const std::function<void (void)> & callback)875 sptr<RSWindowAnimationFinishedCallback> RemoteAnimation::CreateAnimationFinishedCallback(
876     const std::function<void(void)>& callback)
877 {
878     if (callback == nullptr) {
879         WLOGFE("callback is null!");
880         return nullptr;
881     }
882     auto currentId = allocationId_.fetch_add(1);
883     std::string timeOutTaskName = ANIMATION_TIME_OUT_TASK + std::to_string(currentId);
884     auto func = [callback, timeOutTaskName]() {
885         auto handler = wmsTaskHandler_.lock();
886         if (handler != nullptr) {
887             handler->RemoveTask(timeOutTaskName);
888             WLOGFD("remove task %{public}s since animationCallback Come", timeOutTaskName.c_str());
889             handler->PostTask(callback, AppExecFwk::EventQueue::Priority::IMMEDIATE);
890         } else {
891             WLOGFW("callback execute not on main wms thread since handler is null!");
892             callback();
893         }
894     };
895     auto handlerSptr = wmsTaskHandler_.lock();
896     if (handlerSptr != nullptr) {
897         handlerSptr->PostTask(func, timeOutTaskName, ANIMATION_TIME_OUT_MILLISECONDS);
898         WLOGFD("PostTask task %{public}s", timeOutTaskName.c_str());
899     }
900     sptr<RSWindowAnimationFinishedCallback> finishCallback = new(std::nothrow) RSWindowAnimationFinishedCallback(
901         func);
902     if (finishCallback == nullptr) {
903         WLOGFE("New RSIWindowAnimationFinishedCallback failed");
904         func();
905         return nullptr;
906     }
907     return finishCallback;
908 }
909 } // Rosen
910 } // OHOS
911