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