1 /*
2  * Copyright (c) 2022-2024 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 "core/components_ng/pattern/overlay/overlay_manager.h"
17 
18 #include <cstdint>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
23 #include "want.h"
24 #endif
25 
26 #include "base/error/error_code.h"
27 #include "base/geometry/ng/offset_t.h"
28 #include "base/geometry/ng/size_t.h"
29 #include "base/log/dump_log.h"
30 #include "base/log/log.h"
31 #include "base/memory/ace_type.h"
32 #include "base/memory/referenced.h"
33 #include "base/subwindow/subwindow_manager.h"
34 #include "base/utils/measure_util.h"
35 #include "base/utils/system_properties.h"
36 #include "base/utils/utils.h"
37 #include "base/window/foldable_window.h"
38 #include "core/animation/animation_pub.h"
39 #include "core/animation/spring_curve.h"
40 #include "core/common/ace_application_info.h"
41 #include "core/common/ace_engine.h"
42 #include "core/common/container.h"
43 #include "core/common/ime/input_method_manager.h"
44 #include "core/common/interaction/interaction_interface.h"
45 #include "core/common/modal_ui_extension.h"
46 #include "core/common/recorder/event_recorder.h"
47 #include "core/components/common/properties/color.h"
48 #include "core/components/select/select_theme.h"
49 #include "core/components/text_overlay/text_overlay_theme.h"
50 #include "core/components/toast/toast_theme.h"
51 #include "core/components_ng/animation/geometry_transition.h"
52 #include "core/components_ng/base/frame_node.h"
53 #include "core/components_ng/base/ui_node.h"
54 #include "core/components_ng/base/view_abstract.h"
55 #include "core/components_ng/base/view_stack_processor.h"
56 #include "core/components_ng/event/focus_hub.h"
57 #include "core/components_ng/manager/focus/focus_view.h"
58 #include "core/components_ng/pattern/bubble/bubble_event_hub.h"
59 #include "core/components_ng/pattern/bubble/bubble_pattern.h"
60 #include "core/components_ng/pattern/calendar_picker/calendar_dialog_view.h"
61 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
62 #include "core/components_ng/pattern/dialog/dialog_view.h"
63 #include "core/components_ng/pattern/menu/menu_item/menu_item_model_ng.h"
64 #include "core/components_ng/pattern/menu/menu_item/menu_item_pattern.h"
65 #include "core/components_ng/pattern/menu/menu_item_group/menu_item_group_view.h"
66 #include "core/components_ng/pattern/menu/menu_layout_property.h"
67 #include "core/components_ng/pattern/menu/menu_pattern.h"
68 #include "core/components_ng/pattern/menu/menu_theme.h"
69 #include "core/components_ng/pattern/menu/menu_view.h"
70 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
71 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
72 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
73 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
74 #include "core/components_ng/pattern/overlay/keyboard_base_pattern.h"
75 #include "core/components_ng/pattern/overlay/keyboard_view.h"
76 #include "core/components_ng/pattern/overlay/modal_presentation_pattern.h"
77 #include "core/components_ng/pattern/overlay/overlay_container_pattern.h"
78 #include "core/components_ng/pattern/overlay/popup_base_pattern.h"
79 #include "core/components_ng/pattern/overlay/sheet_drag_bar_pattern.h"
80 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h"
81 #include "core/components_ng/pattern/overlay/sheet_presentation_property.h"
82 #include "core/components_ng/pattern/overlay/sheet_style.h"
83 #include "core/components_ng/pattern/overlay/sheet_view.h"
84 #include "core/components_ng/pattern/overlay/sheet_wrapper_pattern.h"
85 #include "core/components_ng/pattern/picker/datepicker_dialog_view.h"
86 #include "core/components_ng/pattern/stage/stage_pattern.h"
87 #include "core/components_ng/pattern/text_field/text_field_manager.h"
88 #include "core/components_ng/pattern/text_picker/textpicker_dialog_view.h"
89 #include "core/components_ng/pattern/time_picker/timepicker_dialog_view.h"
90 #include "core/components_ng/pattern/toast/toast_pattern.h"
91 #include "core/components_ng/pattern/ui_extension/ui_extension_model.h"
92 #include "core/components_ng/pattern/video/video_full_screen_pattern.h"
93 #include "core/components_ng/property/measure_property.h"
94 #include "core/components_ng/property/property.h"
95 #include "core/components_v2/inspector/inspector_constants.h"
96 #include "core/pipeline/pipeline_base.h"
97 #include "core/pipeline/pipeline_context.h"
98 #ifdef WEB_SUPPORTED
99 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
100 #include "core/components_ng/pattern/web/web_pattern.h"
101 #else
102 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
103 #endif
104 #endif
105 
106 namespace OHOS::Ace::NG {
107 namespace {
108 // should be moved to theme.
109 constexpr int32_t TOAST_ANIMATION_DURATION = 100;
110 constexpr int32_t MENU_ANIMATION_DURATION = 150;
111 constexpr float TOAST_ANIMATION_POSITION = 15.0f;
112 
113 constexpr float PIXELMAP_DRAG_SCALE = 1.0f;
114 constexpr float NUM_FLOAT_2 = 2.0f;
115 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 250;
116 constexpr float PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE = 0.5f;
117 
118 constexpr int32_t FULL_MODAL_ALPHA_ANIMATION_DURATION = 200;
119 
120 constexpr int32_t SHEET_HALF_SIZE = 2;
121 // dialog animation params
122 const RefPtr<Curve> SHOW_SCALE_ANIMATION_CURVE = AceType::MakeRefPtr<CubicCurve>(0.38f, 1.33f, 0.6f, 1.0f);
123 
124 constexpr int32_t ROOT_MIN_NODE = 1;
125 constexpr int32_t ATOMIC_SERVICE_MIN_SIZE = 2;
126 
127 //  OVERLAY_EXISTS:  overlay was removed
128 // OVERLAY_REMOVE:: overlay exists
129 // OVERLAY_NOTHING:nothing
130 constexpr int32_t OVERLAY_EXISTS = 0;
131 constexpr int32_t OVERLAY_REMOVE = 1;
132 constexpr int32_t OVERLAY_NOTHING = 2;
133 
134 // custom keyboard animation params
135 const RefPtr<Curve> SHOW_CUSTOM_KEYBOARD_ANIMATION_CURVE =
136     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 342.0f, 37.0f);
137 const RefPtr<Curve> HIDE_CUSTOM_KEYBOARD_ANIMATION_CURVE =
138     AceType::MakeRefPtr<InterpolatingSpring>(4.0f, 1.0f, 342.0f, 37.0f);
139 
140 const RefPtr<InterpolatingSpring> MENU_ANIMATION_CURVE =
141     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 528.0f, 35.0f);
142 
143 const RefPtr<Curve> CUSTOM_PREVIEW_ANIMATION_CURVE =
144     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 280.0f, 30.0f);
145 const std::string HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME = "hoverImageClipDisAppear";
146 constexpr double MENU_ORIGINAL_SCALE = 0.6f;
147 constexpr int32_t DUMP_LOG_DEPTH_1 = 1;
148 constexpr int32_t DUMP_LOG_DEPTH_2 = 2;
149 
150 constexpr int32_t EVENT_COLUMN_SLOT = -2;
151 
152 const float MINIMUM_AMPLITUDE_RATION = 0.08f;
153 
154 // UIExtensionComponent Transform param key
155 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
156 constexpr char WANT_PARAM_UIEXTNODE_ANGLE_KEY[] = "modalUIExtNodeAngle";
157 constexpr char WANT_PARAM_UIEXTNODE_WIDTH_KEY[] = "modalUIExtNodeWidth";
158 constexpr char WANT_PARAM_UIEXTNODE_HEIGHT_KEY[] = "modalUIExtNodeHeight";
159 #endif
160 constexpr int32_t UIEXTNODE_ANGLE_90 = 90;
161 constexpr int32_t UIEXTNODE_ANGLE_180 = 180;
162 constexpr int32_t UIEXTNODE_ANGLE_270 = 270;
163 
164 constexpr double DISTANCE_THRESHOLD = 20.0;
165 
GetLastPage()166 RefPtr<FrameNode> GetLastPage()
167 {
168     auto pipelineContext = PipelineContext::GetCurrentContext();
169     CHECK_NULL_RETURN(pipelineContext, nullptr);
170     auto stageManager = pipelineContext->GetStageManager();
171     CHECK_NULL_RETURN(stageManager, nullptr);
172     auto pageNode = stageManager->GetLastPage();
173     return pageNode;
174 }
175 
ShowPreviewBgDisappearAnimationProc(const RefPtr<RenderContext> & previewRenderContext,const RefPtr<MenuTheme> & menuTheme,bool isShowHoverImage)176 void ShowPreviewBgDisappearAnimationProc(const RefPtr<RenderContext>& previewRenderContext,
177     const RefPtr<MenuTheme>& menuTheme, bool isShowHoverImage)
178 {
179     auto shadow = previewRenderContext->GetBackShadow();
180     if (!shadow.has_value()) {
181         shadow = Shadow::CreateShadow(ShadowStyle::None);
182     }
183     previewRenderContext->UpdateBackShadow(shadow.value());
184     auto disappearDuration = menuTheme->GetDisappearDuration();
185     AnimationOption previewOption;
186     if (isShowHoverImage) {
187         previewOption.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
188     } else {
189         previewOption.SetCurve(Curves::SHARP);
190         previewOption.SetDuration(disappearDuration);
191     }
192     AnimationUtils::Animate(previewOption, [previewRenderContext, shadow]() mutable {
193         CHECK_NULL_VOID(previewRenderContext);
194         auto color = shadow->GetColor();
195         auto newColor = Color::FromARGB(1, color.GetRed(), color.GetGreen(), color.GetBlue());
196         shadow->SetColor(newColor);
197         previewRenderContext->UpdateBackShadow(shadow.value());
198         BorderRadiusProperty borderRadius;
199         borderRadius.SetRadius(0.0_vp);
200         previewRenderContext->UpdateBorderRadius(borderRadius);
201     });
202 }
203 
UpdateHoverImagePreviewOpacityAnimation(const RefPtr<MenuTheme> & menuTheme,const RefPtr<MenuPattern> & menuPattern,RefPtr<FrameNode> & previewChild)204 void UpdateHoverImagePreviewOpacityAnimation(const RefPtr<MenuTheme>& menuTheme,
205     const RefPtr<MenuPattern>& menuPattern, RefPtr<FrameNode>& previewChild)
206 {
207     CHECK_NULL_VOID(menuPattern);
208     CHECK_NULL_VOID(menuPattern->GetIsShowHoverImage());
209 
210     CHECK_NULL_VOID(previewChild);
211     auto previewRenderContext = previewChild->GetRenderContext();
212     CHECK_NULL_VOID(previewRenderContext);
213 
214     bool isCustomPreview = previewChild->GetTag() == V2::MENU_PREVIEW_ETS_TAG;
215     // only update custom preview opacity
216     CHECK_NULL_VOID(isCustomPreview);
217 
218     AnimationOption option;
219     option.SetDuration(menuTheme->GetHoverImagePreviewDisAppearDuration());
220     option.SetCurve(Curves::FRICTION);
221     AnimationUtils::Animate(
222         option, [previewRenderContext]() {
223             CHECK_NULL_VOID(previewRenderContext);
224             previewRenderContext->UpdateOpacity(0.0);
225         });
226 }
227 
ShowPreviewDisappearAnimationProc(const RefPtr<MenuWrapperPattern> & menuWrapperPattern,RefPtr<FrameNode> & previewChild)228 void ShowPreviewDisappearAnimationProc(const RefPtr<MenuWrapperPattern>& menuWrapperPattern,
229     RefPtr<FrameNode>& previewChild)
230 {
231     CHECK_NULL_VOID(menuWrapperPattern);
232     CHECK_NULL_VOID(previewChild);
233     auto previewRenderContext = previewChild->GetRenderContext();
234     CHECK_NULL_VOID(previewRenderContext);
235     if (menuWrapperPattern->HasPreviewTransitionEffect()) {
236         auto layoutProperty = previewChild->GetLayoutProperty();
237         CHECK_NULL_VOID(layoutProperty);
238         layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
239         return;
240     }
241 
242     auto menuChild = menuWrapperPattern->GetMenu();
243     CHECK_NULL_VOID(menuChild);
244     auto menuPattern = menuChild->GetPattern<MenuPattern>();
245     CHECK_NULL_VOID(menuPattern);
246     auto previewPosition = menuPattern->GetPreviewOriginOffset();
247 
248     auto pipelineContext = menuChild->GetContext();
249     CHECK_NULL_VOID(pipelineContext);
250     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
251     CHECK_NULL_VOID(menuTheme);
252     UpdateHoverImagePreviewOpacityAnimation(menuTheme, menuPattern, previewChild);
253 
254     auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
255     auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
256     AnimationOption scaleOption;
257     auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
258     scaleOption.SetCurve(motion);
259     float previewScale = 1.0f;
260     if (menuPattern->GetPreviewMode() == MenuPreviewMode::IMAGE) {
261         auto previewGeometryNode = previewChild->GetGeometryNode();
262         CHECK_NULL_VOID(previewGeometryNode);
263         auto preivewSize = previewGeometryNode->GetFrameSize();
264         if (!NearEqual(menuPattern->GetTargetSize().Width(), preivewSize.Width())) {
265             previewScale = menuPattern->GetTargetSize().Width() / preivewSize.Width();
266         }
267     }
268     ShowPreviewBgDisappearAnimationProc(previewRenderContext, menuTheme, menuWrapperPattern->GetIsShowHoverImage());
269 
270     CHECK_NULL_VOID(!menuPattern->GetIsShowHoverImage());
271     AnimationUtils::Animate(scaleOption,
272         [previewRenderContext, previewPosition, previewScale]() {
273         CHECK_NULL_VOID(previewRenderContext);
274         previewRenderContext->UpdatePosition(
275             OffsetT<Dimension>(Dimension(previewPosition.GetX()), Dimension(previewPosition.GetY())));
276         previewRenderContext->UpdateTransformScale(VectorF(previewScale, previewScale));
277     });
278 }
279 
UpdatePreviewVisibleAreaByFrameWhenDisappear(const RefPtr<RenderContext> & clipContext,const RefPtr<MenuPreviewPattern> & previewPattern,float value,float radius,float distVal)280 void UpdatePreviewVisibleAreaByFrameWhenDisappear(const RefPtr<RenderContext>& clipContext,
281     const RefPtr<MenuPreviewPattern>& previewPattern, float value, float radius, float distVal)
282 {
283     CHECK_NULL_VOID(previewPattern);
284     CHECK_NULL_VOID(!NearZero(distVal));
285     auto rate = (value - previewPattern->GetClipEndValue()) / distVal;
286 
287     auto clipStartWidth = previewPattern->GetStackAfterScaleActualWidth();
288     auto clipStartHeight = previewPattern->GetStackAfterScaleActualHeight();
289     auto clipEndWidth = previewPattern->GetHoverImageAfterScaleWidth();
290     auto clipEndHeight = previewPattern->GetHoverImageAfterScaleHeight();
291 
292     auto curentClipAreaWidth = rate * (clipEndWidth - clipStartWidth) + clipStartWidth;
293     auto curentClipAreaHeight = rate * (clipEndHeight - clipStartHeight) + clipStartHeight;
294 
295     auto clipOffset = previewPattern->GetHoverImageAfterScaleOffset();
296     RoundRect roundRectInstance;
297     roundRectInstance.SetRect(RectF(OffsetF(rate * clipOffset.GetX(), rate * clipOffset.GetY()),
298         SizeF(curentClipAreaWidth, curentClipAreaHeight)));
299     roundRectInstance.SetCornerRadius((1 - rate) * radius);
300     CHECK_NULL_VOID(clipContext);
301     clipContext->ClipWithRoundRect(roundRectInstance);
302 }
303 
UpdatePreivewVisibleAreaWhenDisappear(const RefPtr<FrameNode> & hoverImageStackNode,const RefPtr<FrameNode> & previewNode)304 void UpdatePreivewVisibleAreaWhenDisappear(const RefPtr<FrameNode>& hoverImageStackNode,
305     const RefPtr<FrameNode>& previewNode)
306 {
307     CHECK_NULL_VOID(hoverImageStackNode && previewNode);
308     auto previewPattern = previewNode->GetPattern<MenuPreviewPattern>();
309     CHECK_NULL_VOID(previewPattern);
310 
311     // reverse
312     auto clipStartValue = previewPattern->GetClipEndValue();
313     auto clipEndValue = previewPattern->GetClipStartValue();
314     clipEndValue += NearEqual(clipStartValue, clipEndValue) ? 1.0f : 0;
315     auto dist = clipEndValue - clipStartValue;
316 
317     auto pipelineContext = previewNode->GetContext();
318     CHECK_NULL_VOID(pipelineContext);
319     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
320     CHECK_NULL_VOID(menuTheme);
321     hoverImageStackNode->CreateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, 0,
322         [weak = AceType::WeakClaim(AceType::RawPtr(hoverImageStackNode)),
323             previewWeak = AceType::WeakClaim(AceType::RawPtr(previewNode)),
324             radius = menuTheme->GetPreviewBorderRadius().ConvertToPx(), distVal = dist](float value) {
325             auto clipNode = weak.Upgrade();
326             CHECK_NULL_VOID(clipNode);
327             auto clipContext = clipNode->GetRenderContext();
328             CHECK_NULL_VOID(clipContext);
329 
330             auto preview = previewWeak.Upgrade();
331             CHECK_NULL_VOID(preview);
332             auto previewPattern = preview->GetPattern<MenuPreviewPattern>();
333             CHECK_NULL_VOID(previewPattern);
334             UpdatePreviewVisibleAreaByFrameWhenDisappear(clipContext, previewPattern, value, radius, distVal);
335         });
336     AnimationOption option;
337     option.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
338     hoverImageStackNode->UpdateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, clipStartValue);
339     auto clipAnimation_ = AnimationUtils::StartAnimation(option, [hoverImageStackNode, clipEndValue]() {
340         CHECK_NULL_VOID(hoverImageStackNode);
341         hoverImageStackNode->UpdateAnimatablePropertyFloat(HOVER_IMAGE_CLIP_DISAPPEAR_PROPERTY_NAME, clipEndValue);
342     });
343 }
344 
UpdateHoverImageDisappearScaleAndPosition(const RefPtr<MenuWrapperPattern> & menuWrapperPattern,const RefPtr<MenuPreviewPattern> & previewPattern)345 void UpdateHoverImageDisappearScaleAndPosition(const RefPtr<MenuWrapperPattern>& menuWrapperPattern,
346     const RefPtr<MenuPreviewPattern>& previewPattern)
347 {
348     CHECK_NULL_VOID(menuWrapperPattern);
349     CHECK_NULL_VOID(menuWrapperPattern->GetIsShowHoverImage());
350 
351     CHECK_NULL_VOID(previewPattern);
352     // reverse scale
353     auto scaleTo = previewPattern->GetHoverImageScaleFrom();
354     auto pipelineContext = PipelineContext::GetCurrentContext();
355     CHECK_NULL_VOID(pipelineContext);
356     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
357     CHECK_NULL_VOID(menuTheme);
358     auto scaleAfter = LessNotEqual(scaleTo, 0.0) ? menuTheme->GetPreviewBeforeAnimationScale() : scaleTo;
359 
360     auto stackNode = menuWrapperPattern->GetHoverImageStackNode();
361     CHECK_NULL_VOID(stackNode);
362     auto stackContext = stackNode->GetRenderContext();
363     CHECK_NULL_VOID(stackContext);
364 
365     auto flexNode = menuWrapperPattern->GetHoverImageFlexNode();
366     CHECK_NULL_VOID(flexNode);
367     auto flexContext = flexNode->GetRenderContext();
368     CHECK_NULL_VOID(flexContext);
369 
370     auto menuChild = menuWrapperPattern->GetMenu();
371     CHECK_NULL_VOID(menuChild);
372     auto menuPattern = menuChild->GetPattern<MenuPattern>();
373     CHECK_NULL_VOID(menuPattern);
374     auto previewPosition = menuPattern->GetPreviewOriginOffset();
375 
376     menuWrapperPattern->StopHoverImageToPreviewAnimation();
377     AnimationOption option = AnimationOption();
378     option.SetCurve(CUSTOM_PREVIEW_ANIMATION_CURVE);
379     AnimationUtils::Animate(
380         option, [stackContext, scaleAfter, flexContext, previewPosition]() {
381             CHECK_NULL_VOID(stackContext);
382             stackContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
383 
384             CHECK_NULL_VOID(flexContext);
385             flexContext->UpdatePosition(
386                 OffsetT<Dimension>(Dimension(previewPosition.GetX()), Dimension(previewPosition.GetY())));
387         });
388 
389     ShowPreviewBgDisappearAnimationProc(stackContext, menuTheme, menuWrapperPattern->GetHoverImageStackNode());
390 }
391 
ShowPreviewDisappearAnimation(const RefPtr<MenuWrapperPattern> & menuWrapperPattern)392 void ShowPreviewDisappearAnimation(const RefPtr<MenuWrapperPattern>& menuWrapperPattern)
393 {
394     CHECK_NULL_VOID(menuWrapperPattern);
395     auto previewChild = menuWrapperPattern->GetPreview();
396     CHECK_NULL_VOID(previewChild);
397     ShowPreviewDisappearAnimationProc(menuWrapperPattern, previewChild);
398 
399     CHECK_NULL_VOID(menuWrapperPattern->GetIsShowHoverImage());
400     auto hoverImagePreview = menuWrapperPattern->GetHoverImagePreview();
401     CHECK_NULL_VOID(hoverImagePreview);
402     ShowPreviewDisappearAnimationProc(menuWrapperPattern, hoverImagePreview);
403 
404     auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
405     CHECK_NULL_VOID(previewPattern);
406     if (previewPattern->IsHoverImageAnimationPlaying()) {
407         menuWrapperPattern->SetIsStopHoverImageAnimation(true);
408         previewPattern->SetIsHoverImageAnimationPlaying(false);
409     } else {
410         UpdatePreivewVisibleAreaWhenDisappear(menuWrapperPattern->GetHoverImageStackNode(), previewChild);
411     }
412     UpdateHoverImageDisappearScaleAndPosition(menuWrapperPattern, previewPattern);
413 }
414 
UpdateContextMenuDisappearPositionAnimation(const RefPtr<FrameNode> & menu,const NG::OffsetF & offset,float menuScale)415 void UpdateContextMenuDisappearPositionAnimation(const RefPtr<FrameNode>& menu, const NG::OffsetF& offset,
416     float menuScale)
417 {
418     CHECK_NULL_VOID(menu);
419     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
420     CHECK_NULL_VOID(menuWrapperPattern);
421     auto menuChild = menuWrapperPattern->GetMenu();
422     CHECK_NULL_VOID(menuChild);
423     auto menuRenderContext = menuChild->GetRenderContext();
424     CHECK_NULL_VOID(menuRenderContext);
425     auto menuPattern = menuChild->GetPattern<MenuPattern>();
426     CHECK_NULL_VOID(menuPattern);
427     auto menuPosition = menuChild->GetGeometryNode()->GetFrameOffset();
428     menuPosition += offset;
429     menuChild->GetGeometryNode()->SetFrameOffset(menuPosition);
430     menuPattern->SetEndOffset(menuPosition);
431 
432     auto pipelineContext = PipelineContext::GetCurrentContext();
433     CHECK_NULL_VOID(pipelineContext);
434     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
435     CHECK_NULL_VOID(menuTheme);
436 
437     auto scaleAfter = LessNotEqual(menuScale, 0.0) ? 1.0f : menuScale;
438     auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
439     auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
440     AnimationOption positionOption;
441     auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
442     positionOption.SetCurve(motion);
443     AnimationUtils::Animate(positionOption, [menuRenderContext, menuPosition, scaleAfter]() {
444         CHECK_NULL_VOID(menuRenderContext);
445         menuRenderContext->UpdatePosition(
446             OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
447         // menuScale default value is 1.0f, only update menu scale with not the default value
448         if (scaleAfter != 1.0f) {
449             menuRenderContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
450         }
451     });
452 }
453 
ContextMenuSwitchDragPreviewScaleAnimationProc(const RefPtr<RenderContext> & dragPreviewContext,const RefPtr<RenderContext> & previewRenderContext,const RefPtr<FrameNode> & previewChild,const NG::OffsetF & offset,int32_t duration)454 void ContextMenuSwitchDragPreviewScaleAnimationProc(const RefPtr<RenderContext>& dragPreviewContext,
455     const RefPtr<RenderContext>& previewRenderContext, const RefPtr<FrameNode>& previewChild,
456     const NG::OffsetF& offset, int32_t duration)
457 {
458     CHECK_NULL_VOID(previewChild);
459     auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
460     CHECK_NULL_VOID(previewPattern);
461     CHECK_NULL_VOID(previewPattern->GetIsShowHoverImage());
462 
463     CHECK_NULL_VOID(dragPreviewContext);
464     auto width = dragPreviewContext->GetPaintRectWithTransform().Width();
465     auto height = dragPreviewContext->GetPaintRectWithTransform().Height();
466 
467     CHECK_NULL_VOID(previewRenderContext);
468     auto previewWidth = previewPattern->GetCustomPreviewWidth();
469     auto previewHeight = previewPattern->GetCustomPreviewHeight();
470 
471     // reverse scale
472     float scaleTo = 1.0f;
473     if (previewWidth - width < previewHeight - height) {
474         CHECK_EQUAL_VOID(previewWidth, 0);
475         scaleTo = width / previewWidth;
476     } else {
477         CHECK_EQUAL_VOID(previewHeight, 0);
478         scaleTo = height / previewHeight;
479     }
480     auto scaleAfter = LessNotEqual(scaleTo, 0.0) ? 1.0f : scaleTo;
481     AnimationOption option = AnimationOption();
482     option.SetDuration(duration);
483     option.SetCurve(Curves::FRICTION);
484     AnimationUtils::Animate(
485         option,
486         [previewRenderContext, dragPreviewContext, scaleAfter, offset]() {
487             CHECK_NULL_VOID(previewRenderContext);
488             previewRenderContext->UpdateTransformScale(VectorF(scaleAfter, scaleAfter));
489             previewRenderContext->UpdateTransformTranslate({ offset.GetX(), offset.GetY(), 0.0f });
490 
491             CHECK_NULL_VOID(dragPreviewContext);
492             dragPreviewContext->UpdateTransformTranslate({ offset.GetX(), offset.GetY(), 0.0f });
493         });
494 }
495 
UpdateContextMenuSwitchDragPreviewBefore(const RefPtr<FrameNode> & menu)496 void UpdateContextMenuSwitchDragPreviewBefore(const RefPtr<FrameNode>& menu)
497 {
498     CHECK_NULL_VOID(menu);
499     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
500     CHECK_NULL_VOID(menuWrapperPattern && menuWrapperPattern->GetIsShowHoverImage());
501     auto previewChild = menuWrapperPattern->GetPreview();
502     CHECK_NULL_VOID(previewChild);
503     auto previewPattern = previewChild->GetPattern<MenuPreviewPattern>();
504     CHECK_NULL_VOID(previewPattern);
505 
506     if (previewPattern->IsHoverImageScalePlaying()) {
507         auto previewRenderContext = previewChild->GetRenderContext();
508         CHECK_NULL_VOID(previewRenderContext);
509         previewRenderContext->UpdateOpacity(0.0);
510     }
511 }
512 
ContextMenuSwitchDragPreviewAnimationProc(const RefPtr<FrameNode> & menu,const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)513 void ContextMenuSwitchDragPreviewAnimationProc(const RefPtr<FrameNode>& menu,
514     const RefPtr<NG::FrameNode>& dragPreviewNode, const NG::OffsetF& offset)
515 {
516     CHECK_NULL_VOID(dragPreviewNode && menu);
517     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
518     CHECK_NULL_VOID(menuWrapperPattern && menuWrapperPattern->GetIsShowHoverImage());
519 
520     auto pipelineContext = PipelineContext::GetCurrentContext();
521     CHECK_NULL_VOID(pipelineContext);
522     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
523     CHECK_NULL_VOID(menuTheme);
524     // consistent with the menu disappear duration
525     auto duration = menuTheme->GetDisappearDuration();
526 
527     auto previewChild = menuWrapperPattern->GetPreview();
528     CHECK_NULL_VOID(previewChild);
529     auto previewRenderContext = previewChild->GetRenderContext();
530     CHECK_NULL_VOID(previewRenderContext);
531     auto dragPreviewContext = dragPreviewNode->GetRenderContext();
532     CHECK_NULL_VOID(dragPreviewContext);
533 
534     // update custom preview scale and position
535     ContextMenuSwitchDragPreviewScaleAnimationProc(dragPreviewContext, previewRenderContext, previewChild, offset,
536         duration);
537 
538     // custom preview and drag preview update Opacity
539     CHECK_NULL_VOID(!menuWrapperPattern->GetIsShowHoverImagePreviewStartDrag());
540     menuWrapperPattern->SetIsShowHoverImagePreviewStartDrag(true);
541     auto imageNode = menuWrapperPattern->GetHoverImagePreview();
542     CHECK_NULL_VOID(imageNode);
543     auto imageContext = imageNode->GetRenderContext();
544     CHECK_NULL_VOID(imageContext);
545     imageContext->UpdateOpacity(0.0);
546 
547     previewRenderContext->UpdateOpacity(1.0);
548     dragPreviewContext->UpdateOpacity(0.0);
549     AnimationOption option;
550     option.SetDuration(duration);
551     option.SetCurve(Curves::FRICTION);
552     option.SetOnFinishEvent(
553         [id = Container::CurrentId(), menuWrapperPattern] {
554             ContainerScope scope(id);
555             menuWrapperPattern->SetIsShowHoverImagePreviewStartDrag(false);
556         });
557     AnimationUtils::Animate(
558         option, [previewRenderContext, dragPreviewContext]() mutable {
559             CHECK_NULL_VOID(previewRenderContext);
560             previewRenderContext->UpdateOpacity(0.0);
561 
562             BorderRadiusProperty borderRadius;
563             borderRadius.SetRadius(0.0_vp);
564             previewRenderContext->UpdateBorderRadius(borderRadius);
565 
566             CHECK_NULL_VOID(dragPreviewContext);
567             dragPreviewContext->UpdateOpacity(1.0);
568         },
569         option.GetOnFinishEvent());
570 }
571 
ShowContextMenuDisappearAnimation(AnimationOption & option,const RefPtr<MenuWrapperPattern> & menuWrapperPattern,bool startDrag=false)572 void ShowContextMenuDisappearAnimation(
573     AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern, bool startDrag = false)
574 {
575     CHECK_NULL_VOID(menuWrapperPattern);
576     auto menuChild = menuWrapperPattern->GetMenu();
577     CHECK_NULL_VOID(menuChild);
578     auto menuRenderContext = menuChild->GetRenderContext();
579     CHECK_NULL_VOID(menuRenderContext);
580     auto menuPattern = menuChild->GetPattern<MenuPattern>();
581     CHECK_NULL_VOID(menuPattern);
582     auto menuPosition = menuPattern->GetEndOffset();
583     menuWrapperPattern->ClearAllSubMenu();
584 
585     auto pipelineContext = PipelineContext::GetCurrentContext();
586     CHECK_NULL_VOID(pipelineContext);
587     auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
588     CHECK_NULL_VOID(menuTheme);
589     if (startDrag) {
590         menuRenderContext->UpdateTransformScale(
591             VectorF(menuTheme->GetMenuDragAnimationScale(), menuTheme->GetMenuDragAnimationScale()));
592     }
593     auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
594     auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
595     AnimationOption positionOption;
596     auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
597     positionOption.SetCurve(motion);
598     AnimationUtils::Animate(positionOption, [menuRenderContext, menuPosition]() {
599         CHECK_NULL_VOID(menuRenderContext);
600         menuRenderContext->UpdatePosition(
601             OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
602     });
603 
604     auto disappearDuration = menuTheme->GetDisappearDuration();
605     auto menuAnimationScale = menuTheme->GetMenuAnimationScale();
606     AnimationOption scaleOption;
607     scaleOption.SetCurve(Curves::FAST_OUT_LINEAR_IN);
608     scaleOption.SetDuration(disappearDuration);
609     AnimationUtils::Animate(scaleOption, [menuRenderContext, menuAnimationScale]() {
610         CHECK_NULL_VOID(menuRenderContext);
611         menuRenderContext->UpdateTransformScale({ menuAnimationScale, menuAnimationScale });
612     });
613 
614     option.SetDuration(disappearDuration);
615     option.SetCurve(Curves::FRICTION);
616     AnimationUtils::Animate(
617         option,
618         [menuRenderContext]() {
619             CHECK_NULL_VOID(menuRenderContext);
620             menuRenderContext->UpdateOpacity(0.0);
621         },
622         option.GetOnFinishEvent());
623 }
624 
FireMenuDisappear(AnimationOption & option,const RefPtr<MenuWrapperPattern> & menuWrapperPattern)625 void FireMenuDisappear(AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern)
626 {
627     CHECK_NULL_VOID(menuWrapperPattern);
628     auto menuNode = menuWrapperPattern->GetMenu();
629     CHECK_NULL_VOID(menuNode);
630     auto menuRenderContext = menuNode->GetRenderContext();
631     CHECK_NULL_VOID(menuRenderContext);
632     MENU_ANIMATION_CURVE->UpdateMinimumAmplitudeRatio(MINIMUM_AMPLITUDE_RATION);
633     option.SetCurve(MENU_ANIMATION_CURVE);
634     AnimationUtils::Animate(option, [menuRenderContext]() {
635         if (menuRenderContext) {
636             menuRenderContext->UpdateTransformScale(VectorF(MENU_ORIGINAL_SCALE, MENU_ORIGINAL_SCALE));
637             menuRenderContext->UpdateOpacity(0.0f);
638         }
639     }, option.GetOnFinishEvent());
640 }
641 
SendPopupAccessibilityPageOpen(const RefPtr<FrameNode> & popupNode)642 void SendPopupAccessibilityPageOpen(const RefPtr<FrameNode>& popupNode)
643 {
644     CHECK_NULL_VOID(popupNode);
645     auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
646     CHECK_NULL_VOID(accessibilityProperty);
647     accessibilityProperty->SetShowedState(1);
648     popupNode->OnAccessibilityEvent(
649         AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
650 }
651 } // namespace
652 
~OverlayManager()653 OverlayManager::~OverlayManager()
654 {
655     TAG_LOGI(AceLogTag::ACE_OVERLAY, "OverlayManager destroyed");
656     popupMap_.clear();
657 }
658 
UpdateContextMenuDisappearPosition(const NG::OffsetF & offset,float menuScale,bool isRedragStart,int32_t menuWrapperId)659 void OverlayManager::UpdateContextMenuDisappearPosition(
660     const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
661 {
662     auto pipelineContext = PipelineContext::GetCurrentContext();
663     CHECK_NULL_VOID(pipelineContext);
664     auto overlayManager = pipelineContext->GetOverlayManager();
665     CHECK_NULL_VOID(overlayManager);
666     if (isRedragStart) {
667         overlayManager->ResetContextMenuRestartDragVector();
668     }
669 
670     if (menuMap_.empty()) {
671         return;
672     }
673 
674     RefPtr<FrameNode> menuWrapper = nullptr;
675     for (auto [targetId, node] : menuMap_) {
676         if (node && node->GetId() == menuWrapperId) {
677             menuWrapper = node;
678         }
679     }
680 
681     CHECK_NULL_VOID(menuWrapper && menuWrapper->GetTag() == V2::MENU_WRAPPER_ETS_TAG);
682     overlayManager->UpdateDragMoveVector(offset);
683 
684     if (overlayManager->IsOriginDragMoveVector() || !overlayManager->IsUpdateDragMoveVector()) {
685         return;
686     }
687 
688     UpdateContextMenuDisappearPositionAnimation(menuWrapper, overlayManager->GetUpdateDragMoveVector(), menuScale);
689 }
690 
CalculateMenuPosition(const RefPtr<FrameNode> & menuWrapperNode,const OffsetF & offset)691 OffsetF OverlayManager::CalculateMenuPosition(const RefPtr<FrameNode>& menuWrapperNode, const OffsetF& offset)
692 {
693     CHECK_NULL_RETURN(menuWrapperNode, OffsetF(0.0f, 0.0f));
694     if (IsContextMenuDragHideFinished()) {
695         return OffsetF(0.0f, 0.0f);
696     }
697     UpdateDragMoveVector(offset);
698     if (IsOriginDragMoveVector() || !IsUpdateDragMoveVector()) {
699         return OffsetF(0.0f, 0.0f);
700     }
701 
702     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
703     CHECK_NULL_RETURN(menuWrapperPattern, OffsetF(0.0f, 0.0f));
704     auto menuNode = menuWrapperPattern->GetMenu();
705     CHECK_NULL_RETURN(menuNode, OffsetF(0.0f, 0.0f));
706     auto menuOffset = GetUpdateDragMoveVector();
707     auto menuPattern = menuNode->GetPattern<MenuPattern>();
708     CHECK_NULL_RETURN(menuPattern, OffsetF(0.0f, 0.0f));
709     auto menuGeometryNode = menuNode->GetGeometryNode();
710     CHECK_NULL_RETURN(menuGeometryNode, OffsetF(0.0f, 0.0f));
711     auto menuPosition = menuGeometryNode->GetFrameOffset();
712     menuPosition += menuOffset;
713     menuGeometryNode->SetFrameOffset(menuPosition);
714     menuPattern->SetEndOffset(menuPosition);
715     return menuPosition;
716 }
717 
GetMenuPreviewCenter(NG::OffsetF & offset)718 bool OverlayManager::GetMenuPreviewCenter(NG::OffsetF& offset)
719 {
720     auto rootNode = rootNodeWeak_.Upgrade();
721     CHECK_NULL_RETURN(rootNode, false);
722     for (const auto& child : rootNode->GetChildren()) {
723         auto node = DynamicCast<FrameNode>(child);
724         if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
725             auto menuWarpperPattern = node->GetPattern<MenuWrapperPattern>();
726             CHECK_NULL_RETURN(menuWarpperPattern, false);
727             auto previewChild = menuWarpperPattern->GetPreview();
728             CHECK_NULL_RETURN(previewChild, false);
729             auto geometryNode = previewChild->GetGeometryNode();
730             if (geometryNode && geometryNode->GetFrameRect().IsEmpty()) {
731                 return false;
732             }
733             auto previewOffset = previewChild->GetPaintRectCenter();
734             offset.SetX(previewOffset.GetX());
735             offset.SetY(previewOffset.GetY());
736             return true;
737         }
738     }
739     return false;
740 }
741 
ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)742 void OverlayManager::ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode>& dragPreviewNode,
743     const NG::OffsetF& offset)
744 {
745     CHECK_NULL_VOID(dragPreviewNode);
746     if (menuMap_.empty()) {
747         return;
748     }
749     auto rootNode = rootNodeWeak_.Upgrade();
750     for (const auto& child : rootNode->GetChildren()) {
751         auto node = DynamicCast<FrameNode>(child);
752         if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
753             UpdateContextMenuSwitchDragPreviewBefore(node);
754             ContextMenuSwitchDragPreviewAnimationProc(node, dragPreviewNode, offset);
755         }
756     }
757 }
758 
PostDialogFinishEvent(const WeakPtr<FrameNode> & nodeWk)759 void OverlayManager::PostDialogFinishEvent(const WeakPtr<FrameNode>& nodeWk)
760 {
761     TAG_LOGI(AceLogTag::ACE_DIALOG, "post dialog finish event enter");
762     auto context = PipelineContext::GetCurrentContext();
763     CHECK_NULL_VOID(context);
764     auto taskExecutor = context->GetTaskExecutor();
765     CHECK_NULL_VOID(taskExecutor);
766     // animation finish event should be posted to UI thread.
767     taskExecutor->PostTask(
768         [weak = WeakClaim(this), nodeWk, id = Container::CurrentId()]() {
769             ContainerScope scope(id);
770             auto overlayManager = weak.Upgrade();
771             auto node = nodeWk.Upgrade();
772             CHECK_NULL_VOID(overlayManager && node);
773             SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_NONE };
774             node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
775             overlayManager->OnDialogCloseEvent(node);
776         },
777         TaskExecutor::TaskType::UI, "ArkUIOverlayDialogCloseEvent");
778 }
779 
FireAutoSave(const RefPtr<FrameNode> & ContainerNode)780 void OverlayManager::FireAutoSave(const RefPtr<FrameNode>& ContainerNode)
781 {
782     TAG_LOGD(AceLogTag::ACE_OVERLAY, "fire auto save enter");
783     CHECK_NULL_VOID(ContainerNode);
784     if (!ContainerNode->NeedRequestAutoSave()) {
785         return;
786     }
787     auto container = Container::Current();
788     auto currentId = Container::CurrentId();
789     CHECK_NULL_VOID(container);
790 
791     const auto& nodeTag = ContainerNode->GetTag();
792     if (nodeTag == V2::SHEET_PAGE_TAG) {
793         // BindSheet does not use subwindowManage. If use subwindow for display, autosave is started in the main window.
794         auto layoutProperty = ContainerNode->GetLayoutProperty<SheetPresentationProperty>();
795         CHECK_NULL_VOID(layoutProperty);
796         auto currentStyle = layoutProperty->GetSheetStyleValue();
797         if (currentStyle.instanceId.has_value()) {
798             auto pattern = ContainerNode->GetPattern<SheetPresentationPattern>();
799             CHECK_NULL_VOID(pattern);
800             auto targetNode = FrameNode::GetFrameNode(pattern->GetTargetTag(), pattern->GetTargetId());
801             CHECK_NULL_VOID(targetNode);
802             currentId = targetNode->GetInstanceId();
803         }
804     } else if (container->IsSubContainer()) {
805         currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
806     }
807     container->RequestAutoSave(ContainerNode, nullptr, nullptr, true, currentId);
808 }
809 
OnDialogCloseEvent(const RefPtr<FrameNode> & node)810 void OverlayManager::OnDialogCloseEvent(const RefPtr<FrameNode>& node)
811 {
812     CHECK_NULL_VOID(node);
813     TAG_LOGI(AceLogTag::ACE_DIALOG, "on dialog/%{public}d close event enter", node->GetId());
814 
815     BlurOverlayNode(node);
816     FireAutoSave(node);
817 
818     auto dialogPattern = node->GetPattern<DialogPattern>();
819     CHECK_NULL_VOID(dialogPattern);
820     auto option = dialogPattern->GetCloseAnimation().value_or(AnimationOption());
821     auto onFinish = option.GetOnFinishEvent();
822 
823     auto dialogLayoutProp = dialogPattern->GetLayoutProperty<DialogLayoutProperty>();
824     bool isShowInSubWindow = false;
825     if (dialogLayoutProp) {
826         isShowInSubWindow = dialogLayoutProp->GetShowInSubWindowValue(false);
827     }
828     if (onFinish != nullptr) {
829         onFinish();
830     }
831 
832     auto container = Container::Current();
833     auto currentId = Container::CurrentId();
834     CHECK_NULL_VOID(container);
835     if (isShowInSubWindow && !container->IsSubContainer()) {
836         currentId = SubwindowManager::GetInstance()->GetSubContainerId(currentId);
837     }
838 
839     ContainerScope scope(currentId);
840     auto root = node->GetParent();
841     CHECK_NULL_VOID(root);
842     node->OnAccessibilityEvent(
843         AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
844     DeleteDialogHotAreas(node);
845     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove DialogNode/%{public}d from RootNode/%{public}d",
846         node->GetId(), root->GetId());
847     root->RemoveChild(node, node->GetIsUseTransitionAnimator());
848     root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
849 
850     if (container->IsDialogContainer() || isShowInSubWindow) {
851         SubwindowManager::GetInstance()->HideSubWindowNG();
852     }
853 }
854 
OpenDialogAnimation(const RefPtr<FrameNode> & node)855 void OverlayManager::OpenDialogAnimation(const RefPtr<FrameNode>& node)
856 {
857     TAG_LOGD(AceLogTag::ACE_OVERLAY, "open dialog animation");
858     CHECK_NULL_VOID(node);
859     auto pipeline = PipelineContext::GetCurrentContext();
860     CHECK_NULL_VOID(pipeline);
861     auto theme = pipeline->GetTheme<DialogTheme>();
862     CHECK_NULL_VOID(theme);
863     auto root = rootNodeWeak_.Upgrade();
864     auto dialogPattern = node->GetPattern<DialogPattern>();
865     dialogPattern->CallDialogWillAppearCallback();
866     auto container = Container::Current();
867     if (container && container->IsScenceBoardWindow()) {
868         root = dialogPattern->GetDialogProperties().windowScene.Upgrade();
869     }
870     CHECK_NULL_VOID(root);
871     MountToParentWithService(root, node);
872     root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
873     BlurLowerNode(node);
874 
875     AnimationOption option;
876     // default opacity animation params
877     option.SetCurve(Curves::SHARP);
878     option.SetDuration(theme->GetOpacityAnimationDurIn());
879     option.SetFillMode(FillMode::FORWARDS);
880     option = dialogPattern->GetOpenAnimation().value_or(option);
881     option.SetIteration(1);
882     option.SetAnimationDirection(AnimationDirection::NORMAL);
883     auto onFinish = option.GetOnFinishEvent();
884     option.SetOnFinishEvent(
885         [weak = WeakClaim(this), nodeWK = WeakPtr<FrameNode>(node), onFinish] {
886             if (onFinish) {
887                 onFinish();
888             }
889             auto overlayManager = weak.Upgrade();
890             auto node = nodeWK.Upgrade();
891             CHECK_NULL_VOID(overlayManager && node);
892             overlayManager->FocusOverlayNode(node);
893             auto dialogPattern = node->GetPattern<DialogPattern>();
894             dialogPattern->CallDialogDidAppearCallback();
895         });
896     auto ctx = node->GetRenderContext();
897     option.SetFinishCallbackType(dialogPattern->GetOpenAnimation().has_value()
898                             ? dialogPattern->GetOpenAnimation().value().GetFinishCallbackType()
899                             : FinishCallbackType::REMOVED);
900     CHECK_NULL_VOID(ctx);
901     ctx->OpacityAnimation(option, theme->GetOpacityStart(), theme->GetOpacityEnd());
902     // scale animation on dialog content
903     auto contentNode = DynamicCast<FrameNode>(node->GetFirstChild());
904     CHECK_NULL_VOID(contentNode);
905     ctx = contentNode->GetRenderContext();
906     CHECK_NULL_VOID(ctx);
907     option.SetOnFinishEvent(nullptr);
908     option.SetCurve(SHOW_SCALE_ANIMATION_CURVE);
909     option.SetDuration(dialogPattern->GetOpenAnimation().has_value()
910                            ? dialogPattern->GetOpenAnimation().value().GetDuration()
911                            : theme->GetAnimationDurationIn());
912     ctx->ScaleAnimation(option, theme->GetScaleStart(), theme->GetScaleEnd());
913     node->OnAccessibilityEvent(
914         AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
915 }
916 
CloseDialogAnimation(const RefPtr<FrameNode> & node)917 void OverlayManager::CloseDialogAnimation(const RefPtr<FrameNode>& node)
918 {
919     TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog animation");
920     CHECK_NULL_VOID(node);
921     auto pipeline = PipelineContext::GetCurrentContext();
922     CHECK_NULL_VOID(pipeline);
923     auto theme = pipeline->GetTheme<DialogTheme>();
924     CHECK_NULL_VOID(theme);
925     SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_KEYBOARD };
926     node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
927 
928     // default opacity animation params
929     AnimationOption option;
930     option.SetFillMode(FillMode::FORWARDS);
931     option.SetCurve(Curves::SHARP);
932     option.SetDuration(theme->GetAnimationDurationOut());
933     // get customized animation params
934     auto dialogPattern = node->GetPattern<DialogPattern>();
935     dialogPattern->CallDialogWillDisappearCallback();
936     option = dialogPattern->GetCloseAnimation().value_or(option);
937     option.SetIteration(1);
938     option.SetAnimationDirection(AnimationDirection::NORMAL);
939     option.SetOnFinishEvent(
940         [weak = WeakClaim(this), nodeWk = WeakPtr<FrameNode>(node), dialogPattern, id = Container::CurrentId()] {
941             ContainerScope scope(id);
942             auto overlayManager = weak.Upgrade();
943             CHECK_NULL_VOID(overlayManager);
944             overlayManager->PostDialogFinishEvent(nodeWk);
945             dialogPattern->CallDialogDidDisappearCallback();
946         });
947     auto ctx = node->GetRenderContext();
948     if (!ctx) {
949         TAG_LOGW(AceLogTag::ACE_OVERLAY, "not find render context when closing dialog");
950         return;
951     }
952     option.SetFinishCallbackType(dialogPattern->GetOpenAnimation().has_value()
953                             ? dialogPattern->GetOpenAnimation().value().GetFinishCallbackType()
954                             : FinishCallbackType::REMOVED);
955     ctx->OpacityAnimation(option, theme->GetOpacityEnd(), theme->GetOpacityStart());
956 
957     // scale animation
958     auto contentNode = DynamicCast<FrameNode>(node->GetFirstChild());
959     CHECK_NULL_VOID(contentNode);
960     ctx = contentNode->GetRenderContext();
961     CHECK_NULL_VOID(ctx);
962     option.SetOnFinishEvent(nullptr);
963     option.SetCurve(Curves::FRICTION);
964     ctx->ScaleAnimation(option, theme->GetScaleEnd(), theme->GetScaleStart());
965     // start animation immediately
966     pipeline->RequestFrame();
967 }
968 
SetDialogTransitionEffect(const RefPtr<FrameNode> & node)969 void OverlayManager::SetDialogTransitionEffect(const RefPtr<FrameNode>& node)
970 {
971     TAG_LOGD(AceLogTag::ACE_OVERLAY, "set dialog transition");
972     CHECK_NULL_VOID(node);
973     auto root = rootNodeWeak_.Upgrade();
974     auto dialogPattern = node->GetPattern<DialogPattern>();
975     dialogPattern->CallDialogWillAppearCallback();
976 
977     auto layoutProperty = node->GetLayoutProperty();
978     layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
979 
980     auto ctx = node->GetRenderContext();
981     CHECK_NULL_VOID(ctx);
982     ctx->SetTransitionInCallback(
983         [weak = WeakClaim(this), nodeWK = WeakPtr<FrameNode>(node)] {
984             auto overlayManager = weak.Upgrade();
985             auto node = nodeWK.Upgrade();
986             CHECK_NULL_VOID(overlayManager && node);
987             overlayManager->FocusOverlayNode(node);
988             auto dialogPattern = node->GetPattern<DialogPattern>();
989             dialogPattern->CallDialogDidAppearCallback();
990         }
991     );
992 
993     auto container = Container::Current();
994     if (container && container->IsScenceBoardWindow()) {
995         root = dialogPattern->GetDialogProperties().windowScene.Upgrade();
996     }
997 
998     CHECK_NULL_VOID(root);
999     MountToParentWithService(root, node);
1000     root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1001     BlurLowerNode(node);
1002     node->OnAccessibilityEvent(
1003         AccessibilityEventType::CHANGE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1004 }
1005 
CloseDialogMatchTransition(const RefPtr<FrameNode> & node)1006 void OverlayManager::CloseDialogMatchTransition(const RefPtr<FrameNode>& node)
1007 {
1008     TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog match transition");
1009     CHECK_NULL_VOID(node);
1010     SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_KEYBOARD };
1011     node->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
1012     auto dialogPattern = node->GetPattern<DialogPattern>();
1013     dialogPattern->CallDialogWillDisappearCallback();
1014 
1015     auto ctx = node->GetRenderContext();
1016     if (!ctx) {
1017         TAG_LOGW(AceLogTag::ACE_OVERLAY, "not find render context when closing dialog");
1018         return;
1019     }
1020     auto layoutProperty = node->GetLayoutProperty();
1021     layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
1022     if (ctx->HasDisappearTransition()) {
1023         ctx->SetTransitionOutCallback(
1024             [weak = WeakClaim(this), nodeWk = WeakPtr<FrameNode>(node), id = Container::CurrentId()] {
1025                 ContainerScope scope(id);
1026                 auto overlayManager = weak.Upgrade();
1027                 CHECK_NULL_VOID(overlayManager);
1028                 overlayManager->PostDialogFinishEvent(nodeWk);
1029                 auto node = nodeWk.Upgrade();
1030                 CHECK_NULL_VOID(node);
1031                 auto dialogPattern = node->GetPattern<DialogPattern>();
1032                 dialogPattern->CallDialogDidDisappearCallback();
1033         });
1034     } else {
1035         auto id = Container::CurrentId();
1036         ContainerScope scope(id);
1037         auto overlayManager = WeakClaim(this).Upgrade();
1038         CHECK_NULL_VOID(overlayManager);
1039         auto nodeWk = WeakPtr<FrameNode>(node);
1040         overlayManager->PostDialogFinishEvent(nodeWk);
1041         dialogPattern->CallDialogDidDisappearCallback();
1042     }
1043 }
1044 
SetContainerButtonEnable(bool isEnabled)1045 void OverlayManager::SetContainerButtonEnable(bool isEnabled)
1046 {
1047     auto pipeline = PipelineContext::GetCurrentContext();
1048     CHECK_NULL_VOID(pipeline);
1049     pipeline->SetCloseButtonStatus(isEnabled);
1050 }
1051 
UpdateMenuVisibility(const RefPtr<FrameNode> & menu)1052 void OverlayManager::UpdateMenuVisibility(const RefPtr<FrameNode>& menu)
1053 {
1054     auto layoutProperty = menu->GetLayoutProperty();
1055     CHECK_NULL_VOID(layoutProperty);
1056     layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
1057 }
1058 
OnShowMenuAnimationFinished(const WeakPtr<FrameNode> menuWK,const WeakPtr<OverlayManager> weak,int32_t instanceId)1059 void OverlayManager::OnShowMenuAnimationFinished(const WeakPtr<FrameNode> menuWK, const WeakPtr<OverlayManager> weak,
1060     int32_t instanceId)
1061 {
1062     auto menu = menuWK.Upgrade();
1063     auto overlayManager = weak.Upgrade();
1064     CHECK_NULL_VOID(menu && overlayManager);
1065     ContainerScope scope(instanceId);
1066     auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1067     CHECK_NULL_VOID(menuNode);
1068     auto menuLayoutProp = menuNode->GetLayoutProperty<MenuLayoutProperty>();
1069     CHECK_NULL_VOID(menuLayoutProp);
1070     if (!menuLayoutProp->GetIsRectInTargetValue(false)) {
1071         overlayManager->FocusOverlayNode(menu);
1072     }
1073     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1074     menuWrapperPattern->CallMenuAppearCallback();
1075     menuWrapperPattern->SetMenuStatus(MenuStatus::SHOW);
1076 }
1077 
ShowMenuAnimation(const RefPtr<FrameNode> & menu)1078 void OverlayManager::ShowMenuAnimation(const RefPtr<FrameNode>& menu)
1079 {
1080     BlurLowerNode(menu);
1081     auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1082     CHECK_NULL_VOID(wrapperPattern);
1083     wrapperPattern->CallMenuAboutToAppearCallback();
1084     wrapperPattern->SetMenuStatus(MenuStatus::ON_SHOW_ANIMATION);
1085     SetIsMenuShow(true);
1086     if (wrapperPattern->HasTransitionEffect()) {
1087         UpdateMenuVisibility(menu);
1088         auto renderContext = menu->GetRenderContext();
1089         CHECK_NULL_VOID(renderContext);
1090         renderContext->SetTransitionInCallback(
1091             [weak = WeakClaim(this), menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId()] {
1092                 auto overlayManager = weak.Upgrade();
1093                 CHECK_NULL_VOID(overlayManager);
1094                 overlayManager->OnShowMenuAnimationFinished(menuWK, weak, id);
1095                 overlayManager->SendToAccessibility(menuWK, true);
1096             });
1097         return;
1098     }
1099     AnimationOption option;
1100     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1101     option.SetDuration(MENU_ANIMATION_DURATION);
1102     option.SetFillMode(FillMode::FORWARDS);
1103     option.SetOnFinishEvent(
1104         [weak = WeakClaim(this), menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId()] {
1105             auto overlayManager = weak.Upgrade();
1106             CHECK_NULL_VOID(overlayManager);
1107             overlayManager->OnShowMenuAnimationFinished(menuWK, weak, id);
1108             overlayManager->SendToAccessibility(menuWK, true);
1109         });
1110     if (wrapperPattern->GetPreviewMode() == MenuPreviewMode::CUSTOM) {
1111         auto pipelineContext = PipelineContext::GetCurrentContext();
1112         CHECK_NULL_VOID(pipelineContext);
1113         auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
1114         CHECK_NULL_VOID(menuTheme);
1115         option.SetDuration(menuTheme->GetContextMenuAppearDuration());
1116         auto previewChild = wrapperPattern->GetPreview();
1117         if (previewChild) {
1118             auto previewPattern = AceType::DynamicCast<MenuPreviewPattern>(previewChild->GetPattern());
1119             if (previewPattern) {
1120                 previewPattern->SetFirstShow();
1121             }
1122         }
1123     }
1124     wrapperPattern->SetAniamtinOption(option);
1125     SetPatternFirstShow(menu);
1126 }
1127 
SendToAccessibility(const WeakPtr<FrameNode> node,bool isShow)1128 void OverlayManager::SendToAccessibility(const WeakPtr<FrameNode> node, bool isShow)
1129 {
1130     auto menuWrapper = node.Upgrade();
1131     CHECK_NULL_VOID(menuWrapper);
1132     auto wrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
1133     CHECK_NULL_VOID(wrapperPattern);
1134     auto menu = wrapperPattern->GetMenu();
1135     CHECK_NULL_VOID(menu);
1136     auto accessibilityProperty = menu->GetAccessibilityProperty<MenuAccessibilityProperty>();
1137     CHECK_NULL_VOID(accessibilityProperty);
1138     accessibilityProperty->SetAccessibilityIsShow(isShow);
1139     if (isShow) {
1140         menu->OnAccessibilityEvent(AccessibilityEventType::PAGE_OPEN,
1141             WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1142         TAG_LOGI(AceLogTag::ACE_OVERLAY, "Send event to %{public}d",
1143             static_cast<int32_t>(AccessibilityEventType::PAGE_OPEN));
1144     } else {
1145         menu->OnAccessibilityEvent(AccessibilityEventType::PAGE_CLOSE,
1146             WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1147         TAG_LOGI(AceLogTag::ACE_OVERLAY, "Send event to %{public}d",
1148             static_cast<int32_t>(AccessibilityEventType::PAGE_CLOSE));
1149     }
1150 }
1151 
SetPatternFirstShow(const RefPtr<FrameNode> & menu)1152 void OverlayManager::SetPatternFirstShow(const RefPtr<FrameNode>& menu)
1153 {
1154     auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1155     CHECK_NULL_VOID(wrapperPattern);
1156     wrapperPattern->SetFirstShow();
1157     auto menuChild = wrapperPattern->GetMenu();
1158     CHECK_NULL_VOID(menuChild);
1159     auto menuPattern = AceType::DynamicCast<MenuPattern>(menuChild->GetPattern());
1160     CHECK_NULL_VOID(menuPattern);
1161     menuPattern->SetFirstShow();
1162     menuPattern->SetMenuShow();
1163 }
1164 
OnPopMenuAnimationFinished(const WeakPtr<FrameNode> menuWK,const WeakPtr<UINode> rootWeak,const WeakPtr<OverlayManager> weak,int32_t instanceId)1165 void OverlayManager::OnPopMenuAnimationFinished(const WeakPtr<FrameNode> menuWK, const WeakPtr<UINode> rootWeak,
1166     const WeakPtr<OverlayManager> weak, int32_t instanceId)
1167 {
1168     TAG_LOGI(AceLogTag::ACE_OVERLAY, "close menu animation finished");
1169     auto menu = menuWK.Upgrade();
1170     CHECK_NULL_VOID(menu);
1171     auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1172     CHECK_NULL_VOID(menuNode);
1173     auto eventHub = menuNode->GetEventHub<EventHub>();
1174     CHECK_NULL_VOID(eventHub);
1175     eventHub->SetEnabledInternal(true);
1176     auto menuPattern = menuNode->GetPattern<MenuPattern>();
1177     CHECK_NULL_VOID(menuPattern);
1178     auto root = rootWeak.Upgrade();
1179     auto overlayManager = weak.Upgrade();
1180     CHECK_NULL_VOID(overlayManager);
1181 
1182     overlayManager->SetContextMenuDragHideFinished(true);
1183     DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_FINISHED);
1184     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1185     menuWrapperPattern->CallMenuDisappearCallback();
1186     menuWrapperPattern->SetMenuStatus(MenuStatus::HIDE);
1187     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1188     if (mainPipeline && menuWrapperPattern->GetMenuDisappearCallback()) {
1189         ContainerScope scope(mainPipeline->GetInstanceId());
1190         mainPipeline->FlushPipelineImmediately();
1191     }
1192     // clear contextMenu then return
1193     auto pipeline = PipelineBase::GetCurrentContext();
1194     CHECK_NULL_VOID(pipeline);
1195     auto theme = pipeline->GetTheme<SelectTheme>();
1196     CHECK_NULL_VOID(theme);
1197     auto expandDisplay = theme->GetExpandDisplay();
1198     auto menuLayoutProp = menuPattern->GetLayoutProperty<MenuLayoutProperty>();
1199     CHECK_NULL_VOID(menuLayoutProp);
1200     bool isShowInSubWindow = menuLayoutProp->GetShowInSubWindowValue(true);
1201     auto targetId = menuWrapperPattern->GetTargetId();
1202     overlayManager->EraseMenuInfo(targetId);
1203     if (((menuWrapperPattern && menuWrapperPattern->IsContextMenu()) || (isShowInSubWindow && expandDisplay)) &&
1204         (menuPattern->GetTargetTag() != V2::SELECT_ETS_TAG)) {
1205         SubwindowManager::GetInstance()->ClearMenuNG(instanceId, menuWrapperPattern->GetTargetId());
1206         overlayManager->ResetContextMenuDragHideFinished();
1207         overlayManager->SetIsMenuShow(false);
1208         return;
1209     }
1210     overlayManager->RemoveMenuNotInSubWindow(menuWK, rootWeak, weak);
1211     overlayManager->SetIsMenuShow(false);
1212 }
1213 
PopMenuAnimation(const RefPtr<FrameNode> & menu,bool showPreviewAnimation,bool startDrag)1214 void OverlayManager::PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation, bool startDrag)
1215 {
1216     TAG_LOGI(AceLogTag::ACE_OVERLAY, "pop menu animation enter");
1217     CHECK_NULL_VOID(menu);
1218     auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1219     CHECK_NULL_VOID(wrapperPattern);
1220 
1221     if (wrapperPattern->IsHide()) {
1222         return;
1223     }
1224 
1225     ResetLowerNodeFocusable(menu);
1226     ResetContextMenuDragHideFinished();
1227     RemoveMenuBadgeNode(menu);
1228 
1229     auto menuNode = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
1230     CHECK_NULL_VOID(menuNode);
1231     auto eventHub = menuNode->GetEventHub<EventHub>();
1232     CHECK_NULL_VOID(eventHub);
1233     eventHub->SetEnabledInternal(false);
1234 
1235     wrapperPattern->CallMenuAboutToDisappearCallback();
1236     wrapperPattern->SetMenuStatus(MenuStatus::ON_HIDE_ANIMATION);
1237     if (wrapperPattern->HasTransitionEffect() || wrapperPattern->HasFoldModeChangedTransition()) {
1238         if (wrapperPattern->GetPreviewMode() != MenuPreviewMode::NONE) {
1239             ShowPreviewDisappearAnimation(wrapperPattern);
1240         }
1241         auto layoutProperty = menu->GetLayoutProperty();
1242         CHECK_NULL_VOID(layoutProperty);
1243         layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
1244         auto renderContext = menu->GetRenderContext();
1245         CHECK_NULL_VOID(renderContext);
1246         if (wrapperPattern->HasFoldModeChangedTransition()) {
1247             TAG_LOGI(AceLogTag::ACE_OVERLAY, "Close menu when foldMode is changed, disappear transiton is %{public}d",
1248                 renderContext->HasDisappearTransition());
1249         }
1250 
1251         if (renderContext->HasDisappearTransition()) {
1252             renderContext->SetTransitionOutCallback(
1253                 [rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1254                                     weak = WeakClaim(this)] {
1255                     ContainerScope scope(id);
1256                     auto overlayManager = weak.Upgrade();
1257                     CHECK_NULL_VOID(overlayManager);
1258                     overlayManager->SendToAccessibility(menuWK, false);
1259                     overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1260                 });
1261         } else {
1262             auto context = PipelineContext::GetCurrentContext();
1263             CHECK_NULL_VOID(context);
1264             auto taskExecutor = context->GetTaskExecutor();
1265             CHECK_NULL_VOID(taskExecutor);
1266             taskExecutor->PostTask(
1267                 [rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1268                     weak = WeakClaim(this)] {
1269                     ContainerScope scope(id);
1270                     auto overlayManager = weak.Upgrade();
1271                     CHECK_NULL_VOID(overlayManager);
1272                     overlayManager->SendToAccessibility(menuWK, false);
1273                     overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1274                 },
1275                 TaskExecutor::TaskType::UI, "ArkUIOverlayPopMenuAnimation");
1276         }
1277         return;
1278     }
1279 
1280     AnimationOption option;
1281     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1282     option.SetDuration(MENU_ANIMATION_DURATION);
1283     option.SetFillMode(FillMode::FORWARDS);
1284     if (!startDrag) {
1285         DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_STARTED);
1286     }
1287     option.SetOnFinishEvent([rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1288                                 weak = WeakClaim(this)] {
1289         ContainerScope scope(id);
1290         auto overlayManager = weak.Upgrade();
1291         CHECK_NULL_VOID(overlayManager);
1292         overlayManager->SendToAccessibility(menuWK, false);
1293         overlayManager->OnPopMenuAnimationFinished(menuWK, rootWeak, weak, id);
1294     });
1295     ShowMenuClearAnimation(menu, option, showPreviewAnimation, startDrag);
1296 }
1297 
ClearMenuAnimation(const RefPtr<FrameNode> & menu,bool showPreviewAnimation,bool startDrag)1298 void OverlayManager::ClearMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation, bool startDrag)
1299 {
1300     TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear menu animation enter");
1301     ResetLowerNodeFocusable(menu);
1302     RemoveMenuBadgeNode(menu);
1303     AnimationOption option;
1304     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
1305     option.SetDuration(MENU_ANIMATION_DURATION);
1306     option.SetFillMode(FillMode::FORWARDS);
1307     option.SetOnFinishEvent([rootWeak = rootNodeWeak_, menuWK = WeakClaim(RawPtr(menu)), id = Container::CurrentId(),
1308                                 weak = WeakClaim(this)] {
1309         auto menu = menuWK.Upgrade();
1310         auto root = rootWeak.Upgrade();
1311         auto overlayManager = weak.Upgrade();
1312         CHECK_NULL_VOID(menu && overlayManager);
1313         ContainerScope scope(id);
1314         auto container = Container::Current();
1315         if (container && container->IsScenceBoardWindow()) {
1316             root = overlayManager->FindWindowScene(menu);
1317         }
1318         CHECK_NULL_VOID(root);
1319         auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
1320         // clear contextMenu then return
1321         if ((menuWrapperPattern && menuWrapperPattern->IsContextMenu())) {
1322             return;
1323         }
1324         overlayManager->BlurOverlayNode(menu);
1325         root->RemoveChild(menu);
1326         root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1327     });
1328     ShowMenuClearAnimation(menu, option, showPreviewAnimation, startDrag);
1329 }
1330 
ShowMenuClearAnimation(const RefPtr<FrameNode> & menuWrapper,AnimationOption & option,bool showPreviewAnimation,bool startDrag)1331 void OverlayManager::ShowMenuClearAnimation(const RefPtr<FrameNode>& menuWrapper, AnimationOption& option,
1332     bool showPreviewAnimation, bool startDrag)
1333 {
1334     TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menuWrapper clear animation enter");
1335     auto context = menuWrapper->GetRenderContext();
1336     CHECK_NULL_VOID(context);
1337     auto pipeline = PipelineBase::GetCurrentContext();
1338     CHECK_NULL_VOID(pipeline);
1339     auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
1340     CHECK_NULL_VOID(menuWrapperPattern);
1341     auto menuAnimationOffset = menuWrapperPattern->GetAnimationOffset();
1342     auto outterMenu = menuWrapperPattern->GetMenu();
1343     CHECK_NULL_VOID(outterMenu);
1344     auto outterMenuPattern = outterMenu->GetPattern<MenuPattern>();
1345     CHECK_NULL_VOID(outterMenuPattern);
1346     bool isShow = outterMenuPattern->GetDisappearAnimation();
1347     bool isPreviewModeNone = menuWrapperPattern->GetPreviewMode() == MenuPreviewMode::NONE;
1348     if (!isPreviewModeNone
1349         || (isPreviewModeNone && IsContextMenuBindedOnOrigNode() && !showPreviewAnimation && startDrag)) {
1350         if (!showPreviewAnimation) {
1351             CleanPreviewInSubWindow();
1352         } else {
1353             ShowPreviewDisappearAnimation(menuWrapperPattern);
1354         }
1355         ShowContextMenuDisappearAnimation(option, menuWrapperPattern, startDrag);
1356     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && isShow) {
1357         FireMenuDisappear(option, menuWrapperPattern);
1358     } else {
1359         AnimationUtils::Animate(
1360             option,
1361             [context, menuAnimationOffset]() {
1362                 context->UpdateOpacity(0.0);
1363                 context->UpdateOffset(menuAnimationOffset);
1364             },
1365             option.GetOnFinishEvent());
1366 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1367         auto* transactionProxy = Rosen::RSTransactionProxy::GetInstance();
1368         if (transactionProxy != nullptr) {
1369             transactionProxy->FlushImplicitTransaction();
1370         }
1371 #endif
1372     }
1373     // start animation immediately
1374     pipeline->RequestFrame();
1375 }
1376 
1377 // check if there is a bound menu on the current floating node on the main window
IsContextMenuBindedOnOrigNode()1378 bool OverlayManager::IsContextMenuBindedOnOrigNode()
1379 {
1380     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1381     CHECK_NULL_RETURN(mainPipeline, false);
1382     auto dragDropManager = mainPipeline->GetDragDropManager();
1383     CHECK_NULL_RETURN(dragDropManager, false);
1384     auto draggingNode = dragDropManager->GetPrepareDragFrameNode().Upgrade();
1385     CHECK_NULL_RETURN(draggingNode, false);
1386     auto eventHub = draggingNode->GetEventHub<EventHub>();
1387     CHECK_NULL_RETURN(eventHub, false);
1388     auto frameNode = eventHub->GetFrameNode();
1389     CHECK_NULL_RETURN(frameNode, false);
1390     auto focusHub = frameNode->GetFocusHub();
1391     CHECK_NULL_RETURN(focusHub, false);
1392     return focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1393 }
1394 
ShowToast(const NG::ToastInfo & toastInfo)1395 void OverlayManager::ShowToast(const NG::ToastInfo& toastInfo)
1396 {
1397     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast enter");
1398     auto context = PipelineContext::GetCurrentContext();
1399     CHECK_NULL_VOID(context);
1400     auto rootNode = context->GetRootElement();
1401     CHECK_NULL_VOID(rootNode);
1402 
1403     // only one toast
1404     for (auto [id, toastNodeWeak] : toastMap_) {
1405         rootNode->RemoveChild(toastNodeWeak.Upgrade());
1406     }
1407     toastMap_.clear();
1408     auto toastNode = ToastView::CreateToastNode(toastInfo);
1409     CHECK_NULL_VOID(toastNode);
1410     auto toastId = toastNode->GetId();
1411     // mount to parent
1412     TAG_LOGD(AceLogTag::ACE_OVERLAY, "toast mount to root");
1413     toastNode->MountToParent(rootNode);
1414     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1415     toastMap_[toastId] = toastNode;
1416     OpenToastAnimation(toastNode, toastInfo.duration);
1417     if (toastInfo.showMode == NG::ToastShowMode::DEFAULT) {
1418         TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast DEFAULT");
1419     } else if (toastInfo.showMode == NG::ToastShowMode::TOP_MOST) {
1420         TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast TOP_MOST");
1421     } else if (toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1422         TAG_LOGD(AceLogTag::ACE_OVERLAY, "show toast SYSTEM_TOP_MOST");
1423     }
1424 }
1425 
OpenToastAnimation(const RefPtr<FrameNode> & toastNode,int32_t duration)1426 void OverlayManager::OpenToastAnimation(const RefPtr<FrameNode>& toastNode, int32_t duration)
1427 {
1428     TAG_LOGD(AceLogTag::ACE_OVERLAY, "open toast animation enter");
1429     auto toastId = toastNode->GetId();
1430     AnimationOption option;
1431     auto curve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.1f, 1.0f);
1432     option.SetCurve(curve);
1433     option.SetDuration(TOAST_ANIMATION_DURATION);
1434     option.SetFillMode(FillMode::FORWARDS);
1435     duration = std::max(duration, AceApplicationInfo::GetInstance().GetBarrierfreeDuration());
1436     continuousTask_.Reset([weak = WeakClaim(this), toastId, duration, id = Container::CurrentId()]() {
1437         auto overlayManager = weak.Upgrade();
1438         CHECK_NULL_VOID(overlayManager);
1439         ContainerScope scope(id);
1440         overlayManager->PopToast(toastId);
1441     });
1442     option.SetOnFinishEvent([continuousTask = continuousTask_, duration, id = Container::CurrentId()] {
1443         ContainerScope scope(id);
1444         auto context = PipelineContext::GetCurrentContext();
1445         CHECK_NULL_VOID(context);
1446         auto taskExecutor = context->GetTaskExecutor();
1447         CHECK_NULL_VOID(taskExecutor);
1448         taskExecutor->PostDelayedTask(
1449             continuousTask, TaskExecutor::TaskType::UI, duration, "ArkUIOverlayContinuousPopToast");
1450     });
1451     auto ctx = toastNode->GetRenderContext();
1452     CHECK_NULL_VOID(ctx);
1453     ctx->UpdateOpacity(0.0);
1454     ctx->OnTransformTranslateUpdate({ 0.0f, TOAST_ANIMATION_POSITION, 0.0f });
1455     AnimationUtils::Animate(
1456         option,
1457         [ctx]() {
1458             if (ctx) {
1459                 ctx->UpdateOpacity(1.0);
1460                 ctx->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
1461             }
1462         },
1463         option.GetOnFinishEvent());
1464     auto toastProperty = toastNode->GetLayoutProperty<ToastLayoutProperty>();
1465     CHECK_NULL_VOID(toastProperty);
1466     toastProperty->SetSelectStatus(ToastLayoutProperty::SelectStatus::ON);
1467     toastNode->OnAccessibilityEvent(
1468         AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1469 }
1470 
PopToast(int32_t toastId)1471 void OverlayManager::PopToast(int32_t toastId)
1472 {
1473     TAG_LOGD(AceLogTag::ACE_OVERLAY, "pop toast enter");
1474     AnimationOption option;
1475     auto curve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.1f, 1.0f);
1476     option.SetCurve(curve);
1477     option.SetDuration(TOAST_ANIMATION_DURATION);
1478     option.SetFillMode(FillMode::FORWARDS);
1479     // OnFinishEvent should be executed in UI thread.
1480     option.SetOnFinishEvent([weak = WeakClaim(this), toastId] {
1481         TAG_LOGD(AceLogTag::ACE_OVERLAY, "start toast exit finish event");
1482         auto overlayManager = weak.Upgrade();
1483         CHECK_NULL_VOID(overlayManager);
1484         auto toastIter = overlayManager->toastMap_.find(toastId);
1485         if (toastIter == overlayManager->toastMap_.end()) {
1486             return;
1487         }
1488         auto toastUnderPop = toastIter->second.Upgrade();
1489         CHECK_NULL_VOID(toastUnderPop);
1490         auto context = PipelineContext::GetCurrentContext();
1491         CHECK_NULL_VOID(context);
1492         auto rootNode = context->GetRootElement();
1493         CHECK_NULL_VOID(rootNode);
1494         TAG_LOGI(AceLogTag::ACE_OVERLAY, "toast remove from root");
1495         rootNode->RemoveChild(toastUnderPop);
1496         overlayManager->toastMap_.erase(toastId);
1497         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1498 
1499         auto container = Container::Current();
1500         CHECK_NULL_VOID(container);
1501         if (container->IsDialogContainer() || (container->IsSubContainer() && rootNode->GetChildren().empty())) {
1502             auto pattern = toastUnderPop->GetPattern<ToastPattern>();
1503             CHECK_NULL_VOID(pattern);
1504             auto toastInfo = pattern->GetToastInfo();
1505             // hide window when toast show in subwindow.
1506             if (toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1507                 SubwindowManager::GetInstance()->HideSystemTopMostWindow();
1508             } else {
1509                 SubwindowManager::GetInstance()->HideToastSubWindowNG();
1510             }
1511         }
1512     });
1513     auto toastIter = toastMap_.find(toastId);
1514     if (toastIter == toastMap_.end()) {
1515         return;
1516     }
1517     auto toastUnderPop = toastIter->second.Upgrade();
1518     CHECK_NULL_VOID(toastUnderPop);
1519     auto ctx = toastUnderPop->GetRenderContext();
1520     CHECK_NULL_VOID(ctx);
1521     ctx->UpdateOpacity(1.0);
1522     ctx->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
1523     AnimationUtils::Animate(
1524         option,
1525         [ctx]() {
1526             if (ctx) {
1527                 ctx->UpdateOpacity(0.0);
1528                 ctx->OnTransformTranslateUpdate({ 0.0f, TOAST_ANIMATION_POSITION, 0.0f });
1529             }
1530         },
1531         option.GetOnFinishEvent());
1532 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1533     auto* transactionProxy = Rosen::RSTransactionProxy::GetInstance();
1534     if (transactionProxy != nullptr) {
1535         transactionProxy->FlushImplicitTransaction();
1536     }
1537 #endif
1538     // start animation immediately
1539     auto pipeline = PipelineContext::GetCurrentContext();
1540     CHECK_NULL_VOID(pipeline);
1541     pipeline->RequestFrame();
1542     auto toastProperty = toastUnderPop->GetLayoutProperty<ToastLayoutProperty>();
1543     CHECK_NULL_VOID(toastProperty);
1544     toastProperty->SetSelectStatus(ToastLayoutProperty::SelectStatus::OFF);
1545     toastUnderPop->OnAccessibilityEvent(
1546         AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1547 }
1548 
ClearToastInSubwindow()1549 void OverlayManager::ClearToastInSubwindow()
1550 {
1551     TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear toast in subwindow enter");
1552     SubwindowManager::GetInstance()->ClearToastInSubwindow();
1553 }
1554 
ClearToast()1555 void OverlayManager::ClearToast()
1556 {
1557     TAG_LOGD(AceLogTag::ACE_OVERLAY, "clear toast enter");
1558     auto context = PipelineContext::GetCurrentContext();
1559     CHECK_NULL_VOID(context);
1560     auto rootNode = context->GetRootElement();
1561     CHECK_NULL_VOID(rootNode);
1562     for (auto [id, toastNodeWeak] : toastMap_) {
1563         PopToast(id);
1564     }
1565 }
1566 
ShowPopupAnimation(const RefPtr<FrameNode> & popupNode)1567 void OverlayManager::ShowPopupAnimation(const RefPtr<FrameNode>& popupNode)
1568 {
1569     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1570     CHECK_NULL_VOID(popupPattern);
1571     popupPattern->ResetFocusState();
1572     BlurLowerNode(popupNode);
1573     auto onFinish = [popupNodeWk = WeakPtr<FrameNode>(popupNode), weak = WeakClaim(this)]() {
1574         auto overlayManager = weak.Upgrade();
1575         auto popupNode = popupNodeWk.Upgrade();
1576         CHECK_NULL_VOID(overlayManager && popupNode);
1577         overlayManager->FocusOverlayNode(popupNode);
1578     };
1579     if (popupPattern->GetHasTransition()) {
1580         popupPattern->StartEnteringTransitionEffects(popupNode, onFinish);
1581     } else {
1582         popupPattern->StartEnteringAnimation(onFinish);
1583     }
1584 }
1585 
ShowPopupAnimationNG(const RefPtr<FrameNode> & popupNode)1586 void OverlayManager::ShowPopupAnimationNG(const RefPtr<FrameNode>& popupNode)
1587 {
1588     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1589     CHECK_NULL_VOID(popupPattern);
1590     if (popupPattern->GetHasTransition()) {
1591         popupPattern->StartEnteringTransitionEffects(popupNode, nullptr);
1592     } else {
1593         popupPattern->StartEnteringAnimation(nullptr);
1594     }
1595 }
1596 
HidePopupAnimation(const RefPtr<FrameNode> & popupNode,const std::function<void ()> & finish)1597 void OverlayManager::HidePopupAnimation(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish)
1598 {
1599     auto rootNode = rootNodeWeak_.Upgrade();
1600     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1601     if (popupPattern->GetHasTransition()) {
1602         if (!popupNode->GetRenderContext()->HasDisappearTransition()) {
1603             popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1604             popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1605             RemoveChildWithService(rootNode, popupNode);
1606             rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1607             auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1608             CHECK_NULL_VOID(layoutProp);
1609             auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1610             if (isShowInSubWindow) {
1611                 auto subwindowMgr = SubwindowManager::GetInstance();
1612                 subwindowMgr->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1613             }
1614         } else {
1615             popupPattern->StartExitingTransitionEffects(popupNode, finish);
1616         }
1617     } else {
1618         popupPattern->StartExitingAnimation(finish);
1619     }
1620 }
1621 
ShowPopup(int32_t targetId,const PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)1622 void OverlayManager::ShowPopup(int32_t targetId, const PopupInfo& popupInfo,
1623     const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
1624 {
1625     if (!UpdatePopupMap(targetId, popupInfo)) {
1626         TAG_LOGE(AceLogTag::ACE_OVERLAY, "failed to update popup map, tag:%{public}s",
1627             popupInfo.target.Upgrade()->GetTag().c_str());
1628         return;
1629     }
1630     auto rootNode = rootNodeWeak_.Upgrade();
1631     CHECK_NULL_VOID(rootNode);
1632     auto frameNode = AceType::DynamicCast<FrameNode>(rootNode);
1633     if (frameNode && !frameNode->IsLayoutComplete()) {
1634         auto context = PipelineContext::GetCurrentContext();
1635         CHECK_NULL_VOID(context);
1636         auto taskExecutor = context->GetTaskExecutor();
1637         CHECK_NULL_VOID(taskExecutor);
1638         taskExecutor->PostTask(
1639             [targetId, popupInfo, weak = WeakClaim(this), callback = std::move(onWillDismiss), interactiveDismiss]() {
1640                 auto overlayManager = weak.Upgrade();
1641                 CHECK_NULL_VOID(overlayManager);
1642                 overlayManager->MountPopup(targetId, popupInfo, std::move(callback), interactiveDismiss);
1643             },
1644             TaskExecutor::TaskType::UI, "ArkUIOverlayShowPopup");
1645     } else {
1646         MountPopup(targetId, popupInfo, std::move(onWillDismiss), interactiveDismiss);
1647     }
1648 }
1649 
UpdatePopupMap(int32_t targetId,const PopupInfo & popupInfo)1650 bool OverlayManager::UpdatePopupMap(int32_t targetId, const PopupInfo& popupInfo)
1651 {
1652     popupMap_[targetId] = popupInfo;
1653     if (!popupInfo.markNeedUpdate) {
1654         TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1655         return false;
1656     }
1657     popupMap_[targetId].markNeedUpdate = false;
1658     return true;
1659 }
1660 
MountPopup(int32_t targetId,const PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)1661 void OverlayManager::MountPopup(int32_t targetId, const PopupInfo& popupInfo,
1662     const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
1663 {
1664     // TargetNode may be destroyed when MontPopup is thrown thread.
1665     auto targetNode = popupInfo.target.Upgrade();
1666     CHECK_NULL_VOID(targetNode);
1667     auto popupNode = popupInfo.popupNode;
1668     CHECK_NULL_VOID(popupNode);
1669     auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1670     CHECK_NULL_VOID(layoutProp);
1671     auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1672     auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1673     CHECK_NULL_VOID(paintProperty);
1674     auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1675     auto isUseCustom = paintProperty->GetUseCustom().value_or(false);
1676 
1677     auto rootNode = rootNodeWeak_.Upgrade();
1678     auto container = Container::Current();
1679     if (container && container->IsScenceBoardWindow()) {
1680         rootNode = FindWindowScene(popupInfo.target.Upgrade());
1681     }
1682     CHECK_NULL_VOID(rootNode);
1683     CHECK_NULL_VOID(popupInfo.markNeedUpdate);
1684     CHECK_NULL_VOID(popupInfo.popupNode);
1685 
1686     const auto& rootChildren = rootNode->GetChildren();
1687     auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode);
1688     if (iter == rootChildren.rend()) {
1689         MountToParentWithService(rootNode, popupNode);
1690     }
1691 
1692     // attach popupNode before entering animation
1693     popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(true);
1694     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1695     popupMap_[targetId].isCurrentOnShow = true;
1696 
1697     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1698     CHECK_NULL_VOID(popupPattern);
1699     popupPattern->AddPipelineCallBack();
1700     popupPattern->SetInteractiveDismiss(interactiveDismiss);
1701     popupPattern->UpdateOnWillDismiss(move(onWillDismiss));
1702     if ((isTypeWithOption && !isShowInSubWindow) ||
1703         (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && popupInfo.focusable)) {
1704         ShowPopupAnimation(popupNode);
1705     } else {
1706         ShowPopupAnimationNG(popupNode);
1707     }
1708     SetPopupHotAreas(popupNode);
1709     SendPopupAccessibilityPageOpen(popupNode);
1710 }
1711 
SetPopupHotAreas(RefPtr<FrameNode> popupNode)1712 void OverlayManager::SetPopupHotAreas(RefPtr<FrameNode> popupNode)
1713 {
1714     CHECK_NULL_VOID(popupNode);
1715     auto popupId = popupNode->GetId();
1716     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1717     CHECK_NULL_VOID(popupPattern);
1718     auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1719     CHECK_NULL_VOID(layoutProp);
1720     auto isBlock = layoutProp->GetBlockEventValue(true);
1721     auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1722     if (isShowInSubWindow && popupPattern->IsOnShow()) {
1723         std::vector<Rect> rects;
1724         if (!isBlock) {
1725             auto rect = Rect(popupPattern->GetChildOffset().GetX(), popupPattern->GetChildOffset().GetY(),
1726                 popupPattern->GetChildSize().Width(), popupPattern->GetChildSize().Height());
1727             rects.emplace_back(rect);
1728         } else {
1729             auto parentWindowRect = popupPattern->GetHostWindowRect();
1730             auto rect = Rect(popupPattern->GetChildOffset().GetX(), popupPattern->GetChildOffset().GetY(),
1731                 popupPattern->GetChildSize().Width(), popupPattern->GetChildSize().Height());
1732             rects.emplace_back(parentWindowRect);
1733             rects.emplace_back(rect);
1734         }
1735         auto subWindowMgr = SubwindowManager::GetInstance();
1736         subWindowMgr->SetHotAreas(rects, popupId, popupPattern->GetContainerId());
1737     }
1738 }
1739 
HidePopup(int32_t targetId,const PopupInfo & popupInfo)1740 void OverlayManager::HidePopup(int32_t targetId, const PopupInfo& popupInfo)
1741 {
1742     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide popup enter");
1743     popupMap_[targetId] = popupInfo;
1744     if (!popupInfo.markNeedUpdate) {
1745         TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1746         return;
1747     }
1748     popupMap_[targetId].markNeedUpdate = false;
1749     auto focusable = popupInfo.focusable;
1750     auto popupNode = popupInfo.popupNode;
1751     CHECK_NULL_VOID(popupNode);
1752     auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1753     CHECK_NULL_VOID(layoutProp);
1754     auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1755     auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1756     CHECK_NULL_VOID(paintProperty);
1757     auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1758     auto isUseCustom = paintProperty->GetUseCustom().value_or(false);
1759 
1760     auto rootNode = rootNodeWeak_.Upgrade();
1761     auto container = Container::Current();
1762     if (container && container->IsScenceBoardWindow()) {
1763         rootNode = FindWindowScene(popupInfo.target.Upgrade());
1764     }
1765     CHECK_NULL_VOID(rootNode);
1766 
1767     auto pipeline = rootNode->GetContextRefPtr();
1768     CHECK_NULL_VOID(pipeline);
1769     const auto& rootChildren = rootNode->GetChildren();
1770     auto iter = std::find(rootChildren.rbegin(), rootChildren.rend(), popupNode);
1771     // There is no overlay under the root node or it is not in atomicservice
1772     if (iter == rootChildren.rend() && !pipeline->GetInstallationFree()) {
1773         return;
1774     }
1775 
1776     auto popupPattern = popupNode->GetPattern<BubblePattern>();
1777     CHECK_NULL_VOID(popupPattern);
1778     if (popupPattern->GetTransitionStatus() == TransitionStatus::EXITING) {
1779         return;
1780     }
1781     popupPattern->SetTransitionStatus(TransitionStatus::EXITING);
1782     if ((isTypeWithOption && !isShowInSubWindow) ||
1783         (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && focusable)) {
1784         ResetLowerNodeFocusable(popupNode);
1785     }
1786     CheckReturnFocus(popupNode);
1787     auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
1788     CHECK_NULL_VOID(accessibilityProperty);
1789     accessibilityProperty->SetShowedState(0);
1790     popupNode->OnAccessibilityEvent(
1791         AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1792     // detach popupNode after exiting animation
1793     popupMap_[targetId].isCurrentOnShow = false;
1794     auto onFinish = [isShowInSubWindow, isTypeWithOption, isUseCustom, focusable,
1795         targetId, popupNodeWk = WeakPtr<FrameNode>(popupNode),
1796         rootNodeWk = WeakPtr<UINode>(rootNode), weak = WeakClaim(this)]() {
1797         auto rootNode = rootNodeWk.Upgrade();
1798         auto popupNode = popupNodeWk.Upgrade();
1799         auto overlayManager = weak.Upgrade();
1800         CHECK_NULL_VOID(rootNode && popupNode && overlayManager);
1801         if (overlayManager->popupMap_[targetId].isCurrentOnShow) {
1802             return;
1803         }
1804         auto popupPattern = popupNode->GetPattern<BubblePattern>();
1805         CHECK_NULL_VOID(popupPattern);
1806         popupPattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1807         popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1808         popupNode->GetRenderContext()->UpdateChainedTransition(nullptr);
1809         overlayManager->RemoveChildWithService(rootNode, popupNode);
1810         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1811         overlayManager->ErasePopupInfo(targetId);
1812         if ((isTypeWithOption && !isShowInSubWindow) ||
1813             (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) && isUseCustom && focusable)) {
1814             overlayManager->BlurOverlayNode(popupNode);
1815         }
1816         if (isShowInSubWindow) {
1817             auto subwindow = SubwindowManager::GetInstance();
1818             subwindow->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1819             subwindow->HideSubWindowNG();
1820         }
1821     };
1822     HidePopupAnimation(popupNode, onFinish);
1823     RemoveEventColumn();
1824     RemovePixelMapAnimation(false, 0, 0);
1825     RemoveGatherNodeWithAnimation();
1826     RemoveFilter();
1827 }
1828 
HidePopupWithoutAnimation(int32_t targetId,const PopupInfo & popupInfo)1829 RefPtr<FrameNode> OverlayManager::HidePopupWithoutAnimation(int32_t targetId, const PopupInfo& popupInfo)
1830 {
1831     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide popup without animation enter");
1832     popupMap_[targetId] = popupInfo;
1833     CHECK_NULL_RETURN(popupInfo.markNeedUpdate, nullptr);
1834     if (!popupInfo.markNeedUpdate) {
1835         TAG_LOGW(AceLogTag::ACE_OVERLAY, "mark need update failed");
1836         return nullptr;
1837     }
1838     CHECK_NULL_RETURN(popupInfo.popupNode, nullptr);
1839     auto bubbleRenderProp = popupInfo.popupNode->GetPaintProperty<BubbleRenderProperty>();
1840     CHECK_NULL_RETURN(bubbleRenderProp, nullptr);
1841     auto autoCancel = bubbleRenderProp->GetAutoCancel().value_or(true);
1842     if (!autoCancel) {
1843         return nullptr;
1844     }
1845     popupInfo.popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1846     CHECK_NULL_RETURN(popupInfo.isCurrentOnShow, nullptr);
1847     popupMap_[targetId].isCurrentOnShow = false;
1848     auto pattern = popupInfo.popupNode->GetPattern<BubblePattern>();
1849     CHECK_NULL_RETURN(pattern, nullptr);
1850     pattern->SetTransitionStatus(TransitionStatus::INVISIABLE);
1851     auto rootNode = rootNodeWeak_.Upgrade();
1852     CHECK_NULL_RETURN(rootNode, nullptr);
1853     auto rootChildren = rootNode->GetChildren();
1854     auto iter = std::find(rootChildren.begin(), rootChildren.end(), popupInfo.popupNode);
1855     if (iter != rootChildren.end()) {
1856         return popupMap_[targetId].popupNode;
1857     }
1858     return nullptr;
1859 }
1860 
ShowIndexerPopup(int32_t targetId,RefPtr<FrameNode> & customNode)1861 void OverlayManager::ShowIndexerPopup(int32_t targetId, RefPtr<FrameNode>& customNode)
1862 {
1863     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show indexer popup enter");
1864     CHECK_NULL_VOID(customNode);
1865     auto rootNode = rootNodeWeak_.Upgrade();
1866     CHECK_NULL_VOID(rootNode);
1867     if (!customPopupMap_[targetId] || customPopupMap_[targetId] != customNode) {
1868         customPopupMap_[targetId] = customNode;
1869         customNode->MountToParent(rootNode);
1870         customNode->MarkModifyDone();
1871         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1872     }
1873 }
1874 
RemoveIndexerPopupById(int32_t targetId)1875 void OverlayManager::RemoveIndexerPopupById(int32_t targetId)
1876 {
1877     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove indexer popup by id enter");
1878     if (customPopupMap_.empty()) {
1879         return;
1880     }
1881     auto rootNode = rootNodeWeak_.Upgrade();
1882     CHECK_NULL_VOID(rootNode);
1883     auto iter = customPopupMap_.find(targetId);
1884     if (iter != customPopupMap_.end()) {
1885         RemoveChildWithService(rootNode, iter->second);
1886         customPopupMap_.erase(iter);
1887         rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
1888     }
1889 }
1890 
RemoveIndexerPopup()1891 void OverlayManager::RemoveIndexerPopup()
1892 {
1893     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove indexer popup enter");
1894     if (customPopupMap_.empty()) {
1895         return;
1896     }
1897     auto rootNode = rootNodeWeak_.Upgrade();
1898     CHECK_NULL_VOID(rootNode);
1899     for (const auto& popup : customPopupMap_) {
1900         auto popupNode = popup.second;
1901         RemoveChildWithService(rootNode, popupNode);
1902     }
1903     customPopupMap_.clear();
1904     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
1905 }
1906 
HideCustomPopups()1907 void OverlayManager::HideCustomPopups()
1908 {
1909     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide custom popup enter");
1910     if (popupMap_.empty()) {
1911         return;
1912     }
1913     for (const auto& popup : popupMap_) {
1914         auto popupInfo = popup.second;
1915         if (popupInfo.isCurrentOnShow && popupInfo.target.Upgrade()) {
1916             auto targetNodeId = popupInfo.target.Upgrade()->GetId();
1917             auto popupNode = popupInfo.popupNode;
1918             CHECK_NULL_VOID(popupNode);
1919             auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1920             CHECK_NULL_VOID(layoutProp);
1921             auto paintProperty = popupNode->GetPaintProperty<BubbleRenderProperty>();
1922             CHECK_NULL_VOID(paintProperty);
1923             auto isTypeWithOption = paintProperty->GetPrimaryButtonShow().value_or(false);
1924             popupNode->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
1925             // if use popup with option, skip
1926             if (isTypeWithOption) {
1927                 continue;
1928             }
1929             popupInfo.markNeedUpdate = true;
1930             auto showInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1931             if (showInSubWindow) {
1932                 SubwindowManager::GetInstance()->HidePopupNG(targetNodeId);
1933             } else {
1934                 HidePopup(targetNodeId, popupInfo);
1935             }
1936         }
1937     }
1938 }
1939 
HideAllPopups()1940 void OverlayManager::HideAllPopups()
1941 {
1942     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all popup enter");
1943     if (popupMap_.empty()) {
1944         return;
1945     }
1946     auto tempPopupMap = popupMap_;
1947     for (const auto& popup : tempPopupMap) {
1948         auto popupInfo = popup.second;
1949         if (popupInfo.isCurrentOnShow && popupInfo.target.Upgrade()) {
1950             auto targetNodeId = popupInfo.target.Upgrade()->GetId();
1951             auto popupNode = popupInfo.popupNode;
1952             CHECK_NULL_VOID(popupNode);
1953             auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1954             CHECK_NULL_VOID(layoutProp);
1955             popupInfo.markNeedUpdate = true;
1956             auto showInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1957             if (showInSubWindow) {
1958                 SubwindowManager::GetInstance()->HidePopupNG(targetNodeId);
1959             } else {
1960                 HidePopup(targetNodeId, popupInfo);
1961             }
1962         }
1963     }
1964 }
1965 
ErasePopup(int32_t targetId)1966 void OverlayManager::ErasePopup(int32_t targetId)
1967 {
1968     TAG_LOGD(AceLogTag::ACE_OVERLAY, "erase popup enter");
1969     auto it = popupMap_.find(targetId);
1970     if (it != popupMap_.end()) {
1971         auto rootNode = rootNodeWeak_.Upgrade();
1972         CHECK_NULL_VOID(rootNode);
1973         auto popupNode = it->second.popupNode;
1974         CHECK_NULL_VOID(popupNode);
1975         auto layoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
1976         CHECK_NULL_VOID(layoutProp);
1977         auto isShowInSubWindow = layoutProp->GetShowInSubWindow().value_or(false);
1978         auto accessibilityProperty = popupNode->GetAccessibilityProperty<BubbleAccessibilityProperty>();
1979         CHECK_NULL_VOID(accessibilityProperty);
1980         accessibilityProperty->SetShowedState(0);
1981         popupNode->OnAccessibilityEvent(
1982             AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
1983         if (isShowInSubWindow) {
1984             auto subwindowMgr = SubwindowManager::GetInstance();
1985             subwindowMgr->DeleteHotAreas(Container::CurrentId(), popupNode->GetId());
1986         }
1987         RemoveChildWithService(rootNode, popupNode);
1988         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1989         popupMap_.erase(targetId);
1990     }
1991 }
1992 
DismissPopup()1993 void OverlayManager::DismissPopup()
1994 {
1995     auto iter = popupMap_.find(dismissPopupId_);
1996     if (iter == popupMap_.end()) {
1997         return;
1998     }
1999     auto popupInfo = iter->second;
2000     popupInfo.markNeedUpdate = true;
2001     HidePopup(dismissPopupId_, popupInfo);
2002 }
2003 
ShowMenuHelper(RefPtr<FrameNode> & menu,int32_t targetId,const NG::OffsetF & offset)2004 bool OverlayManager::ShowMenuHelper(RefPtr<FrameNode>& menu, int32_t targetId, const NG::OffsetF& offset)
2005 {
2006     TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu helper enter");
2007     if (!menu) {
2008         // get existing menuNode
2009         auto it = menuMap_.find(targetId);
2010         if (it != menuMap_.end()) {
2011             menu = it->second;
2012         }
2013     } else {
2014         // creating new menu
2015         menuMap_[targetId] = menu;
2016     }
2017     CHECK_NULL_RETURN(menu, false);
2018 
2019     RefPtr<FrameNode> menuFrameNode = menu;
2020     if (menu->GetTag() != V2::MENU_ETS_TAG) {
2021         auto menuChild = menu->GetChildAtIndex(0);
2022         CHECK_NULL_RETURN(menuChild, false);
2023         menuFrameNode = DynamicCast<FrameNode>(menuChild);
2024     }
2025 
2026     auto props = menuFrameNode->GetLayoutProperty<MenuLayoutProperty>();
2027     CHECK_NULL_RETURN(props, false);
2028     props->UpdateMenuOffset(offset);
2029     menuFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
2030     return true;
2031 }
2032 
ShowMenu(int32_t targetId,const NG::OffsetF & offset,RefPtr<FrameNode> menu)2033 void OverlayManager::ShowMenu(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu)
2034 {
2035     TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu enter");
2036     if (!ShowMenuHelper(menu, targetId, offset)) {
2037         TAG_LOGW(AceLogTag::ACE_OVERLAY, "show menu helper failed");
2038         return;
2039     }
2040     auto rootNode = rootNodeWeak_.Upgrade();
2041     auto container = Container::Current();
2042     if (container && container->IsScenceBoardWindow()) {
2043         auto wrapperPattern = AceType::DynamicCast<MenuWrapperPattern>(menu->GetPattern());
2044         CHECK_NULL_VOID(wrapperPattern);
2045         auto menuChild = wrapperPattern->GetMenu();
2046         CHECK_NULL_VOID(menuChild);
2047         auto menuPattern = AceType::DynamicCast<MenuPattern>(menuChild->GetPattern());
2048         CHECK_NULL_VOID(menuPattern);
2049         rootNode = FindWindowScene(FrameNode::GetFrameNode(menuPattern->GetTargetTag(), menuPattern->GetTargetId()));
2050     }
2051     CHECK_NULL_VOID(rootNode);
2052     auto rootChildren = rootNode->GetChildren();
2053     auto iter = std::find(rootChildren.begin(), rootChildren.end(), menu);
2054     // menuNode already showing
2055     if (iter == rootChildren.end()) {
2056         MountToParentWithService(rootNode, menu);
2057         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2058         menu->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2059         ShowMenuAnimation(menu);
2060         menu->MarkModifyDone();
2061     }
2062 }
2063 
2064 // subwindow only contains one menu instance.
ShowMenuInSubWindow(int32_t targetId,const NG::OffsetF & offset,RefPtr<FrameNode> menu)2065 void OverlayManager::ShowMenuInSubWindow(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu)
2066 {
2067     TAG_LOGI(AceLogTag::ACE_OVERLAY, "show menu insubwindow enter");
2068     auto menuOffset = offset;
2069     auto currentSubwindow = SubwindowManager::GetInstance()->GetCurrentWindow();
2070     if (currentSubwindow) {
2071         auto subwindowRect = currentSubwindow->GetRect();
2072         menuOffset -= subwindowRect.GetOffset();
2073     }
2074     if (!ShowMenuHelper(menu, targetId, menuOffset)) {
2075         TAG_LOGW(AceLogTag::ACE_OVERLAY, "show menu helper failed");
2076         return;
2077     }
2078     auto rootNode = rootNodeWeak_.Upgrade();
2079     CHECK_NULL_VOID(rootNode);
2080 
2081     std::vector<int32_t> idsNeedClean;
2082     for (auto child: rootNode->GetChildren()) {
2083         idsNeedClean.push_back(child->GetId());
2084     }
2085     auto pipeline = rootNode->GetContext();
2086     CHECK_NULL_VOID(pipeline);
2087     pipeline->AddAfterLayoutTask([idsNeedClean, containerId = Container::CurrentId()] {
2088         auto subwindowMgr = SubwindowManager::GetInstance();
2089         for (auto child : idsNeedClean) {
2090             subwindowMgr->DeleteHotAreas(containerId, child);
2091         }
2092     });
2093     rootNode->Clean();
2094 
2095     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
2096     CHECK_NULL_VOID(menuWrapperPattern);
2097     if (menuWrapperPattern->IsContextMenu() && menuWrapperPattern->GetPreviewMode() != MenuPreviewMode::NONE) {
2098         auto filterNode = menuWrapperPattern->GetFilterColumnNode();
2099         if (filterNode) {
2100             SetHasFilter(true);
2101             SetFilterColumnNode(filterNode);
2102             filterNode->MountToParent(rootNode);
2103             ShowFilterAnimation(filterNode);
2104             filterNode->MarkModifyDone();
2105         }
2106     }
2107     menu->MountToParent(rootNode);
2108     ShowMenuAnimation(menu);
2109     menu->MarkModifyDone();
2110     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2111     pipeline->FlushUITasks();
2112 
2113     // set subwindow container id in menu.
2114     auto menuPattern = menu->GetPattern<PopupBasePattern>();
2115     CHECK_NULL_VOID(menuPattern);
2116     menuPattern->SetContainerId(Container::CurrentId());
2117 }
2118 
HideMenuInSubWindow(const RefPtr<FrameNode> & menu,int32_t targetId)2119 void OverlayManager::HideMenuInSubWindow(const RefPtr<FrameNode>& menu, int32_t targetId)
2120 {
2121     TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu insubwindow enter");
2122     CHECK_NULL_VOID(menu);
2123     if (menu->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2124         auto wrapperPattern = menu->GetPattern<MenuWrapperPattern>();
2125         CHECK_NULL_VOID(wrapperPattern);
2126         wrapperPattern->UpdateMenuAnimation(menu);
2127     }
2128     PopMenuAnimation(menu);
2129 }
2130 
HideMenuInSubWindow(bool showPreviewAnimation,bool startDrag)2131 void OverlayManager::HideMenuInSubWindow(bool showPreviewAnimation, bool startDrag)
2132 {
2133     TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu insubwindow enter");
2134     if (menuMap_.empty()) {
2135         return;
2136     }
2137     auto rootNode = rootNodeWeak_.Upgrade();
2138     for (const auto& child : rootNode->GetChildren()) {
2139         auto node = DynamicCast<FrameNode>(child);
2140         if (node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2141             PopMenuAnimation(node, showPreviewAnimation, startDrag);
2142         }
2143     }
2144 }
2145 
GetMenuNode(int32_t targetId)2146 RefPtr<FrameNode> OverlayManager::GetMenuNode(int32_t targetId)
2147 {
2148     auto it = menuMap_.find(targetId);
2149     if (it != menuMap_.end()) {
2150         return it->second;
2151     }
2152     return nullptr;
2153 }
2154 
HideMenu(const RefPtr<FrameNode> & menu,int32_t targetId,bool isMenuOnTouch)2155 void OverlayManager::HideMenu(const RefPtr<FrameNode>& menu, int32_t targetId, bool isMenuOnTouch)
2156 {
2157     TAG_LOGI(AceLogTag::ACE_OVERLAY, "hide menu enter");
2158     PopMenuAnimation(menu);
2159     RemoveEventColumn();
2160     if (isMenuOnTouch) {
2161         RemovePixelMap();
2162         RemoveGatherNode();
2163     } else {
2164         RemovePixelMapAnimation(false, 0, 0);
2165         RemoveGatherNodeWithAnimation();
2166     }
2167     RemoveFilterAnimation();
2168 }
2169 
HideAllMenus()2170 void OverlayManager::HideAllMenus()
2171 {
2172     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all menus enter");
2173     auto container = Container::Current();
2174     if (container && container->IsScenceBoardWindow()) {
2175         for (const auto& windowScene : windowSceneSet_) {
2176             if (!windowScene.Upgrade()) {
2177                 continue;
2178             }
2179             for (const auto& child : windowScene.Upgrade()->GetChildren()) {
2180                 auto node = DynamicCast<FrameNode>(child);
2181                 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2182                     PopMenuAnimation(node);
2183                 }
2184             }
2185         }
2186         return;
2187     }
2188 
2189     auto rootNode = rootNodeWeak_.Upgrade();
2190     CHECK_NULL_VOID(rootNode);
2191     for (const auto& child : rootNode->GetChildren()) {
2192         auto node = DynamicCast<FrameNode>(child);
2193         if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2194             auto wrapperPattern = node->GetPattern<MenuWrapperPattern>();
2195             CHECK_NULL_VOID(wrapperPattern);
2196             wrapperPattern->UpdateMenuAnimation(node);
2197             PopMenuAnimation(node);
2198         }
2199     }
2200 }
2201 
DeleteMenu(int32_t targetId)2202 void OverlayManager::DeleteMenu(int32_t targetId)
2203 {
2204     TAG_LOGI(AceLogTag::ACE_OVERLAY, "delete menu enter");
2205     auto it = menuMap_.find(targetId);
2206     if (it == menuMap_.end()) {
2207         return;
2208     }
2209     auto node = AceType::DynamicCast<FrameNode>(it->second);
2210     if (node->GetParent()) {
2211         auto id = Container::CurrentId();
2212         SubwindowManager::GetInstance()->ClearMenu();
2213         SubwindowManager::GetInstance()->ClearMenuNG(id, targetId);
2214 
2215         if (node->GetParent()) {
2216             RemoveEventColumn();
2217             RemoveMenuNotInSubWindow(WeakClaim(RawPtr(node)), rootNodeWeak_, WeakClaim(this));
2218         }
2219     }
2220     EraseMenuInfo(targetId);
2221 }
2222 
CleanMenuInSubWindowWithAnimation()2223 void OverlayManager::CleanMenuInSubWindowWithAnimation()
2224 {
2225     TAG_LOGD(AceLogTag::ACE_OVERLAY, "clean menu insubwindow with animation enter");
2226     auto rootNode = rootNodeWeak_.Upgrade();
2227     CHECK_NULL_VOID(rootNode);
2228     RefPtr<FrameNode> menu;
2229     for (const auto& child : rootNode->GetChildren()) {
2230         auto node = DynamicCast<FrameNode>(child);
2231         if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2232             menu = node;
2233             break;
2234         }
2235     }
2236     CHECK_NULL_VOID(menu);
2237     PopMenuAnimation(menu);
2238 }
2239 
CleanHoverImagePreviewInSubWindow(const RefPtr<FrameNode> & flexNode)2240 void OverlayManager::CleanHoverImagePreviewInSubWindow(const RefPtr<FrameNode>& flexNode)
2241 {
2242     CHECK_NULL_VOID(flexNode && flexNode->GetTag() == V2::FLEX_ETS_TAG);
2243     for (const auto& child : flexNode->GetChildren()) {
2244         auto node = DynamicCast<FrameNode>(child);
2245         CHECK_NULL_VOID(node && node->GetTag() == V2::STACK_ETS_TAG);
2246 
2247         auto previewNode = node->GetLastChild();
2248         if (previewNode && previewNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG) {
2249             node->RemoveChild(previewNode);
2250         }
2251 
2252         auto imageNode = node->GetFirstChild();
2253         if (imageNode && imageNode->GetTag() == V2::IMAGE_ETS_TAG) {
2254             node->RemoveChild(imageNode);
2255         }
2256 
2257         flexNode->RemoveChild(node);
2258         flexNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2259         break;
2260     }
2261 }
2262 
CleanPreviewInSubWindow()2263 void OverlayManager::CleanPreviewInSubWindow()
2264 {
2265     auto rootNode = rootNodeWeak_.Upgrade();
2266     CHECK_NULL_VOID(rootNode);
2267     for (const auto& child : rootNode->GetChildren()) {
2268         auto node = DynamicCast<FrameNode>(child);
2269         if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2270             for (auto& childNode : node->GetChildren()) {
2271                 auto frameNode = DynamicCast<FrameNode>(childNode);
2272                 if (frameNode && (frameNode->GetTag() == V2::FLEX_ETS_TAG ||
2273                     frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
2274                     CleanHoverImagePreviewInSubWindow(frameNode);
2275                     auto imagelayoutProperty = frameNode->GetLayoutProperty();
2276                     if (imagelayoutProperty) {
2277                         imagelayoutProperty->UpdateVisibility(VisibleType::GONE);
2278                     } else {
2279                         TAG_LOGW(AceLogTag::ACE_OVERLAY, "Preview image failed to set invisible.");
2280                     }
2281                     break;
2282                 }
2283             }
2284             break;
2285         }
2286     }
2287 }
2288 
CleanMenuInSubWindow(int32_t targetId)2289 void OverlayManager::CleanMenuInSubWindow(int32_t targetId)
2290 {
2291     TAG_LOGI(AceLogTag::ACE_OVERLAY, "clean menu insubwindow enter");
2292     auto rootNode = rootNodeWeak_.Upgrade();
2293     CHECK_NULL_VOID(rootNode);
2294 
2295     for (const auto& child : rootNode->GetChildren()) {
2296         auto node = DynamicCast<FrameNode>(child);
2297         if (node && node->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
2298             continue;
2299         }
2300 
2301         auto menuWrapperPattern = node->GetPattern<MenuWrapperPattern>();
2302         CHECK_NULL_VOID(menuWrapperPattern);
2303         if (menuWrapperPattern->GetTargetId() != targetId) {
2304             continue;
2305         }
2306 
2307         for (auto& childNode : node->GetChildren()) {
2308             auto frameNode = DynamicCast<FrameNode>(childNode);
2309             if (frameNode && (frameNode->GetTag() == V2::FLEX_ETS_TAG ||
2310                 frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
2311                 CleanHoverImagePreviewInSubWindow(frameNode);
2312                 node->RemoveChild(frameNode);
2313                 break;
2314             }
2315         }
2316         rootNode->RemoveChild(node);
2317         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2318         auto subwindowMgr = SubwindowManager::GetInstance();
2319         subwindowMgr->DeleteHotAreas(Container::CurrentId(), node->GetId());
2320         menuWrapperPattern->SetMenuStatus(MenuStatus::HIDE);
2321         break;
2322     }
2323 }
2324 
CleanPopupInSubWindow()2325 void OverlayManager::CleanPopupInSubWindow()
2326 {
2327     TAG_LOGD(AceLogTag::ACE_OVERLAY, "clean popup insubwindow enter");
2328     auto rootNode = rootNodeWeak_.Upgrade();
2329     CHECK_NULL_VOID(rootNode);
2330     std::vector<RefPtr<FrameNode>> removeNodes;
2331     for (const auto& child : rootNode->GetChildren()) {
2332         if (!child || child->GetTag() != V2::POPUP_ETS_TAG) {
2333             continue;
2334         }
2335         auto id = child->GetId();
2336         for (const auto& popup : popupMap_) {
2337             auto popupInfo = popup.second;
2338             auto target = popup.first;
2339             if (id != popupInfo.popupId) {
2340                 continue;
2341             }
2342             popupInfo.markNeedUpdate = true;
2343             auto removeNode = HidePopupWithoutAnimation(target, popupInfo);
2344             if (removeNode) {
2345                 removeNodes.emplace_back(removeNode);
2346                 auto subwindowMgr = SubwindowManager::GetInstance();
2347                 subwindowMgr->DeleteHotAreas(Container::CurrentId(), removeNode->GetId());
2348                 ErasePopupInfo(target);
2349             }
2350             break;
2351         }
2352     }
2353     for (const auto& removeNode : removeNodes) {
2354         rootNode->RemoveChild(removeNode);
2355     }
2356     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2357 }
2358 
BeforeShowDialog(const RefPtr<FrameNode> & node)2359 void OverlayManager::BeforeShowDialog(const RefPtr<FrameNode>& node)
2360 {
2361     TAG_LOGD(AceLogTag::ACE_OVERLAY, "before show dialog");
2362     CHECK_NULL_VOID(node);
2363     if (dialogMap_.find(node->GetId()) != dialogMap_.end()) {
2364         return;
2365     }
2366     dialogMap_[node->GetId()] = node;
2367 }
2368 
SetDialogMask(const DialogProperties & dialogProps)2369 RefPtr<FrameNode> OverlayManager::SetDialogMask(const DialogProperties& dialogProps)
2370 {
2371     DialogProperties Maskarg;
2372     Maskarg.isMask = true;
2373     Maskarg.autoCancel = dialogProps.autoCancel;
2374     Maskarg.onWillDismiss = dialogProps.onWillDismiss;
2375     Maskarg.maskColor = dialogProps.maskColor;
2376     return ShowDialog(Maskarg, nullptr, false);
2377 }
2378 
ShowDialog(const DialogProperties & dialogProps,std::function<void ()> && buildFunc,bool isRightToLeft)2379 RefPtr<FrameNode> OverlayManager::ShowDialog(
2380     const DialogProperties& dialogProps, std::function<void()>&& buildFunc, bool isRightToLeft)
2381 {
2382     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show dialog enter");
2383     RefPtr<UINode> customNode;
2384     // create custom builder content
2385     if (buildFunc) {
2386         NG::ScopedViewStackProcessor builderViewStackProcessor;
2387         buildFunc();
2388         customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2389         CHECK_NULL_RETURN(customNode, nullptr);
2390     }
2391 
2392     auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2393     CHECK_NULL_RETURN(dialog, nullptr);
2394     BeforeShowDialog(dialog);
2395     if (dialogProps.transitionEffect != nullptr) {
2396         SetDialogTransitionEffect(dialog);
2397     } else {
2398         OpenDialogAnimation(dialog);
2399     }
2400     dialogCount_++;
2401     // set close button disable
2402     SetContainerButtonEnable(false);
2403     if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2404         Recorder::EventParamsBuilder builder;
2405         builder
2406             .SetType("Dialog")
2407             .SetEventType(Recorder::EventType::DIALOG_SHOW)
2408             .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2409             .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2410         Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2411     }
2412     return dialog;
2413 }
2414 
ShowDialogWithNode(const DialogProperties & dialogProps,const RefPtr<UINode> & customNode,bool isRightToLeft)2415 RefPtr<FrameNode> OverlayManager::ShowDialogWithNode(
2416     const DialogProperties& dialogProps, const RefPtr<UINode>& customNode, bool isRightToLeft)
2417 {
2418     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show dialog enter");
2419     CHECK_NULL_RETURN(customNode, nullptr);
2420     auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2421     CHECK_NULL_RETURN(dialog, nullptr);
2422     BeforeShowDialog(dialog);
2423     if (dialogProps.transitionEffect != nullptr) {
2424         SetDialogTransitionEffect(dialog);
2425     } else {
2426         OpenDialogAnimation(dialog);
2427     }
2428     dialogCount_++;
2429     // set close button disable
2430     SetContainerButtonEnable(false);
2431     if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2432         Recorder::EventParamsBuilder builder;
2433         builder
2434             .SetType("Dialog")
2435             .SetEventType(Recorder::EventType::DIALOG_SHOW)
2436             .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2437             .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2438         Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2439     }
2440     return dialog;
2441 }
2442 
GetDialogNodeWithExistContent(const RefPtr<UINode> & node)2443 RefPtr<FrameNode> OverlayManager::GetDialogNodeWithExistContent(const RefPtr<UINode>& node)
2444 {
2445     auto iter = dialogMap_.begin();
2446     while (iter != dialogMap_.end()) {
2447         auto dialogNode = (*iter).second;
2448         CHECK_NULL_RETURN(dialogNode, nullptr);
2449         auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2450         CHECK_NULL_RETURN(dialogPattern, nullptr);
2451         if (dialogPattern->GetCustomNode() == node) {
2452             return dialogNode;
2453         }
2454         iter++;
2455     }
2456     return nullptr;
2457 }
2458 
RegisterDialogLifeCycleCallback(const RefPtr<FrameNode> & dialog,const DialogProperties & dialogProps)2459 void OverlayManager::RegisterDialogLifeCycleCallback(
2460     const RefPtr<FrameNode>& dialog, const DialogProperties& dialogProps)
2461 {
2462     auto dialogPattern = dialog->GetPattern<DialogPattern>();
2463     CHECK_NULL_VOID(dialogPattern);
2464     auto onDidAppearEvent = dialogProps.onDidAppear;
2465     dialogPattern->RegisterDialogDidAppearCallback(std::move(onDidAppearEvent));
2466     auto onDidDisappearEvent = dialogProps.onDidDisappear;
2467     dialogPattern->RegisterDialogDidDisappearCallback(std::move(onDidDisappearEvent));
2468     auto onWillAppearEvent = dialogProps.onWillAppear;
2469     dialogPattern->RegisterDialogWillAppearCallback(std::move(onWillAppearEvent));
2470     auto onWillDisappearEvent = dialogProps.onWillDisappear;
2471     dialogPattern->RegisterDialogWillDisappearCallback(std::move(onWillDisappearEvent));
2472 }
2473 
CustomDialogRecordEvent(const DialogProperties & dialogProps)2474 void OverlayManager::CustomDialogRecordEvent(const DialogProperties& dialogProps)
2475 {
2476     if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2477         Recorder::EventParamsBuilder builder;
2478         builder
2479             .SetType("Dialog")
2480             .SetEventType(Recorder::EventType::DIALOG_SHOW)
2481             .SetExtra(Recorder::KEY_TITLE, dialogProps.title)
2482             .SetExtra(Recorder::KEY_SUB_TITLE, dialogProps.subtitle);
2483         Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2484     }
2485 }
2486 
RebuildCustomBuilder(RefPtr<UINode> & contentNode)2487 RefPtr<UINode> OverlayManager::RebuildCustomBuilder(RefPtr<UINode>& contentNode)
2488 {
2489     auto currentId = Container::CurrentId();
2490     if (!(currentId >= MIN_SUBCONTAINER_ID && currentId < MIN_PLUGIN_SUBCONTAINER_ID)) {
2491         return contentNode;
2492     }
2493 
2494     RefPtr<UINode> customNode;
2495     auto lazyBuilderFunc = contentNode->GetBuilderFunc();
2496     if (lazyBuilderFunc) {
2497         NG::ScopedViewStackProcessor builderViewStackProcessor;
2498         lazyBuilderFunc();
2499         customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2500     } else {
2501         customNode = contentNode;
2502     }
2503 
2504     auto updateNodeFunc = contentNode->GetUpdateNodeFunc();
2505     if (updateNodeFunc) {
2506         updateNodeFunc(currentId, customNode);
2507     }
2508     auto updateNodeConfig = contentNode->GetUpdateNodeConfig();
2509     if (updateNodeConfig) {
2510         customNode->SetUpdateNodeConfig(std::move(updateNodeConfig));
2511     }
2512     return customNode;
2513 }
2514 
ReloadBuilderNodeConfig()2515 void OverlayManager::ReloadBuilderNodeConfig()
2516 {
2517     if (dialogMap_.empty()) {
2518         return;
2519     }
2520     auto iter = dialogMap_.begin();
2521     while (iter != dialogMap_.end()) {
2522         auto dialogNode = (*iter).second;
2523         if (dialogNode) {
2524             auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2525             CHECK_NULL_VOID(dialogPattern);
2526             auto customNode = dialogPattern->GetCustomNode();
2527             if (customNode && customNode->GetUpdateNodeConfig()) {
2528                 customNode->GetUpdateNodeConfig()();
2529             }
2530         }
2531         iter++;
2532     }
2533 }
2534 
OpenCustomDialog(const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)2535 void OverlayManager::OpenCustomDialog(const DialogProperties& dialogProps, std::function<void(int32_t)> &&callback)
2536 {
2537     RefPtr<UINode> customNode;
2538     bool showComponentContent = false;
2539     if (!callback) {
2540         TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of OpenCustomDialog are incomplete because of no callback.");
2541         return;
2542     }
2543     if (dialogProps.customBuilder) {
2544         TAG_LOGD(AceLogTag::ACE_DIALOG, "open custom dialog with custom builder.");
2545         NG::ScopedViewStackProcessor builderViewStackProcessor(Container::CurrentId());
2546         dialogProps.customBuilder();
2547         customNode = NG::ViewStackProcessor::GetInstance()->Finish();
2548         if (!customNode) {
2549             TAG_LOGE(AceLogTag::ACE_DIALOG, "Fail to build custom node.");
2550             callback(-1);
2551             return;
2552         }
2553     } else {
2554         auto contentNode = dialogProps.contentNode.Upgrade();
2555         if (!contentNode) {
2556             TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2557             callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2558             return;
2559         }
2560         if (GetDialogNodeWithExistContent(contentNode)) {
2561             TAG_LOGW(AceLogTag::ACE_DIALOG, "Content of custom dialog already existed.");
2562             callback(ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST);
2563             return;
2564         }
2565         TAG_LOGD(AceLogTag::ACE_DIALOG, "OpenCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2566         customNode = RebuildCustomBuilder(contentNode);
2567         showComponentContent = true;
2568     }
2569     auto dialog = DialogView::CreateDialogNode(dialogProps, customNode);
2570     if (!dialog) {
2571         TAG_LOGE(AceLogTag::ACE_DIALOG, "Fail to create dialog node.");
2572         callback(showComponentContent ? ERROR_CODE_DIALOG_CONTENT_ERROR : -1);
2573         return;
2574     }
2575     RegisterDialogLifeCycleCallback(dialog, dialogProps);
2576     BeforeShowDialog(dialog);
2577 
2578     callback(showComponentContent ? ERROR_CODE_NO_ERROR : dialog->GetId());
2579 
2580     if (dialogProps.transitionEffect != nullptr) {
2581         SetDialogTransitionEffect(dialog);
2582     } else {
2583         OpenDialogAnimation(dialog);
2584     }
2585 
2586     dialogCount_++;
2587     CustomDialogRecordEvent(dialogProps);
2588     return;
2589 }
2590 
CloseCustomDialog(const int32_t dialogId)2591 void OverlayManager::CloseCustomDialog(const int32_t dialogId)
2592 {
2593     auto iter = dialogMap_.end();
2594     if (dialogId == -1) {
2595         int32_t tmpNodeId = -1;
2596         RefPtr<FrameNode> tmpNode;
2597         iter = dialogMap_.begin();
2598         while (iter != dialogMap_.end()) {
2599             auto dialogNode = (*iter).second;
2600             if (dialogNode && dialogNode->GetId() > tmpNodeId) {
2601                 tmpNodeId = dialogNode->GetId();
2602                 tmpNode = dialogNode;
2603             }
2604             iter++;
2605         }
2606         if (tmpNode) {
2607             DeleteDialogHotAreas(tmpNode);
2608             CloseDialogInner(tmpNode);
2609         } else {
2610             TAG_LOGE(AceLogTag::ACE_DIALOG, "not find dialog when no dialog id");
2611         }
2612     } else {
2613         iter = dialogMap_.find(dialogId);
2614         if (iter == dialogMap_.end()) {
2615             TAG_LOGE(AceLogTag::ACE_DIALOG, "not find dialog by id %{public}d", dialogId);
2616             return;
2617         }
2618         RefPtr<FrameNode> tmpDialog = (*iter).second;
2619         DeleteDialogHotAreas(tmpDialog);
2620         CloseDialogInner(tmpDialog);
2621     }
2622     return;
2623 }
2624 
CloseCustomDialog(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)2625 void OverlayManager::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)> &&callback)
2626 {
2627     if (!callback) {
2628         TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of CloseCustomDialog are incomplete because of no callback.");
2629         return;
2630     }
2631     auto contentNode = node.Upgrade();
2632     if (!contentNode) {
2633         TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2634         callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2635         return;
2636     }
2637     TAG_LOGD(AceLogTag::ACE_DIALOG, "CloseCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2638     auto dialogNode = GetDialogNodeWithExistContent(contentNode);
2639     if (!dialogNode) {
2640         dialogNode = SubwindowManager::GetInstance()->GetSubwindowDialogNodeWithExistContent(contentNode);
2641     }
2642     if (dialogNode) {
2643         DeleteDialogHotAreas(dialogNode);
2644         CloseDialogInner(dialogNode);
2645         callback(ERROR_CODE_NO_ERROR);
2646         return;
2647     }
2648     TAG_LOGE(AceLogTag::ACE_DIALOG, "UpdateCustomDialog failed because cannot find dialog.");
2649     callback(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND);
2650 }
2651 
UpdateCustomDialog(const WeakPtr<NG::UINode> & node,const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)2652 void OverlayManager::UpdateCustomDialog(
2653     const WeakPtr<NG::UINode>& node, const DialogProperties& dialogProps, std::function<void(int32_t)> &&callback)
2654 {
2655     if (!callback) {
2656         TAG_LOGE(AceLogTag::ACE_DIALOG, "Parameters of UpdateCustomDialog are incomplete because of no callback.");
2657         return;
2658     }
2659     auto contentNode = node.Upgrade();
2660     if (!contentNode) {
2661         TAG_LOGE(AceLogTag::ACE_DIALOG, "Content of custom dialog is null");
2662         callback(ERROR_CODE_DIALOG_CONTENT_ERROR);
2663         return;
2664     }
2665     TAG_LOGD(AceLogTag::ACE_DIALOG, "UpdateCustomDialog ComponentContent id: %{public}d", contentNode->GetId());
2666     auto dialogNode = GetDialogNodeWithExistContent(contentNode);
2667     if (!dialogNode) {
2668         dialogNode = SubwindowManager::GetInstance()->GetSubwindowDialogNodeWithExistContent(contentNode);
2669     }
2670     if (dialogNode) {
2671         auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2672         CHECK_NULL_VOID(dialogLayoutProp);
2673         dialogLayoutProp->UpdateDialogAlignment(dialogProps.alignment);
2674         dialogLayoutProp->UpdateDialogOffset(dialogProps.offset);
2675         dialogLayoutProp->UpdateAutoCancel(dialogProps.autoCancel);
2676         auto dialogContext = dialogNode->GetRenderContext();
2677         CHECK_NULL_VOID(dialogContext);
2678         auto pipelineContext = dialogNode->GetContext();
2679         CHECK_NULL_VOID(pipelineContext);
2680         auto dialogTheme = pipelineContext->GetTheme<DialogTheme>();
2681         CHECK_NULL_VOID(dialogTheme);
2682         dialogContext->UpdateBackgroundColor(dialogProps.maskColor.value_or(dialogTheme->GetMaskColorEnd()));
2683         dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2684 
2685         callback(ERROR_CODE_NO_ERROR);
2686         return;
2687     }
2688     TAG_LOGE(AceLogTag::ACE_DIALOG, "CloseCustomDialog failed because cannot find dialog.");
2689     callback(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND);
2690 }
2691 
ShowCustomDialog(const RefPtr<FrameNode> & customNode)2692 void OverlayManager::ShowCustomDialog(const RefPtr<FrameNode>& customNode)
2693 {
2694     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show custom dialog enter");
2695     BeforeShowDialog(customNode);
2696     OpenDialogAnimation(customNode);
2697 }
2698 
RegisterDialogCallback(const RefPtr<FrameNode> & node,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent)2699 void RegisterDialogCallback(
2700     const RefPtr<FrameNode>& node, std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent)
2701 {
2702     CHECK_NULL_VOID(node);
2703     auto pipeline = PipelineContext::GetCurrentContext();
2704     CHECK_NULL_VOID(pipeline);
2705     auto theme = pipeline->GetTheme<DialogTheme>();
2706     CHECK_NULL_VOID(theme);
2707     auto dialogPattern = node->GetPattern<DialogPattern>();
2708     if (!dialogLifeCycleEvent.empty()) {
2709         auto didAppearEvent = dialogLifeCycleEvent["didAppearId"];
2710         auto didDisappearEvent = dialogLifeCycleEvent["didDisappearId"];
2711         auto willAppearEvent = dialogLifeCycleEvent["willAppearId"];
2712         auto willDisappearEvent = dialogLifeCycleEvent["willDisappearId"];
2713         dialogPattern->RegisterDialogDidAppearCallback(std::move(didAppearEvent));
2714         dialogPattern->RegisterDialogDidDisappearCallback(std::move(didDisappearEvent));
2715         dialogPattern->RegisterDialogWillAppearCallback(std::move(willAppearEvent));
2716         dialogPattern->RegisterDialogWillDisappearCallback(std::move(willDisappearEvent));
2717     }
2718 }
2719 
ShowDateDialog(const DialogProperties & dialogProps,const DatePickerSettingData & settingData,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2720 void OverlayManager::ShowDateDialog(const DialogProperties& dialogProps, const DatePickerSettingData& settingData,
2721     std::map<std::string, NG::DialogEvent> dialogEvent, std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2722     std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2723 {
2724     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show date dialog enter");
2725     auto dialogNode = DatePickerDialogView::Show(
2726         dialogProps, std::move(settingData), buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2727     RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2728     BeforeShowDialog(dialogNode);
2729     OpenDialogAnimation(dialogNode);
2730 }
2731 
ShowTimeDialog(const DialogProperties & dialogProps,const TimePickerSettingData & settingData,std::map<std::string,PickerTime> timePickerProperty,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2732 void OverlayManager::ShowTimeDialog(const DialogProperties& dialogProps, const TimePickerSettingData& settingData,
2733     std::map<std::string, PickerTime> timePickerProperty, std::map<std::string, NG::DialogEvent> dialogEvent,
2734     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2735     std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2736 {
2737     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show time dialog enter");
2738     auto dialogNode = TimePickerDialogView::Show(dialogProps, settingData, buttonInfos, std::move(timePickerProperty),
2739         std::move(dialogEvent), std::move(dialogCancelEvent));
2740     RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2741     BeforeShowDialog(dialogNode);
2742     OpenDialogAnimation(dialogNode);
2743 }
2744 
ShowTextDialog(const DialogProperties & dialogProps,const TextPickerSettingData & settingData,std::map<std::string,NG::DialogTextEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2745 void OverlayManager::ShowTextDialog(const DialogProperties& dialogProps, const TextPickerSettingData& settingData,
2746     std::map<std::string, NG::DialogTextEvent> dialogEvent,
2747     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2748     std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2749 {
2750     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show text dialog enter");
2751     auto dialogNode = TextPickerDialogView::Show(
2752         dialogProps, settingData, buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2753     RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2754     BeforeShowDialog(dialogNode);
2755     OpenDialogAnimation(dialogNode);
2756     if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
2757         Recorder::EventParamsBuilder builder;
2758         builder.SetType("TextPickerDialog").SetEventType(Recorder::EventType::DIALOG_SHOW);
2759         Recorder::EventRecorder::Get().OnEvent(std::move(builder));
2760     }
2761 }
2762 
ShowCalendarDialog(const DialogProperties & dialogProps,const CalendarSettingData & settingData,std::map<std::string,NG::DialogEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,std::map<std::string,NG::DialogCancelEvent> dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)2763 void OverlayManager::ShowCalendarDialog(const DialogProperties& dialogProps, const CalendarSettingData& settingData,
2764     std::map<std::string, NG::DialogEvent> dialogEvent, std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent,
2765     std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent, const std::vector<ButtonInfo>& buttonInfos)
2766 {
2767     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show calendar dialog enter");
2768     auto dialogNode = CalendarDialogView::Show(dialogProps, settingData,
2769         buttonInfos, std::move(dialogEvent), std::move(dialogCancelEvent));
2770     RegisterDialogCallback(dialogNode, std::move(dialogLifeCycleEvent));
2771     BeforeShowDialog(dialogNode);
2772     OpenDialogAnimation(dialogNode);
2773 }
2774 
PopModalDialog(int32_t maskId)2775 void OverlayManager::PopModalDialog(int32_t maskId)
2776 {
2777     TAG_LOGD(AceLogTag::ACE_OVERLAY, "pop modal dialog enter");
2778     int32_t dialogId = -1;
2779     for (auto it = maskNodeIdMap_.begin(); it != maskNodeIdMap_.end(); it++) {
2780         if (maskId == it->second) {
2781             dialogId = it->first;
2782             break;
2783         }
2784     }
2785     auto subWindow = SubwindowManager::GetInstance()->GetSubwindow(subWindowId_);
2786     CHECK_NULL_VOID(subWindow);
2787     auto subOverlayManager = subWindow->GetOverlayManager();
2788     CHECK_NULL_VOID(subOverlayManager);
2789     std::map<int32_t, RefPtr<FrameNode>> DialogMap(
2790         subOverlayManager->GetDialogMap().begin(), subOverlayManager->GetDialogMap().end());
2791     for (auto it = DialogMap.begin(); it != DialogMap.end(); it++) {
2792         auto dialogProp = DynamicCast<DialogLayoutProperty>(it->second->GetLayoutProperty());
2793         if (dialogId == it->first) {
2794             auto hub = it->second->GetEventHub<DialogEventHub>();
2795             if (hub) {
2796                 hub->FireCancelEvent();
2797             }
2798             subOverlayManager->CloseDialog(it->second);
2799         }
2800     }
2801 }
2802 
RemoveDialogFromMap(const RefPtr<FrameNode> & node)2803 void OverlayManager::RemoveDialogFromMap(const RefPtr<FrameNode>& node)
2804 {
2805     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove dialog from map enter");
2806     CHECK_NULL_VOID(node);
2807     if (dialogMap_.find(node->GetId()) == dialogMap_.end()) {
2808         return;
2809     }
2810     dialogMap_.erase(node->GetId());
2811 }
2812 
RemoveMaskFromMap(const RefPtr<FrameNode> & dialogNode)2813 void OverlayManager::RemoveMaskFromMap(const RefPtr<FrameNode>& dialogNode)
2814 {
2815     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove mask from map enter");
2816     CHECK_NULL_VOID(dialogNode);
2817     if (maskNodeIdMap_.find(dialogNode->GetId()) == maskNodeIdMap_.end()) {
2818         return;
2819     }
2820     maskNodeIdMap_.erase(dialogNode->GetId());
2821 }
2822 
DialogInMapHoldingFocus()2823 bool OverlayManager::DialogInMapHoldingFocus()
2824 {
2825     TAG_LOGD(AceLogTag::ACE_OVERLAY, "dialog in map holding focus enter");
2826     if (dialogMap_.empty()) {
2827         return false;
2828     }
2829     auto iter = dialogMap_.begin();
2830     while (iter != dialogMap_.end()) {
2831         auto dialogNode = (*iter).second;
2832         if (dialogNode && dialogNode->GetFocusHub() && dialogNode->GetFocusHub()->IsCurrentFocus()) {
2833             return true;
2834         }
2835         iter++;
2836     }
2837     return false;
2838 }
2839 
HasModalPage()2840 bool OverlayManager::HasModalPage()
2841 {
2842     if (modalList_.empty()) {
2843         return false;
2844     }
2845     for (auto modal : modalList_) {
2846         if (modal.Upgrade() && modal.Upgrade()->GetTag() == V2::MODAL_PAGE_TAG) {
2847             return true;
2848         }
2849     }
2850     return false;
2851 }
2852 
GetDialog(int32_t dialogId)2853 RefPtr<FrameNode> OverlayManager::GetDialog(int32_t dialogId)
2854 {
2855     TAG_LOGD(AceLogTag::ACE_OVERLAY, "get dialog enter");
2856     for (auto it = dialogMap_.begin(); it != dialogMap_.end(); it++) {
2857         if (dialogId == it->second->GetId()) {
2858             return it->second;
2859         }
2860     }
2861     return nullptr;
2862 }
2863 
CloseDialog(const RefPtr<FrameNode> & dialogNode)2864 void OverlayManager::CloseDialog(const RefPtr<FrameNode>& dialogNode)
2865 {
2866     TAG_LOGD(AceLogTag::ACE_OVERLAY, "close dialog enter");
2867     DeleteDialogHotAreas(dialogNode);
2868     auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2869     CHECK_NULL_VOID(dialogLayoutProp);
2870     if (dialogLayoutProp && dialogLayoutProp->GetShowInSubWindowValue(false) &&
2871         dialogLayoutProp->GetIsModal().value_or(true)) {
2872         RefPtr<OverlayManager> parentOverlayManager = nullptr;
2873 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
2874         auto container = Container::Current();
2875         auto currentId = Container::CurrentId();
2876         CHECK_NULL_VOID(container);
2877         if (container->IsSubContainer()) {
2878             currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
2879             container = AceEngine::Get().GetContainer(currentId);
2880             CHECK_NULL_VOID(container);
2881         }
2882         ContainerScope scope(currentId);
2883         auto pipelineContext = container->GetPipelineContext();
2884         CHECK_NULL_VOID(pipelineContext);
2885         auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2886         CHECK_NULL_VOID(context);
2887         parentOverlayManager = context->GetOverlayManager();
2888 #else
2889         auto parentPipelineContext = PipelineContext::GetMainPipelineContext();
2890         CHECK_NULL_VOID(parentPipelineContext);
2891         parentOverlayManager = parentPipelineContext->GetOverlayManager();
2892 #endif
2893         CHECK_NULL_VOID(parentOverlayManager);
2894         RefPtr<FrameNode> maskNode =
2895             parentOverlayManager->GetDialog(parentOverlayManager->GetMaskNodeIdWithDialogId(dialogNode->GetId()));
2896         if (maskNode) {
2897             parentOverlayManager->CloseDialog(maskNode);
2898         } else {
2899             TAG_LOGD(AceLogTag::ACE_OVERLAY, "no maskNode in currentDialog/%{public}d", dialogNode->GetId());
2900         }
2901     }
2902     CloseDialogInner(dialogNode);
2903 }
2904 
DeleteDialogHotAreas(const RefPtr<FrameNode> & dialogNode)2905 void OverlayManager::DeleteDialogHotAreas(const RefPtr<FrameNode>& dialogNode)
2906 {
2907     auto dialogLayoutProp = AceType::DynamicCast<DialogLayoutProperty>(dialogNode->GetLayoutProperty());
2908     CHECK_NULL_VOID(dialogLayoutProp);
2909     if (dialogLayoutProp->GetShowInSubWindowValue(false)) {
2910         SubwindowManager::GetInstance()->DeleteHotAreas(
2911             SubwindowManager::GetInstance()->GetDialogSubWindowId(), dialogNode->GetId());
2912         SubwindowManager::GetInstance()->HideDialogSubWindow(
2913             SubwindowManager::GetInstance()->GetDialogSubWindowId());
2914     }
2915 }
2916 
CloseDialogInner(const RefPtr<FrameNode> & dialogNode)2917 void OverlayManager::CloseDialogInner(const RefPtr<FrameNode>& dialogNode)
2918 {
2919     RemoveDialogFromMap(dialogNode);
2920     if (dialogNode->IsRemoving()) {
2921         // already in close animation
2922         TAG_LOGW(AceLogTag::ACE_DIALOG, "dialogNode/%{public}d is removing", dialogNode->GetId());
2923         return;
2924     }
2925     dialogNode->MarkRemoving();
2926 
2927     auto container = Container::Current();
2928     auto currentId = Container::CurrentId();
2929     CHECK_NULL_VOID(container);
2930     if (container->IsSubContainer()) {
2931         currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
2932         container = AceEngine::Get().GetContainer(currentId);
2933         CHECK_NULL_VOID(container);
2934     }
2935     ContainerScope scope(currentId);
2936     auto pipelineContext = container->GetPipelineContext();
2937     CHECK_NULL_VOID(pipelineContext);
2938     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2939     CHECK_NULL_VOID(context);
2940     auto overlayManager = context->GetOverlayManager();
2941     CHECK_NULL_VOID(overlayManager);
2942     overlayManager->ResetLowerNodeFocusable(dialogNode);
2943     auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
2944     CHECK_NULL_VOID(dialogPattern);
2945     auto transitionEffect = dialogPattern->GetDialogProperties().transitionEffect;
2946     if (transitionEffect != nullptr) {
2947         CloseDialogMatchTransition(dialogNode);
2948     } else {
2949         CloseDialogAnimation(dialogNode);
2950     }
2951     dialogCount_--;
2952     overlayManager->RemoveMaskFromMap(dialogNode);
2953     // set close button enable
2954     if (dialogCount_ == 0) {
2955         SetContainerButtonEnable(true);
2956     }
2957     CallOnHideDialogCallback();
2958 }
2959 
RemoveDialog(const RefPtr<FrameNode> & overlay,bool isBackPressed,bool isPageRouter)2960 bool OverlayManager::RemoveDialog(const RefPtr<FrameNode>& overlay, bool isBackPressed, bool isPageRouter)
2961 {
2962     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove dialog enter");
2963     if (overlay->IsRemoving()) {
2964         return false;
2965     }
2966     if (FireBackPressEvent()) {
2967         return true;
2968     }
2969     auto hub = overlay->GetEventHub<DialogEventHub>();
2970     if (!isPageRouter && hub) {
2971         hub->FireCancelEvent();
2972     }
2973     CloseDialog(overlay);
2974     if (isBackPressed) {
2975         SetBackPressEvent(nullptr);
2976     }
2977     return true;
2978 }
2979 
PopupInteractiveDismiss(const RefPtr<FrameNode> & overlay)2980 bool OverlayManager::PopupInteractiveDismiss(const RefPtr<FrameNode>& overlay)
2981 {
2982     auto bubblePattern = overlay->GetPattern<BubblePattern>();
2983     CHECK_NULL_RETURN(bubblePattern, false);
2984     return !bubblePattern->GetInteractiveDismiss();
2985 }
2986 
PopupCallBackOnWillDismiss(const RefPtr<FrameNode> & overlay)2987 bool OverlayManager::PopupCallBackOnWillDismiss(const RefPtr<FrameNode>& overlay)
2988 {
2989     auto bubblePattern = overlay->GetPattern<BubblePattern>();
2990     CHECK_NULL_RETURN(bubblePattern, false);
2991     if (bubblePattern->HasOnWillDismiss()) {
2992         int32_t dismissPopupId = GetPopupIdByNode(overlay);
2993         SetDismissPopupId(dismissPopupId);
2994         bubblePattern->CallOnWillDismiss(static_cast<int32_t>(DismissReason::BACK_PRESSED));
2995         return true;
2996     }
2997     return false;
2998 }
2999 
RemoveBubble(const RefPtr<FrameNode> & overlay)3000 bool OverlayManager::RemoveBubble(const RefPtr<FrameNode>& overlay)
3001 {
3002     TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove bubble enter");
3003     if (PopupInteractiveDismiss(overlay)) {
3004         return true;
3005     }
3006     if (PopupCallBackOnWillDismiss(overlay)) {
3007         return true;
3008     }
3009     for (const auto& popup : popupMap_) {
3010         auto targetId = popup.first;
3011         auto popupInfo = popup.second;
3012         if (overlay == popupInfo.popupNode) {
3013             popupInfo.markNeedUpdate = true;
3014             HidePopup(targetId, popupInfo);
3015             return true;
3016         }
3017     }
3018     return false;
3019 }
3020 
RemoveMenu(const RefPtr<FrameNode> & overlay)3021 bool OverlayManager::RemoveMenu(const RefPtr<FrameNode>& overlay)
3022 {
3023     TAG_LOGI(AceLogTag::ACE_OVERLAY, "remove menu enter");
3024     auto menuWrapperPattern = overlay->GetPattern<MenuWrapperPattern>();
3025     CHECK_NULL_RETURN(menuWrapperPattern, false);
3026     menuWrapperPattern->UpdateMenuAnimation(overlay);
3027     menuWrapperPattern->HideMenu();
3028     return true;
3029 }
3030 
RemoveDragPreview(const RefPtr<FrameNode> & overlay)3031 bool OverlayManager::RemoveDragPreview(const RefPtr<FrameNode>& overlay)
3032 {
3033     TAG_LOGI(AceLogTag::ACE_OVERLAY, "remove dragPreview enter");
3034     auto columnNode = pixmapColumnNodeWeak_.Upgrade();
3035     if (columnNode != overlay) {
3036         return false;
3037     }
3038     RemoveEventColumn();
3039     RemovePixelMap();
3040     RemoveGatherNode();
3041     return true;
3042 }
3043 
GetPopupIdByNode(const RefPtr<FrameNode> & overlay)3044 int32_t OverlayManager::GetPopupIdByNode(const RefPtr<FrameNode>& overlay)
3045 {
3046     TAG_LOGD(AceLogTag::ACE_OVERLAY, "GetPopupIdByNode IN");
3047     int32_t targetId = -1;
3048     for (const auto& popup : popupMap_) {
3049         targetId = popup.first;
3050         auto popupInfo = popup.second;
3051         if (overlay == popupInfo.popupNode) {
3052             return targetId;
3053         }
3054     }
3055     return targetId;
3056 }
3057 
RemoveOverlayCommon(const RefPtr<NG::UINode> & rootNode,RefPtr<NG::FrameNode> & overlay,RefPtr<Pattern> & pattern,bool isBackPressed,bool isPageRouter)3058 int32_t OverlayManager::RemoveOverlayCommon(const RefPtr<NG::UINode>& rootNode, RefPtr<NG::FrameNode>& overlay,
3059     RefPtr<Pattern>& pattern, bool isBackPressed, bool isPageRouter)
3060 {
3061     const size_t size = rootNode->GetChildren().size();
3062     if (size == 0) {
3063         return OVERLAY_EXISTS;
3064     }
3065     auto currentIndex = size - 1;
3066     while (InstanceOf<ToastPattern>(pattern)) {
3067         // still have nodes on root expect stage and toast node.
3068         if (currentIndex > 0) {
3069             currentIndex = currentIndex - 1;
3070             overlay = DynamicCast<FrameNode>(rootNode->GetChildAtIndex(currentIndex));
3071             CHECK_NULL_RETURN(overlay, OVERLAY_EXISTS);
3072             pattern = overlay->GetPattern();
3073         } else {
3074             return OVERLAY_EXISTS;
3075         }
3076     }
3077     CHECK_EQUAL_RETURN(overlay->GetTag(), V2::STAGE_ETS_TAG, OVERLAY_EXISTS);
3078     CHECK_EQUAL_RETURN(overlay->GetTag(), V2::OVERLAY_ETS_TAG, OVERLAY_EXISTS);
3079     CHECK_EQUAL_RETURN(overlay->GetTag(), V2::ATOMIC_SERVICE_ETS_TAG, OVERLAY_EXISTS);
3080     // close dialog with animation
3081     if (InstanceOf<DialogPattern>(pattern)) {
3082         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && isPageRouter) {
3083             return OVERLAY_EXISTS;
3084         }
3085         auto dialogPattern = DynamicCast<DialogPattern>(pattern);
3086         CHECK_NULL_RETURN(dialogPattern, OVERLAY_EXISTS);
3087         if (dialogPattern->CallDismissInNDK(static_cast<int32_t>(DialogDismissReason::DIALOG_PRESS_BACK))) {
3088             return OVERLAY_REMOVE;
3089         } else if (dialogPattern->ShouldDismiss()) {
3090             SetDismissDialogId(overlay->GetId());
3091             dialogPattern->CallOnWillDismiss(static_cast<int32_t>(DialogDismissReason::DIALOG_PRESS_BACK));
3092             TAG_LOGI(AceLogTag::ACE_OVERLAY, "Dialog Should Dismiss");
3093             return OVERLAY_REMOVE;
3094         }
3095         return RemoveDialog(overlay, isBackPressed, isPageRouter) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3096     }
3097     if (InstanceOf<BubblePattern>(pattern)) {
3098         return RemoveBubble(overlay) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3099     }
3100     if (InstanceOf<MenuWrapperPattern>(pattern)) {
3101         RemoveDragPreview(overlay);
3102         return RemoveMenu(overlay) ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3103     }
3104     if (InstanceOf<LinearLayoutPattern>(pattern)) {
3105         return RemoveDragPreview(overlay) ? OVERLAY_REMOVE : OVERLAY_NOTHING;
3106     }
3107     return OVERLAY_NOTHING;
3108 }
3109 
RemoveOverlay(bool isBackPressed,bool isPageRouter)3110 bool OverlayManager::RemoveOverlay(bool isBackPressed, bool isPageRouter)
3111 {
3112     auto rootNode = rootNodeWeak_.Upgrade();
3113     CHECK_NULL_RETURN(rootNode, true);
3114     RemoveIndexerPopup();
3115     SetDragNodeNeedClean();
3116     auto pipeline = rootNode->GetContextRefPtr();
3117     CHECK_NULL_RETURN(pipeline, false);
3118     // There is overlay under the root node or it is in atomicservice
3119     if (rootNode->GetChildren().size() > ROOT_MIN_NODE || pipeline->GetInstallationFree()) {
3120         // stage node is at index 0, remove overlay at last
3121         auto overlay = GetOverlayFrameNode();
3122         CHECK_NULL_RETURN(overlay, false);
3123         auto pattern = overlay->GetPattern();
3124         auto ret = RemoveOverlayCommon(rootNode, overlay, pattern, isBackPressed, isPageRouter);
3125         if (ret == OVERLAY_REMOVE) {
3126             return true;
3127         } else if (ret == OVERLAY_EXISTS) {
3128             return false;
3129         }
3130         ret = ExceptComponent(rootNode, overlay, isBackPressed, isPageRouter);
3131         if (ret == OVERLAY_REMOVE) {
3132             return true;
3133         } else if (ret == OVERLAY_EXISTS) {
3134             return false;
3135         }
3136         // remove navDestination in navigation first
3137         do {
3138             CHECK_NULL_BREAK(rootNode->GetTag() != V2::NAVDESTINATION_VIEW_ETS_TAG);
3139             bool isEntry = false;
3140             auto navigationGroupNode =
3141                 AceType::DynamicCast<NavigationGroupNode>(pipeline->FindNavigationNodeToHandleBack(overlay, isEntry));
3142             CHECK_NULL_BREAK(navigationGroupNode);
3143             return true;
3144         } while (0);
3145         if (!modalStack_.empty()) {
3146             TAG_LOGI(AceLogTag::ACE_SHEET, "Modal consumed backpressed event");
3147             if (isPageRouter) {
3148                 return RemoveAllModalInOverlay();
3149             } else {
3150                 return RemoveModalInOverlay();
3151             }
3152         }
3153         if (!InstanceOf<KeyboardPattern>(pattern)) {
3154             if (overlay->GetTag() != V2::SHEET_WRAPPER_TAG) {
3155                 rootNode->RemoveChild(overlay);
3156             }
3157             rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3158             return true;
3159         }
3160     }
3161     return false;
3162 }
3163 
GetOverlayFrameNode()3164 RefPtr<FrameNode> OverlayManager::GetOverlayFrameNode()
3165 {
3166     auto rootNode = rootNodeWeak_.Upgrade();
3167     CHECK_NULL_RETURN(rootNode, nullptr);
3168     auto pipeline = rootNode->GetContextRefPtr();
3169     CHECK_NULL_RETURN(pipeline, nullptr);
3170     auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3171     // There is no overlay under the root node or it is not in atomicservice
3172     if (!pipeline->GetInstallationFree() || rootNode->GetChildren().size() > ROOT_MIN_NODE) {
3173         return overlay;
3174     }
3175     for (auto child : rootNode->GetChildren()) {
3176         if (child->GetTag() == V2::ATOMIC_SERVICE_ETS_TAG) {
3177             auto atomicNode = child;
3178             CHECK_NULL_RETURN(atomicNode, nullptr);
3179             if (atomicNode->GetChildren().size() <= ATOMIC_SERVICE_MIN_SIZE) {
3180                 return nullptr;
3181             }
3182             overlay = DynamicCast<FrameNode>(
3183                 atomicNode->GetChildAtIndex(atomicNode->GetChildren().size() - ATOMIC_SERVICE_MIN_SIZE));
3184             break;
3185         }
3186     }
3187     return overlay;
3188 }
3189 
ExceptComponent(const RefPtr<NG::UINode> & rootNode,RefPtr<NG::FrameNode> & overlay,bool isBackPressed,bool isPageRouter)3190 int32_t OverlayManager::ExceptComponent(const RefPtr<NG::UINode>& rootNode, RefPtr<NG::FrameNode>& overlay,
3191     bool isBackPressed, bool isPageRouter)
3192 {
3193     auto pattern = overlay->GetPattern();
3194     if (InstanceOf<VideoFullScreenPattern>(pattern)) {
3195         auto videoPattern = DynamicCast<VideoFullScreenPattern>(pattern);
3196         CHECK_NULL_RETURN(videoPattern, OVERLAY_EXISTS);
3197         return videoPattern->ExitFullScreen() ? OVERLAY_REMOVE : OVERLAY_EXISTS;
3198     }
3199     // OVERLAY_REMOVE if popup was removed, OVERLAY_NOTHING if not handle it
3200     if (overlay->GetTag() == V2::SHEET_WRAPPER_TAG) {
3201         return WebBackward(overlay);
3202     }
3203     return OVERLAY_NOTHING;
3204 }
3205 
WebBackward(RefPtr<NG::FrameNode> & overlay)3206 int32_t OverlayManager::WebBackward(RefPtr<NG::FrameNode>& overlay)
3207 {
3208 #ifdef WEB_SUPPORTED
3209     RefPtr<NG::FrameNode> webNode;
3210     FindWebNode(overlay, webNode);
3211     if (webNode && InstanceOf<WebPattern>(webNode->GetPattern())) {
3212         auto webPattern = DynamicCast<WebPattern>(webNode->GetPattern());
3213         CHECK_NULL_RETURN(webPattern, OVERLAY_EXISTS);
3214         if (webPattern->Backward()) {
3215             return OVERLAY_REMOVE;
3216         }
3217     }
3218 #endif
3219     return OVERLAY_NOTHING;
3220 }
3221 
FindWebNode(const RefPtr<NG::UINode> & node,RefPtr<NG::FrameNode> & webNode)3222 void OverlayManager::FindWebNode(const RefPtr<NG::UINode>& node, RefPtr<NG::FrameNode>& webNode)
3223 {
3224     CHECK_NULL_VOID(node);
3225 
3226     if (webNode) {
3227         return;
3228     }
3229 
3230     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
3231     if (frameNode && !frameNode->IsInternal() && frameNode->GetTag() == V2::WEB_ETS_TAG) {
3232         webNode = frameNode;
3233         return;
3234     }
3235 
3236     if (!node->GetChildren().empty()) {
3237         for (const auto& child : node->GetChildren()) {
3238             FindWebNode(child, webNode);
3239         }
3240     }
3241 }
3242 
RemoveModalInOverlay()3243 bool OverlayManager::RemoveModalInOverlay()
3244 {
3245     auto topModalNode = modalStack_.top().Upgrade();
3246     CHECK_NULL_RETURN(topModalNode, false);
3247     auto rootNode = FindWindowScene(topModalNode);
3248     CHECK_NULL_RETURN(rootNode, true);
3249     auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3250     if (overlay && overlay->GetTag() == V2::SHEET_WRAPPER_TAG && overlay->GetFirstChild() != topModalNode) {
3251         TAG_LOGD(AceLogTag::ACE_SHEET, "Refuse to back because sheet is in animation");
3252         return true;
3253     }
3254     if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG) {
3255         auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3256         CHECK_NULL_RETURN(sheetPattern, false);
3257         sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::BACK_PRESSED);
3258         return true;
3259     } else if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3260         auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3261         CHECK_NULL_RETURN(modalPattern, false);
3262         if (modalPattern->HasOnWillDismiss()) {
3263             modalPattern->ModalInteractiveDismiss();
3264             return true;
3265         }
3266     }
3267     ModalPageLostFocus(topModalNode);
3268     auto pattern = topModalNode->GetPattern<PopupBasePattern>();
3269     if (isProhibitBack_ && pattern->GetTargetId() < 0) {
3270         return true;
3271     }
3272     auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3273     CHECK_NULL_RETURN(builder, false);
3274     if (!ModalExitProcess(topModalNode)) {
3275         return false;
3276     }
3277     PopTopModalNode();
3278     auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3279     if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3280         sheetMap_.erase(sheetPattern->GetSheetKey());
3281     }
3282     if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3283         auto modalPattern = AceType::DynamicCast<ModalPresentationPattern>(pattern);
3284         CHECK_NULL_RETURN(modalPattern, false);
3285         auto modalTransition = modalPattern->GetType();
3286         if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3287             // Fire shown event of navdestination under the disappeared modal
3288             FireNavigationStateChange(true);
3289         }
3290     }
3291     FireModalPageHide();
3292     SaveLastModalNode();
3293     return true;
3294 }
3295 
RemoveAllModalInOverlay(bool isRouterTransition)3296 bool OverlayManager::RemoveAllModalInOverlay(bool isRouterTransition)
3297 {
3298     if (modalStack_.empty()) {
3299         return true;
3300     }
3301 
3302     auto topModalNode = modalStack_.top().Upgrade();
3303     bool isModalUiextensionNode = IsModalUiextensionNode(topModalNode);
3304     if (!isRouterTransition) {
3305         bool isProhibitedRemoveByNavigation = IsProhibitedRemoveByNavigation(topModalNode);
3306         TAG_LOGI(AceLogTag::ACE_OVERLAY,
3307             "isNavigation: isModalUiextensionNode: %{public}d, isProhibitedRemoveByNavigation: %{public}d",
3308             isModalUiextensionNode, isProhibitedRemoveByNavigation);
3309         if (isModalUiextensionNode && !isProhibitedRemoveByNavigation) {
3310             return RemoveAllModalInOverlayByStack();
3311         }
3312         return true;
3313     }
3314 
3315     bool isProhibitedRemoveByRouter = IsProhibitedRemoveByRouter(topModalNode);
3316     TAG_LOGI(AceLogTag::ACE_OVERLAY,
3317         "isRouter: isModalUiextensionNode: %{public}d, isProhibitedRemoveByRouter: %{public}d,",
3318         isModalUiextensionNode, isProhibitedRemoveByRouter);
3319     if (isModalUiextensionNode && isProhibitedRemoveByRouter) {
3320         return RemoveAllModalInOverlayByList();
3321     }
3322 
3323     return RemoveAllModalInOverlayByStack();
3324 }
3325 
RemoveAllModalInOverlayByStack()3326 bool OverlayManager::RemoveAllModalInOverlayByStack()
3327 {
3328     while (!modalStack_.empty()) {
3329         auto topModalNode = modalStack_.top().Upgrade();
3330         if (!topModalNode) {
3331             modalStack_.pop();
3332             continue;
3333         }
3334         auto rootNode = FindWindowScene(topModalNode);
3335         CHECK_NULL_RETURN(rootNode, true);
3336         auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3337         CHECK_NULL_RETURN(builder, false);
3338         ModalPageLostFocus(topModalNode);
3339         if (!ModalExitProcess(topModalNode)) {
3340             continue;
3341         }
3342         if (!modalStack_.empty()) {
3343             modalStack_.pop();
3344         }
3345         if (!modalList_.empty()) {
3346             modalList_.pop_back();
3347         }
3348 
3349         if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3350             auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3351             CHECK_NULL_RETURN(modalPattern, false);
3352             auto modalTransition = modalPattern->GetType();
3353             if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3354                 // Fire shown event of navdestination under the disappeared modal
3355                 FireNavigationStateChange(true);
3356             }
3357         }
3358         auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3359         if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3360             sheetMap_.erase(sheetPattern->GetSheetKey());
3361         }
3362         FireModalPageHide();
3363         SaveLastModalNode();
3364     }
3365     return true;
3366 }
3367 
RemoveAllModalInOverlayByList()3368 bool OverlayManager::RemoveAllModalInOverlayByList()
3369 {
3370     TAG_LOGI(AceLogTag::ACE_OVERLAY,
3371         "RemoveAllModalInOverlayByList modalStack size: %{public}zu, "
3372         "modalList size: %{public}zu", modalStack_.size(), modalList_.size());
3373     if (modalStack_.size() != modalList_.size()) {
3374         TAG_LOGI(AceLogTag::ACE_OVERLAY,
3375             "Not RemoveAllModalInOverlayByList due to modalStack not same with modalList.");
3376         return true;
3377     }
3378 
3379     bool ret = OnRemoveAllModalInOverlayByList();
3380     // To keep the modalStack consistent with the modalList
3381     AfterRemoveAllModalInOverlayByList();
3382     return ret;
3383 }
3384 
OnRemoveAllModalInOverlayByList()3385 bool OverlayManager::OnRemoveAllModalInOverlayByList()
3386 {
3387     auto modalIter = modalList_.begin();
3388     while (modalIter != modalList_.end()) {
3389         auto topModalNode = (*modalIter).Upgrade();
3390         if (!topModalNode) {
3391             modalIter = modalList_.erase(modalIter);
3392             continue;
3393         }
3394         if (IsModalUiextensionNode(topModalNode)) {
3395             break;
3396         }
3397         auto rootNode = FindWindowScene(topModalNode);
3398         CHECK_NULL_RETURN(rootNode, true);
3399         auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3400         CHECK_NULL_RETURN(builder, false);
3401         ModalPageLostFocus(topModalNode);
3402         if (!ModalExitProcess(topModalNode)) {
3403             modalIter = modalList_.erase(modalIter);
3404             continue;
3405         }
3406         if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3407             auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3408             CHECK_NULL_RETURN(modalPattern, false);
3409             auto modalTransition = modalPattern->GetType();
3410             if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3411                 // Fire shown event of navdestination under the disappeared modal
3412                 FireNavigationStateChange(true);
3413             }
3414         }
3415         auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
3416         if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
3417             sheetMap_.erase(sheetPattern->GetSheetKey());
3418         }
3419         modalIter = modalList_.erase(modalIter);
3420     }
3421     return true;
3422 }
3423 
AfterRemoveAllModalInOverlayByList()3424 void OverlayManager::AfterRemoveAllModalInOverlayByList()
3425 {
3426     TAG_LOGI(AceLogTag::ACE_OVERLAY,
3427         "AfterRemoveAllModalInOverlayByList modalList size: %{public}zu", modalList_.size());
3428     std::stack<WeakPtr<FrameNode>> modalStack;
3429     modalStack_.swap(modalStack);
3430     for (auto modal = modalList_.begin(); modal != modalList_.end(); ++modal) {
3431         modalStack_.push(*modal);
3432     }
3433 }
3434 
IsModalUiextensionNode(const RefPtr<FrameNode> & topModalNode)3435 bool OverlayManager::IsModalUiextensionNode(const RefPtr<FrameNode>& topModalNode)
3436 {
3437     if (topModalNode == nullptr) {
3438         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3439         return false;
3440     }
3441 
3442     if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3443         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3444         return false;
3445     }
3446 
3447     auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3448     CHECK_NULL_RETURN(modalPattern, false);
3449     return modalPattern->IsUIExtension();
3450 }
3451 
IsProhibitedRemoveByRouter(const RefPtr<FrameNode> & topModalNode)3452 bool OverlayManager::IsProhibitedRemoveByRouter(const RefPtr<FrameNode>& topModalNode)
3453 {
3454     if (topModalNode == nullptr) {
3455         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3456         return false;
3457     }
3458 
3459     if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3460         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3461         return false;
3462     }
3463 
3464     auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3465     CHECK_NULL_RETURN(modalPattern, false);
3466     return modalPattern->IsProhibitedRemoveByRouter();
3467 }
3468 
IsProhibitedRemoveByNavigation(const RefPtr<FrameNode> & topModalNode)3469 bool OverlayManager::IsProhibitedRemoveByNavigation(const RefPtr<FrameNode>& topModalNode)
3470 {
3471     if (topModalNode == nullptr) {
3472         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
3473         return true;
3474     }
3475 
3476     if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
3477         TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
3478         return true;
3479     }
3480 
3481     auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3482     CHECK_NULL_RETURN(modalPattern, true);
3483     return modalPattern->IsProhibitedRemoveByNavigation();
3484 }
3485 
ModalExitProcess(const RefPtr<FrameNode> & topModalNode)3486 bool OverlayManager::ModalExitProcess(const RefPtr<FrameNode>& topModalNode)
3487 {
3488     auto rootNode = FindWindowScene(topModalNode);
3489     CHECK_NULL_RETURN(rootNode, true);
3490     if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3491         return ModalPageExitProcess(topModalNode);
3492     }
3493     if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG) {
3494         return SheetPageExitProcess(topModalNode);
3495     }
3496     return true;
3497 }
3498 
PlayTransitionEffectOut(const RefPtr<FrameNode> & topModalNode)3499 void OverlayManager::PlayTransitionEffectOut(const RefPtr<FrameNode>& topModalNode)
3500 {
3501     const auto& layoutProperty = topModalNode->GetLayoutProperty();
3502     layoutProperty->UpdateVisibility(VisibleType::INVISIBLE, true);
3503 
3504     const auto& renderContext = topModalNode->GetRenderContext();
3505     if (!renderContext->HasDisappearTransition()) {
3506         const auto& topModalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3507         if (!topModalPattern->IsExecuteOnDisappear()) {
3508             topModalPattern->OnDisappear();
3509             // Fire hidden event of navdestination on the disappeared modal
3510             FireNavigationStateChange(false, topModalNode);
3511         }
3512         auto rootNode = FindWindowScene(topModalNode);
3513         FireAutoSave(topModalNode);
3514         RemoveChildWithService(rootNode, topModalNode);
3515         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3516         // Fire shown event of navdestination under the disappeared modal
3517         FireNavigationStateChange(true);
3518     } else {
3519         topModalNode->GetRenderContext()->SetTransitionOutCallback(
3520             [modalWK = WeakClaim(RawPtr(topModalNode)), overlayWeak = WeakClaim(this)] {
3521                 auto modal = modalWK.Upgrade();
3522                 auto overlayManager = overlayWeak.Upgrade();
3523                 CHECK_NULL_VOID(modal && overlayManager);
3524                 auto root = overlayManager->FindWindowScene(modal);
3525                 CHECK_NULL_VOID(root);
3526                 const auto& modalPattern = modal->GetPattern<ModalPresentationPattern>();
3527                 if (!modalPattern->IsExecuteOnDisappear()) {
3528                     modalPattern->OnDisappear();
3529                     // Fire hidden event of navdestination on the disappeared modal
3530                     overlayManager->FireNavigationStateChange(false, modal);
3531                 }
3532                 overlayManager->FireAutoSave(modal);
3533                 overlayManager->RemoveChildWithService(root, modal);
3534                 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3535                 // Fire shown event of navdestination under the disappeared modal
3536                 overlayManager->FireNavigationStateChange(true);
3537             });
3538     }
3539 }
3540 
ModalPageExitProcess(const RefPtr<FrameNode> & topModalNode)3541 bool OverlayManager::ModalPageExitProcess(const RefPtr<FrameNode>& topModalNode)
3542 {
3543     auto rootNode = FindWindowScene(topModalNode);
3544     CHECK_NULL_RETURN(rootNode, true);
3545     auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3546     CHECK_NULL_RETURN(builder, false);
3547     topModalNode->GetPattern<ModalPresentationPattern>()->OnWillDisappear();
3548     auto modalTransition = topModalNode->GetPattern<ModalPresentationPattern>()->GetType();
3549     if (builder->GetRenderContext()->HasDisappearTransition()) {
3550         if (!topModalNode->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
3551             topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3552             // Fire hidden event of navdestination on the disappeared modal
3553             FireNavigationStateChange(false, topModalNode);
3554         }
3555         topModalNode->Clean(false, true);
3556         topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3557     }
3558     topModalNode->OnAccessibilityEvent(
3559         AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3560     if (topModalNode->GetPattern<ModalPresentationPattern>()->HasTransitionEffect()) {
3561         PlayTransitionEffectOut(topModalNode);
3562     } else if (modalTransition == ModalTransition::DEFAULT) {
3563         PlayDefaultModalTransition(topModalNode, false);
3564     } else if (modalTransition == ModalTransition::ALPHA) {
3565         PlayAlphaModalTransition(topModalNode, false);
3566     } else if (!builder->GetRenderContext()->HasDisappearTransition()) {
3567         topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3568         // Fire hidden event of navdestination on the disappeared modal
3569         FireNavigationStateChange(false, topModalNode);
3570         FireAutoSave(topModalNode);
3571         RemoveChildWithService(rootNode, topModalNode);
3572         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3573     }
3574     topModalNode->GetPattern<ModalPresentationPattern>()->FireCallback("false");
3575     return true;
3576 }
3577 
SheetPageExitProcess(const RefPtr<FrameNode> & topModalNode)3578 bool OverlayManager::SheetPageExitProcess(const RefPtr<FrameNode>& topModalNode)
3579 {
3580     auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetLastChild());
3581     CHECK_NULL_RETURN(builder, false);
3582     topModalNode->GetPattern<SheetPresentationPattern>()->OnWillDisappear();
3583     if (builder->GetRenderContext()->HasDisappearTransition()) {
3584         if (!topModalNode->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
3585             topModalNode->GetPattern<SheetPresentationPattern>()->OnDisappear();
3586         }
3587         topModalNode->Clean(false, true);
3588         topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3589     }
3590     auto maskNode = GetSheetMask(topModalNode);
3591     if (maskNode) {
3592         PlaySheetMaskTransition(maskNode, false);
3593     }
3594     auto sheetType = topModalNode->GetPattern<SheetPresentationPattern>()->GetSheetType();
3595     if (sheetType == SheetType::SHEET_POPUP) {
3596         PlayBubbleStyleSheetTransition(topModalNode, false);
3597     } else {
3598         PlaySheetTransition(topModalNode, false);
3599     }
3600     topModalNode->GetPattern<SheetPresentationPattern>()->FireCallback("false");
3601     return true;
3602 }
3603 
RemovePopupInSubwindow(const RefPtr<Pattern> & pattern,const RefPtr<FrameNode> & overlay,const RefPtr<UINode> & rootNode)3604 bool OverlayManager::RemovePopupInSubwindow(const RefPtr<Pattern>& pattern, const RefPtr<FrameNode>& overlay,
3605     const RefPtr<UINode>& rootNode)
3606 {
3607     if (PopupInteractiveDismiss(overlay)) {
3608         return true;
3609     }
3610     if (PopupCallBackOnWillDismiss(overlay)) {
3611         return true;
3612     }
3613     auto popupPattern = DynamicCast<BubblePattern>(pattern);
3614     overlay->GetEventHub<BubbleEventHub>()->FireChangeEvent(false);
3615     auto container = Container::Current();
3616     auto currentId = Container::CurrentId();
3617     CHECK_NULL_RETURN(container, false);
3618     if (container->IsSubContainer()) {
3619         currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
3620     }
3621     ContainerScope scope(currentId);
3622     for (const auto& popup : popupMap_) {
3623         auto targetId = popup.first;
3624         auto popupInfo = popup.second;
3625         if (overlay == popupInfo.popupNode) {
3626             popupMap_.erase(targetId);
3627             rootNode->RemoveChild(overlay);
3628             rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3629             auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentId);
3630             CHECK_NULL_RETURN(subwindow, false);
3631             subwindow->DeleteHotAreas(overlay->GetId());
3632             if (rootNode->GetChildren().empty()) {
3633                 subwindow->HideSubWindowNG();
3634             }
3635             return true;
3636         }
3637     }
3638     return false;
3639 }
3640 
RemoveOverlayInSubwindow()3641 bool OverlayManager::RemoveOverlayInSubwindow()
3642 {
3643     auto rootNode = rootNodeWeak_.Upgrade();
3644     CHECK_NULL_RETURN(rootNode, false);
3645     if (rootNode->GetChildren().empty()) {
3646         return false;
3647     }
3648 
3649     // remove the overlay node just mounted in subwindow
3650     auto overlay = DynamicCast<FrameNode>(rootNode->GetLastChild());
3651     CHECK_NULL_RETURN(overlay, false);
3652     auto pattern = overlay->GetPattern();
3653     auto ret = RemoveOverlayCommon(rootNode, overlay, pattern, false, false);
3654     if (ret == OVERLAY_EXISTS) {
3655         return false;
3656     } else if (ret == OVERLAY_REMOVE) {
3657         return true;
3658     }
3659     rootNode->RemoveChild(overlay);
3660     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
3661     if (rootNode->GetChildren().empty()) {
3662         SubwindowManager::GetInstance()->HideSubWindowNG();
3663     }
3664     if (InstanceOf<KeyboardPattern>(pattern)) {
3665         FocusHub::LostFocusToViewRoot();
3666     }
3667     return true;
3668 }
3669 
FocusOverlayNode(const RefPtr<FrameNode> & overlayNode,bool isInSubWindow)3670 void OverlayManager::FocusOverlayNode(const RefPtr<FrameNode>& overlayNode, bool isInSubWindow)
3671 {
3672     CHECK_NULL_VOID(overlayNode);
3673     auto overlayHub = overlayNode->GetFocusHub();
3674     CHECK_NULL_VOID(overlayHub);
3675     auto focusView = overlayHub->GetFirstChildFocusView();
3676     CHECK_NULL_VOID(focusView);
3677     focusView->FocusViewShow();
3678 }
3679 
BlurOverlayNode(const RefPtr<FrameNode> & currentOverlay,bool isInSubWindow)3680 void OverlayManager::BlurOverlayNode(const RefPtr<FrameNode>& currentOverlay, bool isInSubWindow) {}
3681 
BlurLowerNode(const RefPtr<FrameNode> & currentOverlay)3682 void OverlayManager::BlurLowerNode(const RefPtr<FrameNode>& currentOverlay) {}
3683 
ResetLowerNodeFocusable(const RefPtr<FrameNode> & currentOverlay)3684 void OverlayManager::ResetLowerNodeFocusable(const RefPtr<FrameNode>& currentOverlay) {}
3685 
SaveLastModalNode()3686 void OverlayManager::SaveLastModalNode()
3687 {
3688     auto pipeline = PipelineContext::GetCurrentContext();
3689     CHECK_NULL_VOID(pipeline);
3690     auto stageManager = pipeline->GetStageManager();
3691     CHECK_NULL_VOID(stageManager);
3692     auto pageNode = stageManager->GetLastPage();
3693     CHECK_NULL_VOID(pageNode);
3694     if (modalStack_.empty()) {
3695         lastModalNode_ = WeakClaim(RawPtr(pageNode));
3696     } else {
3697         auto topModalNode = modalStack_.top().Upgrade();
3698         modalStack_.pop();
3699         if (modalStack_.empty()) {
3700             lastModalNode_ = WeakClaim(RawPtr(pageNode));
3701         } else {
3702             lastModalNode_ = modalStack_.top();
3703         }
3704         modalStack_.push(topModalNode);
3705     }
3706 }
3707 
FireNavigationStateChange(bool show,const RefPtr<UINode> & node)3708 void OverlayManager::FireNavigationStateChange(bool show, const RefPtr<UINode>& node)
3709 {
3710     if (!show && node) {
3711         // Only check node When it is appointed
3712         NavigationPattern::FireNavigationStateChange(node, show);
3713         return;
3714     }
3715 
3716     // Fire show event with non-empty stack. Only Check top modal node.
3717     RefPtr<FrameNode> topModalNode;
3718     if (!modalStack_.empty()) {
3719         topModalNode = GetModalNodeInStack(modalStack_);
3720     }
3721     if (show && topModalNode) {
3722         // Modal always displays on top of stage. If it existed, only need to check the top of modal stack.
3723         NavigationPattern::FireNavigationStateChange(topModalNode, show);
3724         return;
3725     }
3726 
3727     auto lastPage = GetLastPage();
3728     CHECK_NULL_VOID(lastPage);
3729     auto pagePattern = lastPage->GetPattern<PagePattern>();
3730     bool notTriggerNavigationStateChange = show && pagePattern && !pagePattern->IsOnShow();
3731     if (notTriggerNavigationStateChange) {
3732         // navdestination will not fire onShow When parent page is hide.
3733         return;
3734     }
3735     NavigationPattern::FireNavigationStateChange(lastPage, show);
3736 }
3737 
GetModalNodeInStack(std::stack<WeakPtr<FrameNode>> & stack)3738 RefPtr<FrameNode> OverlayManager::GetModalNodeInStack(std::stack<WeakPtr<FrameNode>>& stack)
3739 {
3740     if (stack.empty()) {
3741         return nullptr;
3742     }
3743     auto topModalNode = stack.top().Upgrade();
3744     CHECK_NULL_RETURN(topModalNode, nullptr);
3745     if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
3746         return topModalNode;
3747     } else {
3748         stack.pop();
3749         auto modalNode = GetModalNodeInStack(stack);
3750         stack.push(topModalNode);
3751         return modalNode;
3752     }
3753 }
3754 
PlayTransitionEffectIn(const RefPtr<FrameNode> & modalNode)3755 void OverlayManager::PlayTransitionEffectIn(const RefPtr<FrameNode>& modalNode)
3756 {
3757     const auto& layoutProperty = modalNode->GetLayoutProperty();
3758     layoutProperty->UpdateVisibility(VisibleType::VISIBLE, true);
3759 
3760     modalNode->GetRenderContext()->SetTransitionInCallback([modalWK = WeakClaim(RawPtr(modalNode))] {
3761         auto modal = modalWK.Upgrade();
3762         CHECK_NULL_VOID(modal);
3763         modal->GetPattern<ModalPresentationPattern>()->OnAppear();
3764     });
3765 
3766     // Fire hidden event of navdestination under the appeared modal
3767     FireNavigationStateChange(false);
3768 }
3769 
BindContentCover(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,const NG::ContentCoverParam & contentCoverParam,const RefPtr<FrameNode> & targetNode,int32_t sessionId)3770 void OverlayManager::BindContentCover(bool isShow, std::function<void(const std::string&)>&& callback,
3771     std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3772     std::function<void()>&& onDisappear, std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
3773     const NG::ContentCoverParam& contentCoverParam, const RefPtr<FrameNode>& targetNode, int32_t sessionId)
3774 {
3775     return OnBindContentCover(isShow, std::move(callback), std::move(buildNodeFunc), modalStyle,
3776         std::move(onAppear), std::move(onDisappear), std::move(onWillAppear), std::move(onWillDisappear),
3777         contentCoverParam, targetNode, sessionId);
3778 }
3779 
OnBindContentCover(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,const NG::ContentCoverParam & contentCoverParam,const RefPtr<FrameNode> & targetNode,int32_t sessionId)3780 void OverlayManager::OnBindContentCover(bool isShow, std::function<void(const std::string&)>&& callback,
3781     std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3782     std::function<void()>&& onDisappear, std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
3783     const NG::ContentCoverParam& contentCoverParam, const RefPtr<FrameNode>& targetNode, int32_t sessionId)
3784 {
3785     int32_t targetId = targetNode ? targetNode->GetId() : sessionId;
3786     auto rootNode = FindWindowScene(targetNode);
3787     CHECK_NULL_VOID(rootNode);
3788     if (isShow) {
3789         auto modalTransition = modalStyle.modalTransition;
3790         if (!modalTransition.has_value()) {
3791             modalTransition = ModalTransition::DEFAULT;
3792         }
3793         auto targetModalNode = GetModal(targetId);
3794         if (targetModalNode) {
3795             const auto& targetModalPattern = targetModalNode->GetPattern<ModalPresentationPattern>();
3796             CHECK_NULL_VOID(targetModalPattern);
3797             auto modalRenderContext = targetModalNode->GetRenderContext();
3798             CHECK_NULL_VOID(modalRenderContext);
3799             if (modalStyle.backgroundColor.has_value()) {
3800                 modalRenderContext->UpdateBackgroundColor(modalStyle.backgroundColor.value());
3801             }
3802             targetModalPattern->UpdateOnDisappear(std::move(onDisappear));
3803             targetModalPattern->UpdateOnWillDisappear(std::move(onWillDisappear));
3804             targetModalPattern->UpdateOnAppear(std::move(onAppear));
3805             targetModalPattern->UpdateOnWillDismiss(std::move(contentCoverParam.onWillDismiss));
3806             targetModalPattern->SetType(modalTransition.value());
3807             targetModalPattern->SetHasTransitionEffect(contentCoverParam.transitionEffect != nullptr);
3808             modalRenderContext->UpdateChainedTransition(contentCoverParam.transitionEffect);
3809             return;
3810         }
3811         if (onWillAppear) {
3812             onWillAppear();
3813         }
3814         HandleModalShow(std::move(callback), std::move(buildNodeFunc), modalStyle, std::move(onAppear),
3815             std::move(onDisappear), std::move(onWillDisappear), rootNode, contentCoverParam, targetId, modalTransition);
3816         return;
3817     }
3818 
3819     // isShow = false, Pop ModalPage
3820     if (!modalStack_.empty()) {
3821         HandleModalPop(std::move(onWillDisappear), rootNode, targetId);
3822     }
3823 }
3824 
HandleModalShow(std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillDisappear,const RefPtr<UINode> rootNode,const NG::ContentCoverParam & contentCoverParam,int32_t targetId,std::optional<ModalTransition> modalTransition)3825 void OverlayManager::HandleModalShow(std::function<void(const std::string&)>&& callback,
3826     std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
3827     std::function<void()>&& onDisappear, std::function<void()>&& onWillDisappear, const RefPtr<UINode> rootNode,
3828     const NG::ContentCoverParam& contentCoverParam, int32_t targetId, std::optional<ModalTransition> modalTransition)
3829 {
3830     // builder content
3831     auto builder = AceType::DynamicCast<FrameNode>(buildNodeFunc());
3832     CHECK_NULL_VOID(builder);
3833     builder->GetRenderContext()->SetIsModalRootNode(true);
3834 
3835     // create modal page
3836     auto modalNode = FrameNode::CreateFrameNode(V2::MODAL_PAGE_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
3837         AceType::MakeRefPtr<ModalPresentationPattern>(
3838             targetId, static_cast<ModalTransition>(modalTransition.value()), std::move(callback)));
3839     if (modalStyle.backgroundColor.has_value()) {
3840         modalNode->GetRenderContext()->UpdateBackgroundColor(modalStyle.backgroundColor.value());
3841     }
3842     auto modalPagePattern = modalNode->GetPattern<ModalPresentationPattern>();
3843     CHECK_NULL_VOID(modalPagePattern);
3844     modalPagePattern->UpdateOnDisappear(std::move(onDisappear));
3845     modalPagePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
3846     modalPagePattern->UpdateOnAppear(std::move(onAppear));
3847     modalPagePattern->UpdateOnWillDismiss(std::move(contentCoverParam.onWillDismiss));
3848     modalPagePattern->UpdateUIExtensionMode(modalStyle.isUIExtension);
3849     modalPagePattern->SetProhibitedRemoveByRouter(modalStyle.prohibitedRemoveByRouter);
3850     modalPagePattern->SetProhibitedRemoveByNavigation(modalStyle.prohibitedRemoveByNavigation);
3851     modalPagePattern->SetHasTransitionEffect(contentCoverParam.transitionEffect != nullptr);
3852     modalNode->GetRenderContext()->UpdateChainedTransition(contentCoverParam.transitionEffect);
3853     modalStack_.push(WeakClaim(RawPtr(modalNode)));
3854     modalList_.emplace_back(WeakClaim(RawPtr(modalNode)));
3855     SaveLastModalNode();
3856     if (targetId < 0) {
3857         // modaluiextention node mounting
3858         modalNode->MountToParent(rootNode, DEFAULT_NODE_SLOT, false, false, true);
3859     } else {
3860         MountToParentWithService(rootNode, modalNode);
3861     }
3862     modalNode->AddChild(builder);
3863     if (!isAllowedBeCovered_ && modalNode->GetParent()) {
3864         TAG_LOGI(AceLogTag::ACE_OVERLAY,
3865             "modalNode->GetParent() %{public}d mark IsProhibitedAddChildNode when sessionId %{public}d,"
3866             "prohibitedRemoveByRouter: %{public}d.",
3867             modalNode->GetParent()->GetId(), targetId, modalStyle.prohibitedRemoveByRouter);
3868         if (AddCurSessionId(targetId)) {
3869             modalNode->GetParent()->UpdateModalUiextensionCount(true);
3870         }
3871     }
3872 
3873     FireModalPageShow();
3874     modalNode->GetParent()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3875     if (contentCoverParam.transitionEffect != nullptr) {
3876         PlayTransitionEffectIn(modalNode);
3877         return;
3878     }
3879     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) ||
3880         modalTransition == ModalTransition::NONE) {
3881         modalPagePattern->OnAppear();
3882         // Fire hidden event of navdestination under the appeared modal
3883         FireNavigationStateChange(false);
3884     }
3885     modalNode->OnAccessibilityEvent(
3886         AccessibilityEventType::PAGE_OPEN, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3887     if (modalTransition == ModalTransition::DEFAULT) {
3888         PlayDefaultModalTransition(modalNode, true);
3889     } else if (modalTransition == ModalTransition::ALPHA) {
3890         PlayAlphaModalTransition(modalNode, true);
3891     }
3892 }
3893 
HandleModalPop(std::function<void ()> && onWillDisappear,const RefPtr<UINode> rootNode,int32_t targetId)3894 void OverlayManager::HandleModalPop(
3895     std::function<void()>&& onWillDisappear, const RefPtr<UINode> rootNode, int32_t targetId)
3896 {
3897     auto topModalNode = GetModal(targetId);
3898     CHECK_NULL_VOID(topModalNode);
3899     if (!CheckTopModalNode(topModalNode, targetId)) {
3900         return;
3901     }
3902     auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
3903     CHECK_NULL_VOID(builder);
3904     if (builder->GetRenderContext()->HasDisappearTransition()) {
3905         if (!topModalNode->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
3906             topModalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
3907             // Fire hidden event of navdestination on the disappeared modal
3908             FireNavigationStateChange(false, topModalNode);
3909         }
3910         topModalNode->Clean(false, true);
3911         topModalNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3912     }
3913     auto modalPresentationPattern = topModalNode->GetPattern<ModalPresentationPattern>();
3914     CHECK_NULL_VOID(modalPresentationPattern);
3915     auto modalTransition = modalPresentationPattern->GetType();
3916     // lost focus
3917     ModalPageLostFocus(topModalNode);
3918     if (onWillDisappear) {
3919         onWillDisappear();
3920     }
3921     topModalNode->OnAccessibilityEvent(
3922         AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
3923     if (modalPresentationPattern->HasTransitionEffect()) {
3924         PlayTransitionEffectOut(topModalNode);
3925     } else if (modalTransition == ModalTransition::DEFAULT) {
3926         PlayDefaultModalTransition(topModalNode, false);
3927     } else if (modalTransition == ModalTransition::ALPHA) {
3928         PlayAlphaModalTransition(topModalNode, false);
3929     } else if (!builder->GetRenderContext()->HasDisappearTransition()) {
3930         if (!modalPresentationPattern->IsExecuteOnDisappear()) {
3931             modalPresentationPattern->OnDisappear();
3932             // Fire hidden event of navdestination on the disappeared modal
3933             FireNavigationStateChange(false, topModalNode);
3934         }
3935         FireAutoSave(topModalNode);
3936         RemoveChildWithService(rootNode, topModalNode);
3937         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3938     }
3939     RemoveModal(targetId);
3940     if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
3941         // Fire shown event of navdestination under the disappeared modal
3942         FireNavigationStateChange(true);
3943     }
3944     FireModalPageHide();
3945     SaveLastModalNode();
3946 }
3947 
FireModalPageShow()3948 void OverlayManager::FireModalPageShow()
3949 {
3950     auto topModalNode = modalList_.back().Upgrade();
3951     CHECK_NULL_VOID(topModalNode);
3952     auto topModalFocusView = topModalNode->GetPattern<FocusView>();
3953     CHECK_NULL_VOID(topModalFocusView);
3954     topModalFocusView->FocusViewShow();
3955 }
3956 
ModalPageLostFocus(const RefPtr<FrameNode> & node)3957 void OverlayManager::ModalPageLostFocus(const RefPtr<FrameNode>& node)
3958 {
3959     InputMethodManager::GetInstance()->ProcessModalPageScene();
3960 }
3961 
FireModalPageHide()3962 void OverlayManager::FireModalPageHide() {}
3963 
PlayDefaultModalTransition(const RefPtr<FrameNode> & modalNode,bool isTransitionIn)3964 void OverlayManager::PlayDefaultModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn)
3965 {
3966     // current modal animation
3967     AnimationOption option;
3968     const RefPtr<InterpolatingSpring> curve =
3969         AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
3970     option.SetCurve(curve);
3971     option.SetFillMode(FillMode::FORWARDS);
3972     auto context = modalNode->GetRenderContext();
3973     CHECK_NULL_VOID(context);
3974 
3975     auto rootHeight = GetRootHeight();
3976     auto modalPositionY = modalNode->GetGeometryNode()->GetFrameRect().GetY();
3977     auto showHeight = rootHeight - modalPositionY;
3978 
3979     if (isTransitionIn) {
3980         PlayDefaultModalIn(modalNode, context, option, showHeight);
3981     } else {
3982         PlayDefaultModalOut(modalNode, context, option, showHeight);
3983     }
3984 }
3985 
PlayDefaultModalIn(const RefPtr<FrameNode> & modalNode,const RefPtr<RenderContext> & context,AnimationOption option,float showHeight)3986 void OverlayManager::PlayDefaultModalIn(
3987     const RefPtr<FrameNode>& modalNode, const RefPtr<RenderContext>& context, AnimationOption option, float showHeight)
3988 {
3989     context->OnTransformTranslateUpdate({ 0.0f, showHeight, 0.0f });
3990     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
3991         option.SetOnFinishEvent([modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
3992             auto modal = modalWK.Upgrade();
3993             auto overlayManager = overlayWeak.Upgrade();
3994             CHECK_NULL_VOID(modal && overlayManager);
3995             modal->GetPattern<ModalPresentationPattern>()->OnAppear();
3996             // Fire hidden event of navdestination on the disappeared modal
3997             overlayManager->FireNavigationStateChange(false);
3998         });
3999     }
4000     AnimationUtils::Animate(
4001         option,
4002         [context]() {
4003             if (context) {
4004                 context->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
4005             }
4006         },
4007         option.GetOnFinishEvent());
4008 }
4009 
PlayDefaultModalOut(const RefPtr<FrameNode> & modalNode,const RefPtr<RenderContext> & context,AnimationOption option,float showHeight)4010 void OverlayManager::PlayDefaultModalOut(
4011     const RefPtr<FrameNode>& modalNode, const RefPtr<RenderContext>& context, AnimationOption option, float showHeight)
4012 {
4013     auto lastModalNode = lastModalNode_.Upgrade();
4014     CHECK_NULL_VOID(lastModalNode);
4015     auto lastModalContext = lastModalNode->GetRenderContext();
4016     CHECK_NULL_VOID(lastModalContext);
4017     lastModalContext->UpdateOpacity(1.0);
4018     option.SetOnFinishEvent(
4019         [rootWeak = rootNodeWeak_, modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4020             auto modal = modalWK.Upgrade();
4021             auto overlayManager = overlayWeak.Upgrade();
4022             CHECK_NULL_VOID(modal && overlayManager);
4023             auto root = overlayManager->FindWindowScene(modal);
4024             CHECK_NULL_VOID(root);
4025             if (!modal->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
4026                 modal->GetPattern<ModalPresentationPattern>()->OnDisappear();
4027                 // Fire hidden event of navdestination on the disappeared modal
4028                 overlayManager->FireNavigationStateChange(false, modal);
4029             }
4030             overlayManager->FireAutoSave(modal);
4031             overlayManager->RemoveChildWithService(root, modal);
4032             root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4033             // Fire shown event of navdestination under the disappeared modal
4034             overlayManager->FireNavigationStateChange(true);
4035         });
4036     context->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f });
4037     AnimationUtils::Animate(
4038         option,
4039         [context, showHeight]() {
4040             if (context) {
4041                 context->OnTransformTranslateUpdate({ 0.0f, showHeight, 0.0f });
4042             }
4043         },
4044         option.GetOnFinishEvent());
4045 }
4046 
PlayAlphaModalTransition(const RefPtr<FrameNode> & modalNode,bool isTransitionIn)4047 void OverlayManager::PlayAlphaModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn)
4048 {
4049     AnimationOption option;
4050     option.SetCurve(Curves::FRICTION);
4051     option.SetDuration(FULL_MODAL_ALPHA_ANIMATION_DURATION);
4052     option.SetFillMode(FillMode::FORWARDS);
4053     auto lastModalNode = lastModalNode_.Upgrade();
4054     CHECK_NULL_VOID(lastModalNode);
4055     auto lastModalContext = lastModalNode->GetRenderContext();
4056     CHECK_NULL_VOID(lastModalContext);
4057     auto context = modalNode->GetRenderContext();
4058     CHECK_NULL_VOID(context);
4059     if (isTransitionIn) {
4060         // last page animation
4061         lastModalContext->OpacityAnimation(option, 1, 0);
4062         lastModalContext->UpdateOpacity(0);
4063         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4064             option.SetOnFinishEvent([modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4065                 auto modal = modalWK.Upgrade();
4066                 auto overlayManager = overlayWeak.Upgrade();
4067                 CHECK_NULL_VOID(modal && overlayManager);
4068                 modal->GetPattern<ModalPresentationPattern>()->OnAppear();
4069                 // Fire hidden event of navdestination on the disappeared modal
4070                 overlayManager->FireNavigationStateChange(false);
4071             });
4072         }
4073         // current modal page animation
4074         context->OpacityAnimation(option, 0, 1);
4075     } else {
4076         // last page animation
4077         lastModalContext->OpacityAnimation(option, 0, 1);
4078 
4079         // current modal page animation
4080         option.SetOnFinishEvent(
4081             [rootWeak = rootNodeWeak_, modalWK = WeakClaim(RawPtr(modalNode)), overlayWeak = WeakClaim(this)] {
4082                 auto modal = modalWK.Upgrade();
4083                 auto overlayManager = overlayWeak.Upgrade();
4084                 CHECK_NULL_VOID(modal && overlayManager);
4085                 auto root = overlayManager->FindWindowScene(modal);
4086                 CHECK_NULL_VOID(root);
4087                 if (!modal->GetPattern<ModalPresentationPattern>()->IsExecuteOnDisappear()) {
4088                     modal->GetPattern<ModalPresentationPattern>()->OnDisappear();
4089                     // Fire hidden event of navdestination on the disappeared modal
4090                     overlayManager->FireNavigationStateChange(false, modal);
4091                 }
4092                 overlayManager->FireAutoSave(modal);
4093                 overlayManager->RemoveChildWithService(root, modal);
4094                 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4095                 // Fire shown event of navdestination under the disappeared modal
4096                 overlayManager->FireNavigationStateChange(true);
4097             });
4098         context->OpacityAnimation(option, 1, 0);
4099     }
4100 }
4101 
BindSheet(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode)4102 void OverlayManager::BindSheet(bool isShow, std::function<void(const std::string&)>&& callback,
4103     std::function<RefPtr<UINode>()>&& buildNodeFunc, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4104     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4105     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4106     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4107     std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4108     std::function<void(const float)>&& onWidthDidChange, std::function<void(const float)>&& onTypeDidChange,
4109     std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode)
4110 {
4111     auto instanceId = sheetStyle.instanceId.has_value() ? sheetStyle.instanceId.value() : Container::CurrentId();
4112     ContainerScope scope(instanceId);
4113     auto pipeline = PipelineContext::GetCurrentContext();
4114     CHECK_NULL_VOID(pipeline);
4115     auto bindSheetTask = [weak = AceType::WeakClaim(this), isShow, callback = std::move(callback),
4116                              buildNodeFunc = std::move(buildNodeFunc),
4117                              buildtitleNodeFunc = std::move(buildtitleNodeFunc), sheetStyle,
4118                              onAppear = std::move(onAppear), onDisappear = std::move(onDisappear),
4119                              shouldDismiss = std::move(shouldDismiss), onWillDismiss = std::move(onWillDismiss),
4120                              onWillAppear = std::move(onWillAppear), onWillDisappear = std::move(onWillDisappear),
4121                              onHeightDidChange = std::move(onHeightDidChange),
4122                              onDetentsDidChange = std::move(onDetentsDidChange),
4123                              onWidthDidChange = std::move(onWidthDidChange),
4124                              onTypeDidChange = std::move(onTypeDidChange), sheetSpringBack = std::move(sheetSpringBack),
4125                              targetNode, instanceId]() mutable {
4126         ContainerScope scope(instanceId);
4127         auto overlay = weak.Upgrade();
4128         CHECK_NULL_VOID(overlay);
4129         overlay->OnBindSheet(isShow, std::move(callback), std::move(buildNodeFunc), std::move(buildtitleNodeFunc),
4130             sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4131             std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4132             std::move(onDetentsDidChange), std::move(onWidthDidChange), std::move(onTypeDidChange),
4133             std::move(sheetSpringBack), targetNode);
4134         auto pipeline = PipelineContext::GetCurrentContext();
4135         CHECK_NULL_VOID(pipeline);
4136         pipeline->FlushUITasks();
4137     };
4138     pipeline->RequestFrame();
4139     pipeline->AddAnimationClosure(bindSheetTask);
4140 }
4141 
UpdateSheetMaskBackgroundColor(const RefPtr<FrameNode> & maskNode,const RefPtr<RenderContext> & maskRenderContext,const SheetStyle & sheetStyle)4142 void OverlayManager::UpdateSheetMaskBackgroundColor(
4143     const RefPtr<FrameNode>& maskNode, const RefPtr<RenderContext>& maskRenderContext, const SheetStyle& sheetStyle)
4144 {
4145     if (sheetStyle.maskColor.has_value()) {
4146         maskRenderContext->UpdateBackgroundColor(sheetStyle.maskColor.value());
4147     } else {
4148         maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4149             HitTestMode::HTMTRANSPARENT);
4150         maskRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
4151     }
4152 }
4153 
InitSheetMask(const RefPtr<FrameNode> & maskNode,const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle)4154 void OverlayManager::InitSheetMask(
4155     const RefPtr<FrameNode>& maskNode, const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle)
4156 {
4157     auto maskRenderContext = maskNode->GetRenderContext();
4158     CHECK_NULL_VOID(maskRenderContext);
4159     auto pipeline = PipelineContext::GetCurrentContext();
4160     CHECK_NULL_VOID(pipeline);
4161     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4162     CHECK_NULL_VOID(sheetTheme);
4163     auto sheetLayoutProps = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4164     CHECK_NULL_VOID(sheetLayoutProps);
4165     maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMDEFAULT);
4166     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
4167         UpdateSheetMaskBackgroundColor(maskNode, maskRenderContext, sheetStyle);
4168     } else {
4169         auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
4170         CHECK_NULL_VOID(eventConfirmHub);
4171         auto sheetMaskClickEvent = AceType::MakeRefPtr<NG::ClickEvent>(
4172             [weak = AceType::WeakClaim(AceType::RawPtr(sheetNode))](const GestureEvent& /* info */) {
4173                 auto sheet = weak.Upgrade();
4174                 CHECK_NULL_VOID(sheet);
4175                 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4176                 CHECK_NULL_VOID(sheetPattern);
4177                 if (sheetPattern->IsDragging()) {
4178                     return;
4179                 }
4180                 sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::TOUCH_OUTSIDE);
4181             });
4182         auto maskNodeId = maskNode->GetId();
4183         sheetMaskClickEventMap_.emplace(maskNodeId, sheetMaskClickEvent);
4184         eventConfirmHub->AddClickEvent(sheetMaskClickEvent, DISTANCE_THRESHOLD);
4185         if (!sheetStyle.interactive.has_value()) {
4186             if (sheetNode->GetPattern<SheetPresentationPattern>()->GetSheetType() == SheetType::SHEET_POPUP) {
4187                 maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4188                     HitTestMode::HTMTRANSPARENT);
4189                 eventConfirmHub->RemoveClickEvent(sheetMaskClickEvent);
4190                 sheetMaskClickEventMap_.erase(maskNodeId);
4191             }
4192         } else if (sheetStyle.interactive == true) {
4193             maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4194                 HitTestMode::HTMTRANSPARENT);
4195             eventConfirmHub->RemoveClickEvent(sheetMaskClickEvent);
4196             sheetMaskClickEventMap_.erase(maskNodeId);
4197         }
4198     }
4199 }
4200 
CleanInvalidModalNode(const WeakPtr<FrameNode> & invalidNode)4201 void OverlayManager::CleanInvalidModalNode(const WeakPtr<FrameNode>& invalidNode)
4202 {
4203     // When a modalNode.Upgrade() == nullptr, the modalNode is invalid
4204     modalList_.remove(invalidNode);
4205     std::vector<WeakPtr<FrameNode>> sheetVector;
4206     while (!modalStack_.empty()) {
4207         if (modalStack_.top() != invalidNode) {
4208             sheetVector.push_back(modalStack_.top());
4209         }
4210         modalStack_.pop();
4211     }
4212     for (auto iter = sheetVector.rbegin(); iter != sheetVector.rend(); ++iter) {
4213         modalStack_.push(*iter);
4214     }
4215 }
4216 
CloseSheet(const SheetKey & sheetKey)4217 void OverlayManager::CloseSheet(const SheetKey& sheetKey)
4218 {
4219     if (modalStack_.empty()) {
4220         return;
4221     }
4222     auto iter = sheetMap_.find(sheetKey);
4223     if (sheetMap_.empty() || iter == sheetMap_.end()) {
4224         DeleteModal(sheetKey.targetId);
4225         return;
4226     }
4227     auto sheetNode = iter->second.Upgrade();
4228     if (sheetNode == nullptr) {
4229         TAG_LOGE(AceLogTag::ACE_SHEET, "The sheetNode is null, clean it.");
4230         CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
4231         CleanInvalidModalNode(iter->second);
4232         sheetMap_.erase(sheetKey);
4233         SaveLastModalNode();
4234         return;
4235     }
4236     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4237     CHECK_NULL_VOID(sheetPattern);
4238     sheetPattern->SetShowState(false);
4239     auto buildContent = sheetPattern->GetFirstFrameNodeOfBuilder();
4240     CHECK_NULL_VOID(buildContent);
4241     auto buildRenderContext = buildContent->GetRenderContext();
4242     CHECK_NULL_VOID(buildRenderContext);
4243     sheetPattern->OnWillDisappear();
4244     if (buildRenderContext->HasDisappearTransition()) {
4245         if (!sheetPattern->IsExecuteOnDisappear()) {
4246             sheetPattern->OnDisappear();
4247         }
4248         sheetPattern->OnDisappear();
4249         sheetNode->Clean(false, true);
4250         sheetNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4251     }
4252     ModalPageLostFocus(sheetNode);
4253     PlaySheetTransitionWhenClose(sheetNode);
4254     sheetPattern->SetDismissProcess(true);
4255     sheetMap_.erase(sheetKey);
4256     CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
4257     RemoveSheetNode(sheetNode);
4258     FireModalPageHide();
4259     SaveLastModalNode();
4260 }
4261 
PlaySheetTransitionWhenClose(const RefPtr<FrameNode> & sheetNode)4262 void OverlayManager::PlaySheetTransitionWhenClose(const RefPtr<FrameNode>& sheetNode)
4263 {
4264     CHECK_NULL_VOID(sheetNode);
4265     auto maskNode = GetSheetMask(sheetNode);
4266     if (maskNode) {
4267         PlaySheetMaskTransition(maskNode, false);
4268     }
4269     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4270     CHECK_NULL_VOID(sheetPattern);
4271     auto sheetType = sheetPattern->GetSheetType();
4272     if (sheetType == SheetType::SHEET_POPUP) {
4273         PlayBubbleStyleSheetTransition(sheetNode, false);
4274     } else {
4275         PlaySheetTransition(sheetNode, false);
4276     }
4277 }
4278 
DismissSheet()4279 void OverlayManager::DismissSheet()
4280 {
4281     if (modalStack_.empty()) {
4282         return;
4283     }
4284     auto iter = sheetMap_.find(dismissTarget_.sheetKey);
4285     if (sheetMap_.empty() || iter == sheetMap_.end()) {
4286         DeleteModal(dismissTarget_.GetTargetId());
4287         return;
4288     }
4289     auto sheetNode = iter->second.Upgrade();
4290     CHECK_NULL_VOID(sheetNode);
4291     if (sheetNode->GetTag() == V2::SHEET_PAGE_TAG) {
4292         auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4293         CHECK_NULL_VOID(sheetPattern);
4294         sheetPattern->DismissSheet();
4295     }
4296 }
4297 
DismissContentCover()4298 void OverlayManager::DismissContentCover()
4299 {
4300     if (modalStack_.empty()) {
4301         return;
4302     }
4303     const auto& modalNode = GetModal(dismissTarget_.GetTargetId());
4304     if (modalNode == nullptr) {
4305         DeleteModal(dismissTarget_.GetTargetId());
4306         return;
4307     }
4308     if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4309         ModalPageLostFocus(modalNode);
4310         auto builder = AceType::DynamicCast<FrameNode>(modalNode->GetFirstChild());
4311         if (!ModalPageExitProcess(modalNode)) {
4312             return;
4313         }
4314         RemoveModal(dismissTarget_.GetTargetId());
4315         auto modalPattern = modalNode->GetPattern<ModalPresentationPattern>();
4316         CHECK_NULL_VOID(modalPattern);
4317         auto modalTransition = modalPattern->GetType();
4318         if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
4319             FireNavigationStateChange(true);
4320         }
4321         FireModalPageHide();
4322         SaveLastModalNode();
4323     }
4324 }
4325 
SheetSpringBack()4326 void OverlayManager::SheetSpringBack()
4327 {
4328     auto sheetNode = sheetMap_[dismissTarget_.sheetKey].Upgrade();
4329     CHECK_NULL_VOID(sheetNode);
4330     if (sheetNode->GetTag() == V2::SHEET_PAGE_TAG) {
4331         auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4332         CHECK_NULL_VOID(sheetPattern);
4333         sheetPattern->SheetSpringBack();
4334     }
4335 }
4336 
GetModal(int32_t targetId)4337 RefPtr<FrameNode> OverlayManager::GetModal(int32_t targetId)
4338 {
4339     for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4340         auto modalNode = (*modal).Upgrade();
4341         if (!modalNode) {
4342             continue;
4343         }
4344         int32_t modalTargetId = -1;
4345         if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4346             modalTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
4347         } else {
4348             continue;
4349         }
4350         if (modalTargetId == targetId) {
4351             return modalNode;
4352         }
4353     }
4354     return nullptr;
4355 }
4356 
RemoveModal(int32_t targetId)4357 void OverlayManager::RemoveModal(int32_t targetId)
4358 {
4359     bool isDelete = false;
4360     for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4361         auto modalNode = (*modal).Upgrade();
4362         if (!modalNode) {
4363             continue;
4364         }
4365         int32_t modalTargetId = -1;
4366         if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
4367             modalTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
4368         } else {
4369             continue;
4370         }
4371         if (modalTargetId == targetId) {
4372             isDelete = true;
4373             modalList_.erase(modal);
4374             break;
4375         }
4376     }
4377     if (isDelete) {
4378         while (!modalStack_.empty()) {
4379             modalStack_.pop();
4380         }
4381         for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
4382             modalStack_.push(*modal);
4383         }
4384     }
4385 }
4386 
RemoveSheetNode(const RefPtr<FrameNode> & sheetNode)4387 void OverlayManager::RemoveSheetNode(const RefPtr<FrameNode>& sheetNode)
4388 {
4389     CHECK_NULL_VOID(sheetNode);
4390     if (!modalList_.empty()) {
4391         modalList_.remove(WeakClaim(RawPtr(sheetNode)));
4392     }
4393     std::vector<WeakPtr<FrameNode>> sheetVector;
4394     while (!modalStack_.empty()) {
4395         if (modalStack_.top() != WeakClaim(RawPtr(sheetNode))) {
4396             sheetVector.push_back(modalStack_.top());
4397         }
4398         modalStack_.pop();
4399     }
4400     for (auto iter = sheetVector.rbegin(); iter != sheetVector.rend(); ++iter) {
4401         modalStack_.push(*iter);
4402     }
4403 }
4404 
PlaySheetTransition(RefPtr<FrameNode> sheetNode,bool isTransitionIn,bool isFirstTransition)4405 void OverlayManager::PlaySheetTransition(
4406     RefPtr<FrameNode> sheetNode, bool isTransitionIn, bool isFirstTransition)
4407 {
4408     CHECK_NULL_VOID(sheetNode);
4409     sheetNode->OnAccessibilityEvent(
4410         isTransitionIn ? AccessibilityEventType::PAGE_OPEN : AccessibilityEventType::PAGE_CLOSE,
4411         WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE);
4412 
4413     // current sheet animation
4414     AnimationOption option;
4415     const RefPtr<InterpolatingSpring> curve =
4416         AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
4417     option.SetCurve(curve);
4418     option.SetFillMode(FillMode::FORWARDS);
4419     auto context = sheetNode->GetRenderContext();
4420     CHECK_NULL_VOID(context);
4421     context->UpdateRenderGroup(true, false, true);
4422     TAG_LOGD(AceLogTag::ACE_SHEET, "UpdateRenderGroup start");
4423     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4424     CHECK_NULL_VOID(sheetPattern);
4425     auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
4426     auto sheetParent = DynamicCast<FrameNode>(sheetNode->GetParent());
4427     CHECK_NULL_VOID(sheetParent);
4428     if (isTransitionIn) {
4429         sheetPattern->SetCurrentHeight(sheetHeight_);
4430         float offset = 0.0f;
4431         auto sheetType = sheetPattern->GetSheetType();
4432         if (sheetType == SheetType::SHEET_POPUP || sheetPattern->IsCurSheetNeedHalfFoldHover()) {
4433             offset = sheetPattern->GetSheetOffset();
4434         } else {
4435             offset = sheetMaxHeight - sheetHeight_;
4436         }
4437         if (isFirstTransition) {
4438             context->UpdateTransformTranslate({ 0.0f, sheetMaxHeight, 0.0f });
4439             if (NearZero(sheetHeight_)) {
4440                 return;
4441             }
4442         }
4443         if (sheetPattern->IsFoldStatusChanged()) {
4444             option.SetDuration(0);
4445             option.SetCurve(Curves::LINEAR);
4446         }
4447         sheetPattern->FireOnTypeDidChange();
4448         sheetPattern->FireOnWidthDidChange(sheetNode);
4449         option.SetOnFinishEvent(
4450             [sheetWK = WeakClaim(RawPtr(sheetNode)), weak = AceType::WeakClaim(this), isFirst = isFirstTransition] {
4451                 auto sheetNode = sheetWK.Upgrade();
4452                 CHECK_NULL_VOID(sheetNode);
4453                 auto context = sheetNode->GetRenderContext();
4454                 CHECK_NULL_VOID(context);
4455                 context->UpdateRenderGroup(false, false, true);
4456                 TAG_LOGD(AceLogTag::ACE_SHEET, "UpdateRenderGroup finished");
4457                 auto pattern = sheetNode->GetPattern<SheetPresentationPattern>();
4458                 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
4459                     isFirst) {
4460                     pattern->OnAppear();
4461                 }
4462                 pattern->AvoidAiBar();
4463                 auto overlay = weak.Upgrade();
4464                 CHECK_NULL_VOID(overlay);
4465                 pattern->FireOnDetentsDidChange(overlay->sheetHeight_);
4466                 pattern->FireOnHeightDidChange(overlay->sheetHeight_);
4467             });
4468         ACE_SCOPED_TRACE("Sheet start admission");
4469         AnimationUtils::Animate(
4470             option,
4471             [context, offset]() {
4472                 if (context) {
4473                     context->UpdateTransformTranslate({ 0.0f, offset, 0.0f });
4474                 }
4475             },
4476             option.GetOnFinishEvent());
4477     } else {
4478         option.SetOnFinishEvent(
4479             [rootWeak = rootNodeWeak_, sheetWK = WeakClaim(RawPtr(sheetNode)), weakOverlayManager = WeakClaim(this)] {
4480                 auto sheet = sheetWK.Upgrade();
4481                 auto overlayManager = weakOverlayManager.Upgrade();
4482                 CHECK_NULL_VOID(sheet && overlayManager);
4483                 if (!sheet->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
4484                     sheet->GetPattern<SheetPresentationPattern>()->OnDisappear();
4485                 }
4486                 auto root = overlayManager->FindWindowScene(sheet);
4487                 CHECK_NULL_VOID(root);
4488                 auto sheetParent = DynamicCast<FrameNode>(sheet->GetParent());
4489                 CHECK_NULL_VOID(sheetParent);
4490                 overlayManager->FireAutoSave(sheet);
4491                 overlayManager->RemoveChildWithService(root, sheetParent);
4492                 root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4493             });
4494         sheetParent->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
4495         AnimationUtils::Animate(
4496             option,
4497             [context, sheetMaxHeight]() {
4498                 if (context) {
4499                     context->UpdateTransformTranslate({ 0.0f, sheetMaxHeight, 0.0f });
4500                 }
4501             },
4502             option.GetOnFinishEvent());
4503     }
4504 }
4505 
OnBindSheet(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<UINode> ()> && buildNodeFunc,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode)4506 void OverlayManager::OnBindSheet(bool isShow, std::function<void(const std::string&)>&& callback,
4507     std::function<RefPtr<UINode>()>&& buildNodeFunc, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4508     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4509     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4510     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4511     std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4512     std::function<void(const float)>&& onWidthDidChange, std::function<void(const float)>&& onTypeDidChange,
4513     std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode)
4514 {
4515     int32_t targetId = targetNode->GetId();
4516     if (!isShow) {
4517         CloseSheet(SheetKey(targetId));
4518         return;
4519     }
4520     SheetKey sheetKey(targetId);
4521     auto iter = sheetMap_.find(sheetKey);
4522     if (iter != sheetMap_.end()) {
4523         auto sheetNode = iter->second.Upgrade();
4524         CHECK_NULL_VOID(sheetNode);
4525         UpdateSheetPage(sheetNode, sheetStyle, targetId, false, false,
4526             std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4527             std::move(onWillDisappear), std::move(onHeightDidChange),
4528             std::move(onDetentsDidChange), std::move(onWidthDidChange),
4529             std::move(onTypeDidChange), std::move(sheetSpringBack));
4530         return;
4531     }
4532     // build content
4533     RefPtr<UINode> sheetContentNode = buildNodeFunc();
4534     CHECK_NULL_VOID(sheetContentNode);
4535     auto frameChildNode = sheetContentNode->GetFrameChildByIndex(0, true);
4536     if (!frameChildNode) {
4537         // The function should return if the frameNodeChild of the builder is empty,
4538         // otherwise an exception will occur when unmount an empty node.
4539         TAG_LOGE(AceLogTag::ACE_SHEET, "sheet buildNode is nullptr");
4540         return;
4541     }
4542     OnBindSheetInner(std::move(callback), sheetContentNode, std::move(buildtitleNodeFunc),
4543         sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4544         std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4545         std::move(onDetentsDidChange), std::move(onWidthDidChange),
4546         std::move(onTypeDidChange), std::move(sheetSpringBack), targetNode);
4547 }
4548 
OpenBindSheetByUIContext(const RefPtr<FrameNode> & sheetContentNode,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,std::function<void (const int32_t,const int32_t)> cleanViewContextMapCallback,const RefPtr<FrameNode> & targetNode)4549 void OverlayManager::OpenBindSheetByUIContext(
4550     const RefPtr<FrameNode>& sheetContentNode, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4551     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4552     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4553     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4554     std::function<void(const float)>&& onHeightDidChange,
4555     std::function<void(const float)>&& onDetentsDidChange,
4556     std::function<void(const float)>&& onWidthDidChange,
4557     std::function<void(const float)>&& onTypeDidChange,
4558     std::function<void()>&& sheetSpringBack,
4559     std::function<void(const int32_t, const int32_t)> cleanViewContextMapCallback,
4560     const RefPtr<FrameNode>& targetNode)
4561 {
4562     if (cleanViewContextMapCallback_ == nullptr) {
4563         cleanViewContextMapCallback_ = cleanViewContextMapCallback;
4564     }
4565     auto instanceId = sheetStyle.instanceId.has_value() ? sheetStyle.instanceId.value() : Container::CurrentId();
4566     ContainerScope scope(instanceId);
4567     OnBindSheetInner(nullptr, sheetContentNode, std::move(buildtitleNodeFunc),
4568         sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
4569         std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4570         std::move(onDetentsDidChange), std::move(onWidthDidChange),
4571         std::move(onTypeDidChange), std::move(sheetSpringBack), targetNode, true);
4572 }
4573 
UpdateBindSheetByUIContext(const RefPtr<NG::FrameNode> & sheetContentNode,NG::SheetStyle & sheetStyle,int32_t targetId,bool isPartialUpdate)4574 void OverlayManager::UpdateBindSheetByUIContext(
4575     const RefPtr<NG::FrameNode>& sheetContentNode, NG::SheetStyle& sheetStyle, int32_t targetId, bool isPartialUpdate)
4576 {
4577     SheetKey sheetKey;
4578     if (!CreateSheetKey(sheetContentNode, targetId, sheetKey)) {
4579         TAG_LOGE(AceLogTag::ACE_SHEET, "CreateSheetKey failed");
4580         return;
4581     }
4582     targetId = sheetKey.targetId;
4583     auto iter = sheetMap_.find(sheetKey);
4584     if (iter != sheetMap_.end()) {
4585         auto sheetNode = iter->second.Upgrade();
4586         CHECK_NULL_VOID(sheetNode);
4587         UpdateSheetPage(sheetNode, sheetStyle, targetId, true, isPartialUpdate);
4588     }
4589     TAG_LOGE(AceLogTag::ACE_SHEET, "Can not find sheet.");
4590     return;
4591 }
4592 
UpdateSheetRender(const RefPtr<FrameNode> & sheetPageNode,NG::SheetStyle & sheetStyle,bool isPartialUpdate)4593 void OverlayManager::UpdateSheetRender(
4594     const RefPtr<FrameNode>& sheetPageNode, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
4595 {
4596     CHECK_NULL_VOID(sheetPageNode);
4597     auto sheetRenderContext = sheetPageNode->GetRenderContext();
4598     CHECK_NULL_VOID(sheetRenderContext);
4599     auto pipeline = sheetPageNode->GetContext();
4600     CHECK_NULL_VOID(pipeline);
4601     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4602     CHECK_NULL_VOID(sheetTheme);
4603     SetSheetBackgroundColor(sheetPageNode, sheetTheme, sheetStyle);
4604     if (sheetStyle.backgroundBlurStyle.has_value()) {
4605         SetSheetBackgroundBlurStyle(sheetPageNode, sheetStyle.backgroundBlurStyle.value());
4606     }
4607     auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4608     CHECK_NULL_VOID(sheetNodePattern);
4609     sheetNodePattern->SetSheetBorderWidth();
4610     if (sheetStyle.borderStyle.has_value()) {
4611         sheetRenderContext->UpdateBorderStyle(sheetStyle.borderStyle.value());
4612     }
4613     if (sheetStyle.borderColor.has_value()) {
4614         sheetRenderContext->UpdateBorderColor(sheetStyle.borderColor.value());
4615     }
4616     if (sheetStyle.shadow.has_value()) {
4617         sheetRenderContext->UpdateBackShadow(sheetStyle.shadow.value());
4618     } else if (!isPartialUpdate) {
4619         sheetRenderContext->UpdateBackShadow(ShadowConfig::NoneShadow);
4620     }
4621     sheetNodePattern->UpdateMaskBackgroundColor();
4622 }
UpdateSheetProperty(const RefPtr<FrameNode> & sheetNode,NG::SheetStyle & currentStyle,bool isPartialUpdate)4623 void OverlayManager::UpdateSheetProperty(const RefPtr<FrameNode>& sheetNode,
4624     NG::SheetStyle& currentStyle, bool isPartialUpdate)
4625 {
4626     auto pipeline = sheetNode->GetContext();
4627     CHECK_NULL_VOID(pipeline);
4628     UpdateSheetRender(sheetNode, currentStyle, isPartialUpdate);
4629     auto maskNode = GetSheetMask(sheetNode);
4630     if (maskNode) {
4631         UpdateSheetMask(maskNode, sheetNode, currentStyle, isPartialUpdate);
4632     }
4633     sheetNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4634     pipeline->FlushUITasks();
4635     ComputeSheetOffset(currentStyle, sheetNode);
4636 }
4637 
UpdateSheetPage(const RefPtr<FrameNode> & sheetNode,NG::SheetStyle & sheetStyle,int32_t targetId,bool isStartByUIContext,bool isPartialUpdate,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack)4638 void OverlayManager::UpdateSheetPage(const RefPtr<FrameNode>& sheetNode, NG::SheetStyle& sheetStyle,
4639     int32_t targetId, bool isStartByUIContext, bool isPartialUpdate,
4640     std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4641     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4642     std::function<void()>&& onWillDisappear, std::function<void(const float)>&& onHeightDidChange,
4643     std::function<void(const float)>&& onDetentsDidChange,
4644     std::function<void(const float)>&& onWidthDidChange,
4645     std::function<void(const float)>&& onTypeDidChange,
4646     std::function<void()>&& sheetSpringBack)
4647 {
4648     if (sheetNode->GetTag() != V2::SHEET_PAGE_TAG ||
4649         sheetNode->GetPattern<SheetPresentationPattern>()->GetTargetId() != targetId) {
4650         return;
4651     }
4652     auto sheetNodePattern = sheetNode->GetPattern<SheetPresentationPattern>();
4653     CHECK_NULL_VOID(sheetNodePattern);
4654     auto customHeightOrDetentsChanged = sheetNodePattern->IsCustomHeightOrDetentsChanged(sheetStyle);
4655     if (isStartByUIContext) {
4656         auto currentStyle = UpdateSheetStyle(sheetNode, sheetStyle, isPartialUpdate);
4657         UpdateSheetProperty(sheetNode, currentStyle, isPartialUpdate);
4658     } else {
4659         sheetNodePattern->UpdateOnAppear(std::move(onAppear));
4660         sheetNodePattern->UpdateOnDisappear(std::move(onDisappear));
4661         sheetNodePattern->UpdateShouldDismiss(std::move(shouldDismiss));
4662         sheetNodePattern->UpdateOnWillDismiss(std::move(onWillDismiss));
4663         sheetNodePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
4664         sheetNodePattern->UpdateOnHeightDidChange(std::move(onHeightDidChange));
4665         sheetNodePattern->UpdateOnDetentsDidChange(std::move(onDetentsDidChange));
4666         sheetNodePattern->UpdateOnWidthDidChange(std::move(onWidthDidChange));
4667         sheetNodePattern->UpdateOnTypeDidChange(std::move(onTypeDidChange));
4668         sheetNodePattern->UpdateSheetSpringBack(std::move(sheetSpringBack));
4669         auto layoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4670         layoutProperty->UpdateSheetStyle(sheetStyle);
4671         UpdateSheetProperty(sheetNode, sheetStyle, isPartialUpdate);
4672     }
4673     sheetNode->MarkModifyDone();
4674     auto sheetType = sheetNodePattern->GetSheetType();
4675     if (sheetType != SheetType::SHEET_POPUP && !sheetNodePattern->GetDismissProcess() && customHeightOrDetentsChanged) {
4676         PlaySheetTransition(sheetNode, true, false);
4677     }
4678 }
4679 
UpdateSheetStyle(const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle,bool isPartialUpdate)4680 SheetStyle OverlayManager::UpdateSheetStyle(
4681     const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle, bool isPartialUpdate)
4682 {
4683     auto layoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4684     CHECK_NULL_RETURN(layoutProperty, sheetStyle);
4685     auto currentStyle = layoutProperty->GetSheetStyleValue();
4686     if (isPartialUpdate) {
4687         currentStyle.PartialUpdate(sheetStyle);
4688     } else {
4689         auto currentShowInPage = currentStyle.showInPage;
4690         auto currentInstanceId = currentStyle.instanceId;
4691         currentStyle = sheetStyle;
4692         currentStyle.showInPage = currentShowInPage;
4693         currentStyle.instanceId = currentInstanceId;
4694     }
4695     layoutProperty->UpdateSheetStyle(currentStyle);
4696     return currentStyle;
4697 }
4698 
CloseBindSheetByUIContext(const RefPtr<NG::FrameNode> & sheetContentNode,int32_t targetId)4699 void OverlayManager::CloseBindSheetByUIContext(const RefPtr<NG::FrameNode>& sheetContentNode, int32_t targetId)
4700 {
4701     SheetKey sheetKey;
4702     if (!CreateSheetKey(sheetContentNode, targetId, sheetKey)) {
4703         TAG_LOGE(AceLogTag::ACE_SHEET, "CreateSheetKey failed");
4704         return;
4705     }
4706     CloseSheet(sheetKey);
4707 }
4708 
OnBindSheetInner(std::function<void (const std::string &)> && callback,const RefPtr<UINode> & sheetContentNode,std::function<RefPtr<UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<FrameNode> & targetNode,bool isStartByUIContext)4709 void OverlayManager::OnBindSheetInner(std::function<void(const std::string&)>&& callback,
4710     const RefPtr<UINode>& sheetContentNode, std::function<RefPtr<UINode>()>&& buildtitleNodeFunc,
4711     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4712     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4713     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4714     std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4715     std::function<void(const float)>&& onWidthDidChange,
4716     std::function<void(const float)>&& onTypeDidChange,
4717     std::function<void()>&& sheetSpringBack, const RefPtr<FrameNode>& targetNode, bool isStartByUIContext)
4718 {
4719     CHECK_NULL_VOID(sheetContentNode);
4720     auto titleBuilder = AceType::DynamicCast<FrameNode>(buildtitleNodeFunc());
4721     if (titleBuilder) {
4722         titleBuilder->GetRenderContext()->SetIsModalRootNode(true);
4723     }
4724 
4725     CHECK_NULL_VOID(targetNode);
4726     auto sheetNode = SheetView::CreateSheetPage(
4727         targetNode->GetId(), targetNode->GetTag(), sheetContentNode, titleBuilder, std::move(callback), sheetStyle);
4728     CHECK_NULL_VOID(sheetNode);
4729     SetSheetProperty(sheetNode, sheetStyle, std::move(onAppear), std::move(onDisappear),
4730         std::move(shouldDismiss), std::move(onWillDismiss),
4731         std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
4732         std::move(onDetentsDidChange), std::move(onWidthDidChange),
4733         std::move(onTypeDidChange), std::move(sheetSpringBack));
4734     SaveSheePageNode(sheetNode, sheetContentNode, targetNode, isStartByUIContext);
4735     auto maskNode = CreateSheetMask(sheetNode, targetNode, sheetStyle);
4736     CHECK_NULL_VOID(maskNode);
4737 
4738     auto sheetNodePattern = sheetNode->GetPattern<SheetPresentationPattern>();
4739     CHECK_NULL_VOID(sheetNodePattern);
4740     if (onWillAppear) {
4741         TAG_LOGI(AceLogTag::ACE_SHEET, "bindSheet lifecycle change to onWillAppear state.");
4742         onWillAppear();
4743     }
4744     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4745         sheetNodePattern->OnAppear();
4746     }
4747 
4748     // start transition animation
4749     auto sheetType = sheetNodePattern->GetSheetType();
4750     if (sheetType == SheetType::SHEET_POPUP) {
4751         PlayBubbleStyleSheetTransition(sheetNode, true);
4752     } else {
4753         PlaySheetTransition(sheetNode, true);
4754     }
4755 
4756     auto pageNode = AceType::DynamicCast<FrameNode>(maskNode->GetParent());
4757     CHECK_NULL_VOID(pageNode);
4758     //when sheet shows in page
4759     if (pageNode->GetTag() == V2::PAGE_ETS_TAG) {
4760         //set focus on sheet when page has more than one child
4761         auto focusView = pageNode->GetPattern<FocusView>();
4762         CHECK_NULL_VOID(focusView);
4763         auto focusHub = sheetNode->GetFocusHub();
4764         CHECK_NULL_VOID(focusHub);
4765         focusView->SetViewRootScope(focusHub);
4766     }
4767 }
4768 
SetSheetProperty(const RefPtr<FrameNode> & sheetPageNode,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack)4769 void OverlayManager::SetSheetProperty(
4770     const RefPtr<FrameNode>& sheetPageNode,
4771     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
4772     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
4773     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
4774     std::function<void(const float)>&& onHeightDidChange, std::function<void(const float)>&& onDetentsDidChange,
4775     std::function<void(const float)>&& onWidthDidChange,
4776     std::function<void(const float)>&& onTypeDidChange,
4777     std::function<void()>&& sheetSpringBack)
4778 {
4779     UpdateSheetRender(sheetPageNode, sheetStyle, true);
4780     auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4781     CHECK_NULL_VOID(sheetNodePattern);
4782     sheetNodePattern->UpdateOnAppear(std::move(onAppear));
4783     sheetNodePattern->UpdateOnDisappear(std::move(onDisappear));
4784     sheetNodePattern->UpdateShouldDismiss(std::move(shouldDismiss));
4785     sheetNodePattern->UpdateOnWillDismiss(std::move(onWillDismiss));
4786     sheetNodePattern->UpdateOnWillDisappear(std::move(onWillDisappear));
4787     sheetNodePattern->UpdateOnHeightDidChange(std::move(onHeightDidChange));
4788     sheetNodePattern->UpdateOnDetentsDidChange(std::move(onDetentsDidChange));
4789     sheetNodePattern->UpdateOnWidthDidChange(std::move(onWidthDidChange));
4790     sheetNodePattern->UpdateOnTypeDidChange(std::move(onTypeDidChange));
4791     sheetNodePattern->UpdateSheetSpringBack(std::move(sheetSpringBack));
4792 }
4793 
SaveSheePageNode(const RefPtr<FrameNode> & sheetPageNode,const RefPtr<UINode> & sheetContentNode,const RefPtr<FrameNode> & targetNode,bool isStartByUIContext)4794 void OverlayManager::SaveSheePageNode(
4795     const RefPtr<FrameNode>& sheetPageNode, const RefPtr<UINode>& sheetContentNode,
4796     const RefPtr<FrameNode>& targetNode, bool isStartByUIContext)
4797 {
4798     int32_t targetId = targetNode->GetId();
4799     auto root = AceType::DynamicCast<FrameNode>(rootNodeWeak_.Upgrade());
4800     CHECK_NULL_VOID(root);
4801     bool isValidTarget = CheckTargetIdIsValid(targetId);
4802     SheetKey sheetKey;
4803     if (isStartByUIContext) {
4804         sheetKey = SheetKey(isValidTarget, sheetContentNode->GetId(), targetId);
4805     } else {
4806         sheetKey = SheetKey(targetId);
4807     }
4808     auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
4809     CHECK_NULL_VOID(sheetNodePattern);
4810     sheetNodePattern->SetSheetKey(sheetKey);
4811     sheetMap_.emplace(sheetKey, WeakClaim(RawPtr(sheetPageNode)));
4812     modalStack_.push(WeakClaim(RawPtr(sheetPageNode)));
4813     modalList_.emplace_back(WeakClaim(RawPtr(sheetPageNode)));
4814     SaveLastModalNode();
4815     sheetNodePattern->SetOverlay(AceType::WeakClaim(this));
4816 }
4817 
CheckTargetIdIsValid(int32_t targetId)4818 bool OverlayManager::CheckTargetIdIsValid(int32_t targetId)
4819 {
4820     if (targetId < 0) {
4821         return false;
4822     }
4823     auto rootNode = rootNodeWeak_.Upgrade();
4824     CHECK_NULL_RETURN(rootNode, false);
4825     auto rootId = rootNode->GetId();
4826     return rootId != targetId;
4827 }
4828 
CreateSheetMask(const RefPtr<FrameNode> & sheetPageNode,const RefPtr<FrameNode> & targetNode,NG::SheetStyle & sheetStyle)4829 RefPtr<FrameNode> OverlayManager::CreateSheetMask(const RefPtr<FrameNode>& sheetPageNode,
4830     const RefPtr<FrameNode>& targetNode, NG::SheetStyle& sheetStyle)
4831 {
4832     // create maskColor node(sheetWrapper)
4833     auto maskNode = FrameNode::CreateFrameNode(V2::SHEET_WRAPPER_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
4834         AceType::MakeRefPtr<SheetWrapperPattern>());
4835     CHECK_NULL_RETURN(maskNode, nullptr);
4836     auto maskLayoutProps = maskNode->GetLayoutProperty();
4837     CHECK_NULL_RETURN(maskLayoutProps, nullptr);
4838     maskLayoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT);
4839     maskLayoutProps->UpdateAlignment(Alignment::TOP_LEFT);
4840     auto maskRenderContext = maskNode->GetRenderContext();
4841     CHECK_NULL_RETURN(maskRenderContext, nullptr);
4842     maskRenderContext->UpdateClipEdge(true);
4843     sheetPageNode->MountToParent(maskNode);
4844     InitSheetMask(maskNode, sheetPageNode, sheetStyle);
4845     auto rootNode = FindWindowScene(targetNode);
4846     CHECK_NULL_RETURN(rootNode, nullptr);
4847     MountToParentWithService(rootNode, maskNode);
4848     FireModalPageShow();
4849     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4850     auto pipeline = sheetPageNode->GetContext();
4851     CHECK_NULL_RETURN(pipeline, nullptr);
4852     pipeline->FlushUITasks();
4853     PlaySheetMaskTransition(maskNode, true);
4854     ComputeSheetOffset(sheetStyle, sheetPageNode);
4855     return maskNode;
4856 }
4857 
CreateSheetKey(const RefPtr<NG::FrameNode> & sheetContentNode,int32_t targetId,SheetKey & sheetKey)4858 bool OverlayManager::CreateSheetKey(const RefPtr<NG::FrameNode>& sheetContentNode, int32_t targetId,
4859     SheetKey& sheetKey)
4860 {
4861     CHECK_NULL_RETURN(sheetContentNode, false);
4862     bool isTargetIdValid = CheckTargetIdIsValid(targetId);
4863     if (!isTargetIdValid) {
4864         auto rootNode = rootNodeWeak_.Upgrade();
4865         CHECK_NULL_RETURN(rootNode, false);
4866         targetId = rootNode->GetId();
4867     }
4868     sheetKey = SheetKey(isTargetIdValid, sheetContentNode->GetId(), targetId);
4869     return true;
4870 }
4871 
UpdateSheetMask(const RefPtr<FrameNode> & maskNode,const RefPtr<FrameNode> & sheetNode,const SheetStyle & sheetStyle,bool isPartialUpdate)4872 void OverlayManager::UpdateSheetMask(const RefPtr<FrameNode>& maskNode,
4873     const RefPtr<FrameNode>& sheetNode, const SheetStyle& sheetStyle, bool isPartialUpdate)
4874 {
4875     auto maskRenderContext = maskNode->GetRenderContext();
4876     CHECK_NULL_VOID(maskRenderContext);
4877     auto pipeline = PipelineContext::GetCurrentContext();
4878     CHECK_NULL_VOID(pipeline);
4879     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
4880     CHECK_NULL_VOID(sheetTheme);
4881     auto sheetLayoutProps = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
4882     CHECK_NULL_VOID(sheetLayoutProps);
4883     maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMDEFAULT);
4884 
4885     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
4886         UpdateSheetMaskBackgroundColor(maskNode, maskRenderContext, sheetStyle);
4887     } else {
4888         if (sheetStyle.maskColor.has_value() || !isPartialUpdate) {
4889             maskRenderContext->UpdateBackgroundColor(sheetStyle.maskColor.value_or(sheetTheme->GetMaskColor()));
4890         }
4891         auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
4892         CHECK_NULL_VOID(eventConfirmHub);
4893 
4894         auto maskNodeId = maskNode->GetId();
4895         auto iter = sheetMaskClickEventMap_.find(maskNodeId);
4896         if (iter == sheetMaskClickEventMap_.end() &&
4897             sheetStyle.interactive.has_value() && !sheetStyle.interactive.value()) {
4898             auto sheetMaskClickEvent = AceType::MakeRefPtr<NG::ClickEvent>(
4899                 [weak = AceType::WeakClaim(AceType::RawPtr(sheetNode))](const GestureEvent& /* info */) {
4900                     auto sheet = weak.Upgrade();
4901                     CHECK_NULL_VOID(sheet);
4902                     auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4903                     CHECK_NULL_VOID(sheetPattern);
4904                     if (sheetPattern->IsDragging()) {
4905                         return;
4906                     }
4907                     sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::TOUCH_OUTSIDE);
4908                 });
4909             sheetMaskClickEventMap_.emplace(maskNodeId, sheetMaskClickEvent);
4910             eventConfirmHub->AddClickEvent(sheetMaskClickEvent, DISTANCE_THRESHOLD);
4911             return;
4912         }
4913 
4914         if ((!sheetStyle.interactive.has_value() && !isPartialUpdate &&
4915                 sheetNode->GetPattern<SheetPresentationPattern>()->GetSheetType() == SheetType::SHEET_POPUP) ||
4916             sheetStyle.interactive.value_or(false)) {
4917             maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(
4918                 HitTestMode::HTMTRANSPARENT);
4919             maskRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
4920             eventConfirmHub->RemoveClickEvent(iter->second);
4921             sheetMaskClickEventMap_.erase(maskNodeId);
4922         }
4923     }
4924 }
4925 
PlayBubbleStyleSheetTransition(RefPtr<FrameNode> sheetNode,bool isTransitionIn)4926 void OverlayManager::PlayBubbleStyleSheetTransition(RefPtr<FrameNode> sheetNode, bool isTransitionIn)
4927 {
4928     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4929     CHECK_NULL_VOID(sheetPattern);
4930     if (isTransitionIn) {
4931         sheetPattern->ResetToInvisible();
4932         sheetPattern->SetCurrentHeight(sheetHeight_);
4933         sheetPattern->StartOffsetEnteringAnimation();
4934         sheetPattern->FireOnHeightDidChange(sheetHeight_);
4935         sheetPattern->StartAlphaEnteringAnimation([sheetWK = WeakClaim(RawPtr(sheetNode))] {
4936             auto sheet = sheetWK.Upgrade();
4937             CHECK_NULL_VOID(sheet);
4938             auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
4939             CHECK_NULL_VOID(sheetPattern);
4940             sheetPattern->ProcessColumnRect();
4941             if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4942                 sheetPattern->OnAppear();
4943             }
4944         });
4945     } else {
4946         sheetPattern->StartOffsetExitingAnimation();
4947         sheetPattern->StartAlphaExitingAnimation(
4948             [rootWeak = rootNodeWeak_, sheetWK = WeakClaim(RawPtr(sheetNode)), id = Container::CurrentId(),
4949                     weakOverlayManager = WeakClaim(this)] {
4950                 ContainerScope scope(id);
4951                 auto context = PipelineContext::GetCurrentContext();
4952                 CHECK_NULL_VOID(context);
4953                 auto taskExecutor = context->GetTaskExecutor();
4954                 CHECK_NULL_VOID(taskExecutor);
4955                 // animation finish event should be posted to UI thread.
4956                 taskExecutor->PostTask(
4957                     [rootWeak, sheetWK, id, weakOverlayManager]() {
4958                         auto sheet = sheetWK.Upgrade();
4959                         auto overlayManager = weakOverlayManager.Upgrade();
4960                         CHECK_NULL_VOID(sheet && overlayManager);
4961 
4962                         ContainerScope scope(id);
4963                         if (!sheet->GetPattern<SheetPresentationPattern>()->IsExecuteOnDisappear()) {
4964                             sheet->GetPattern<SheetPresentationPattern>()->OnDisappear();
4965                         }
4966                         auto root = overlayManager->FindWindowScene(sheet);
4967                         CHECK_NULL_VOID(root);
4968                         auto sheetParent = DynamicCast<FrameNode>(sheet->GetParent());
4969                         CHECK_NULL_VOID(sheetParent);
4970                         overlayManager->FireAutoSave(sheet);
4971                         overlayManager->RemoveChildWithService(root, sheetParent);
4972                         root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4973                     },
4974                     TaskExecutor::TaskType::UI, "ArkUIOverlaySheetExitingAnimation");
4975             });
4976     }
4977 }
4978 
PlaySheetMaskTransition(RefPtr<FrameNode> maskNode,bool isTransitionIn)4979 void OverlayManager::PlaySheetMaskTransition(RefPtr<FrameNode> maskNode, bool isTransitionIn)
4980 {
4981     AnimationOption option;
4982     const RefPtr<InterpolatingSpring> curve =
4983         AceType::MakeRefPtr<InterpolatingSpring>(0.0f, CURVE_MASS, CURVE_STIFFNESS, CURVE_DAMPING);
4984     option.SetCurve(curve);
4985     option.SetFillMode(FillMode::FORWARDS);
4986     auto context = maskNode->GetRenderContext();
4987     CHECK_NULL_VOID(context);
4988     auto sheetNode = AceType::DynamicCast<FrameNode>(maskNode->GetChildAtIndex(0));
4989     CHECK_NULL_VOID(sheetNode);
4990     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
4991     CHECK_NULL_VOID(sheetPattern);
4992     auto backgroundColor = sheetPattern->GetMaskBackgroundColor();
4993     if (isTransitionIn) {
4994         context->UpdateBackgroundColor(backgroundColor.ChangeOpacity(0.0f));
4995         AnimationUtils::Animate(
4996             option,
4997             [context, backgroundColor]() {
4998                 CHECK_NULL_VOID(context);
4999                 context->UpdateBackgroundColor(backgroundColor);
5000             });
5001     } else {
5002         auto iter = sheetMaskClickEventMap_.find(maskNode->GetId());
5003         if (iter != sheetMaskClickEventMap_.end()) {
5004             auto eventConfirmHub = maskNode->GetOrCreateGestureEventHub();
5005             CHECK_NULL_VOID(eventConfirmHub);
5006             eventConfirmHub->RemoveClickEvent(iter->second);
5007         }
5008         maskNode->GetEventHub<EventHub>()->GetOrCreateGestureEventHub()->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
5009         context->UpdateBackgroundColor(backgroundColor);
5010         AnimationUtils::Animate(
5011             option,
5012             [context, backgroundColor]() {
5013                 CHECK_NULL_VOID(context);
5014                 context->UpdateBackgroundColor(backgroundColor.ChangeOpacity(0.0f));
5015             });
5016     }
5017 }
5018 
SetSheetBackgroundColor(const RefPtr<FrameNode> & sheetNode,const RefPtr<SheetTheme> & sheetTheme,const NG::SheetStyle & sheetStyle,bool isPartialUpdate)5019 void OverlayManager::SetSheetBackgroundColor(const RefPtr<FrameNode>& sheetNode, const RefPtr<SheetTheme>& sheetTheme,
5020     const NG::SheetStyle& sheetStyle, bool isPartialUpdate)
5021 {
5022     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5023         if (sheetStyle.backgroundColor.has_value()) {
5024             sheetNode->GetRenderContext()->UpdateBackgroundColor(sheetStyle.backgroundColor.value());
5025         }
5026     } else if (sheetStyle.backgroundColor.has_value() || !isPartialUpdate) {
5027         sheetNode->GetRenderContext()->UpdateBackgroundColor(sheetStyle.backgroundColor.value_or(
5028             sheetTheme->GetSheetBackgoundColor()));
5029     }
5030 }
5031 
SetSheetBackgroundBlurStyle(const RefPtr<FrameNode> & sheetNode,const BlurStyleOption & bgBlurStyle)5032 void OverlayManager::SetSheetBackgroundBlurStyle(const RefPtr<FrameNode>& sheetNode, const BlurStyleOption& bgBlurStyle)
5033 {
5034     auto renderContext = sheetNode->GetRenderContext();
5035     CHECK_NULL_VOID(renderContext);
5036 
5037     if (renderContext->GetBackgroundEffect().has_value()) {
5038         renderContext->UpdateBackgroundEffect(std::nullopt);
5039     }
5040     renderContext->UpdateBackBlurStyle(bgBlurStyle);
5041     if (renderContext->GetBackBlurRadius().has_value()) {
5042         renderContext->UpdateBackBlurRadius(Dimension());
5043     }
5044 }
5045 
CheckTopModalNode(const RefPtr<FrameNode> & topModalNode,int32_t targetId)5046 bool OverlayManager::CheckTopModalNode(const RefPtr<FrameNode>& topModalNode, int32_t targetId)
5047 {
5048     if (topModalNode->GetTag() != V2::SHEET_PAGE_TAG && topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
5049         return false;
5050     }
5051     if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG ||
5052         topModalNode->GetPattern<ModalPresentationPattern>()->GetTargetId() != targetId) {
5053         DeleteModal(targetId);
5054         return false;
5055     }
5056     return true;
5057 }
5058 
ComputeSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5059 void OverlayManager::ComputeSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5060 {
5061     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5062     CHECK_NULL_VOID(sheetPattern);
5063     auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5064     auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx();
5065     auto geometryNode = sheetNode->GetGeometryNode();
5066     CHECK_NULL_VOID(geometryNode);
5067     auto sheetHeight = geometryNode->GetFrameSize().Height();
5068 
5069     auto sheetType = sheetPattern->GetSheetType();
5070     switch (sheetType) {
5071         case SheetType::SHEET_BOTTOMLANDSPACE:
5072             if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5073                 sheetHeight_ = largeHeight;
5074                 break;
5075             }
5076         case SheetType::SHEET_BOTTOM:
5077         case SheetType::SHEET_BOTTOM_FREE_WINDOW:
5078             if (!sheetStyle.detents.empty()) {
5079                 ComputeDetentsSheetOffset(sheetStyle, sheetNode);
5080             } else {
5081                 ComputeSingleGearSheetOffset(sheetStyle, sheetNode);
5082             }
5083             break;
5084         case SheetType::SHEET_CENTER:
5085             sheetHeight_ = (sheetHeight + sheetMaxHeight) / SHEET_HALF_SIZE;
5086             break;
5087         case SheetType::SHEET_POPUP:
5088             sheetHeight_ = sheetMaxHeight;
5089             break;
5090         default:
5091             break;
5092     }
5093 }
5094 
5095 // if device is phone, fold status, screen is in landscape mode, preferType is BOTTOM
CheckDeviceInLandscape(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode,float & sheetTopSafeArea)5096 void OverlayManager::CheckDeviceInLandscape(
5097     NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode, float& sheetTopSafeArea)
5098 {
5099     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5100     CHECK_NULL_VOID(sheetPattern);
5101     if (sheetStyle.sheetType.has_value() && sheetStyle.sheetType.value() == SheetType::SHEET_BOTTOM &&
5102         sheetPattern->IsPhoneInLandScape()) {
5103         sheetTopSafeArea = 0.0f;
5104     }
5105 }
5106 
ComputeSingleGearSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5107 void OverlayManager::ComputeSingleGearSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5108 {
5109     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5110     CHECK_NULL_VOID(sheetPattern);
5111     auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5112     auto sheetTopSafeArea = sheetPattern->GetSheetTopSafeArea();
5113 
5114     CheckDeviceInLandscape(sheetStyle, sheetNode, sheetTopSafeArea);
5115     auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx() - sheetTopSafeArea;
5116     if (sheetStyle.sheetMode.has_value()) {
5117         if (sheetStyle.sheetMode == SheetMode::MEDIUM) {
5118             sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE;
5119             if (!Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
5120                 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE_PRE;
5121             }
5122         } else if (sheetStyle.sheetMode == SheetMode::LARGE) {
5123             sheetHeight_ = largeHeight;
5124         } else if (sheetStyle.sheetMode == SheetMode::AUTO) {
5125             sheetHeight_ = sheetPattern->GetFitContentHeight();
5126             if (GreatNotEqual(sheetHeight_, largeHeight)) {
5127                 sheetHeight_ = largeHeight;
5128             }
5129         }
5130     } else {
5131         float height = 0.0f;
5132         if (sheetStyle.height->Unit() == DimensionUnit::PERCENT) {
5133             height = sheetStyle.height->ConvertToPxWithSize(sheetMaxHeight - sheetTopSafeArea);
5134         } else {
5135             height = sheetStyle.height->ConvertToPx();
5136         }
5137         if (height > largeHeight) {
5138             sheetHeight_ = largeHeight;
5139         } else if (height < 0) {
5140             sheetHeight_ = largeHeight;
5141         } else {
5142             sheetHeight_ = height;
5143         }
5144     }
5145 }
5146 
ComputeDetentsSheetOffset(NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)5147 void OverlayManager::ComputeDetentsSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
5148 {
5149     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
5150     CHECK_NULL_VOID(sheetPattern);
5151     auto sheetMaxHeight = sheetPattern->GetPageHeightWithoutOffset();
5152     auto sheetTopSafeArea = sheetPattern->GetSheetTopSafeArea();
5153     CheckDeviceInLandscape(sheetStyle, sheetNode, sheetTopSafeArea);
5154     auto largeHeight = sheetMaxHeight - SHEET_BLANK_MINI_HEIGHT.ConvertToPx() - sheetTopSafeArea;
5155     auto selection = sheetStyle.detents[sheetPattern->GetDetentsIndex()];
5156     if (selection.sheetMode.has_value()) {
5157         if (selection.sheetMode == SheetMode::MEDIUM) {
5158             sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE;
5159             if (!Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
5160                 sheetHeight_ = sheetMaxHeight * MEDIUM_SIZE_PRE;
5161             }
5162         } else if (selection.sheetMode == SheetMode::LARGE) {
5163             sheetHeight_ = largeHeight;
5164         } else if (selection.sheetMode == SheetMode::AUTO) {
5165             sheetHeight_ = sheetPattern->GetFitContentHeight();
5166             if (GreatNotEqual(sheetHeight_, largeHeight)) {
5167                 sheetHeight_ = largeHeight;
5168             }
5169         }
5170     } else {
5171         float height = 0.0f;
5172         if (selection.height->Unit() == DimensionUnit::PERCENT) {
5173             height = selection.height->ConvertToPxWithSize(sheetMaxHeight - sheetTopSafeArea);
5174         } else {
5175             height = selection.height->ConvertToPx();
5176         }
5177         if (height > largeHeight) {
5178             sheetHeight_ = largeHeight;
5179         } else if (height < 0) {
5180             sheetHeight_ = largeHeight;
5181         } else {
5182             sheetHeight_ = height;
5183         }
5184     }
5185 }
5186 
CleanSheet(const RefPtr<FrameNode> & sheetNode,const SheetKey & sheetKey)5187 void OverlayManager::CleanSheet(const RefPtr<FrameNode>& sheetNode, const SheetKey& sheetKey)
5188 {
5189     if (modalStack_.empty()) {
5190         return;
5191     }
5192     auto iter = sheetMap_.find(sheetKey);
5193     if (sheetMap_.empty() || iter == sheetMap_.end()) {
5194         DeleteModal(sheetKey.targetId, false);
5195         return;
5196     }
5197     auto mapSheetNode = iter->second.Upgrade();
5198     CHECK_NULL_VOID(mapSheetNode);
5199     if (mapSheetNode->GetTag() != V2::SHEET_PAGE_TAG) {
5200         return;
5201     }
5202     if (mapSheetNode->GetPattern<SheetPresentationPattern>()->GetTargetId() != sheetKey.targetId) {
5203         return;
5204     }
5205     ModalPageLostFocus(mapSheetNode);
5206     sheetMap_.erase(sheetKey);
5207     CleanViewContextMap(Container::CurrentId(), sheetKey.contentId);
5208     RemoveSheetNode(sheetNode);
5209     FireModalPageHide();
5210     SaveLastModalNode();
5211 }
5212 
DestroySheet(const RefPtr<FrameNode> & sheetNode,const SheetKey & sheetKey)5213 void OverlayManager::DestroySheet(const RefPtr<FrameNode>& sheetNode, const SheetKey& sheetKey)
5214 {
5215     auto rootNode = FindWindowScene(sheetNode);
5216     CHECK_NULL_VOID(rootNode);
5217     auto root = DynamicCast<FrameNode>(rootNode);
5218     sheetNode->GetPattern<SheetPresentationPattern>()->OnDisappear();
5219     auto sheetParent = DynamicCast<FrameNode>(sheetNode->GetParent());
5220     CHECK_NULL_VOID(sheetParent);
5221     RemoveChildWithService(root, sheetParent);
5222     root->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5223 }
5224 
DeleteModal(int32_t targetId,bool needOnWillDisappear)5225 void OverlayManager::DeleteModal(int32_t targetId, bool needOnWillDisappear)
5226 {
5227     bool isDelete = false;
5228     bool isModal = true;
5229     for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
5230         auto modalNode = (*modal).Upgrade();
5231         if (!modalNode) {
5232             continue;
5233         }
5234         int32_t currentTargetId = -1;
5235         if (modalNode->GetTag() == V2::MODAL_PAGE_TAG) {
5236             isModal = true;
5237             currentTargetId = modalNode->GetPattern<ModalPresentationPattern>()->GetTargetId();
5238         } else if (modalNode->GetTag() == V2::SHEET_PAGE_TAG) {
5239             isModal = false;
5240             currentTargetId = modalNode->GetPattern<SheetPresentationPattern>()->GetTargetId();
5241         } else {
5242             return;
5243         }
5244         if (currentTargetId == targetId) {
5245             isDelete = true;
5246             modalList_.erase(modal);
5247             DeleteModalNode(targetId, modalNode, isModal, needOnWillDisappear);
5248             break;
5249         }
5250     }
5251     if (isDelete) {
5252         while (!modalStack_.empty()) {
5253             modalStack_.pop();
5254         }
5255         for (auto modal = modalList_.begin(); modal != modalList_.end(); modal++) {
5256             modalStack_.push(*modal);
5257         }
5258         SaveLastModalNode();
5259     }
5260 }
5261 
DeleteModalNode(int32_t targetId,RefPtr<FrameNode> & modalNode,bool isModal,bool needOnWillDisappear)5262 void OverlayManager::DeleteModalNode(
5263     int32_t targetId, RefPtr<FrameNode>& modalNode, bool isModal, bool needOnWillDisappear)
5264 {
5265     auto rootNode = FindWindowScene(modalNode);
5266     CHECK_NULL_VOID(rootNode);
5267     if (isModal) {
5268         if (needOnWillDisappear) {
5269             modalNode->GetPattern<ModalPresentationPattern>()->OnWillDisappear();
5270         }
5271         modalNode->GetPattern<ModalPresentationPattern>()->OnDisappear();
5272         modalNode->GetPattern<ModalPresentationPattern>()->FireCallback("false");
5273         // Fire hidden event of navdestination on the disappeared modal
5274         FireNavigationStateChange(false, modalNode);
5275         RemoveChildWithService(rootNode, modalNode);
5276     } else {
5277         auto sheetPattern = modalNode->GetPattern<SheetPresentationPattern>();
5278         CHECK_NULL_VOID(sheetPattern);
5279         if (needOnWillDisappear) {
5280             sheetPattern->OnWillDisappear();
5281         }
5282         sheetPattern->OnDisappear();
5283         sheetPattern->FireCallback("false");
5284         sheetMap_.erase(sheetPattern->GetSheetKey());
5285         auto sheetParent = DynamicCast<FrameNode>(modalNode->GetParent());
5286         CHECK_NULL_VOID(sheetParent);
5287         RemoveChildWithService(rootNode, sheetParent);
5288     }
5289     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5290 }
5291 
PopTopModalNode()5292 void OverlayManager::PopTopModalNode()
5293 {
5294     if (!modalStack_.empty()) {
5295         modalStack_.pop();
5296     }
5297     if (!modalList_.empty()) {
5298         modalList_.pop_back();
5299     }
5300 }
5301 
GetSheetMask(const RefPtr<FrameNode> & sheetNode)5302 RefPtr<FrameNode> OverlayManager::GetSheetMask(const RefPtr<FrameNode>& sheetNode)
5303 {
5304     // get bindsheet masknode
5305     CHECK_NULL_RETURN(sheetNode, nullptr);
5306     auto sheetParent = sheetNode->GetParent();
5307     CHECK_NULL_RETURN(sheetParent, nullptr);
5308     return DynamicCast<FrameNode>(sheetParent);
5309 }
5310 
SetCustomKeyboardOption(bool supportAvoidance)5311 void OverlayManager::SetCustomKeyboardOption(bool supportAvoidance)
5312 {
5313     auto pipeline = PipelineContext::GetMainPipelineContext();
5314     CHECK_NULL_VOID(pipeline);
5315     keyboardAvoidance_ = supportAvoidance;
5316 }
5317 
PlayKeyboardTransition(const RefPtr<FrameNode> & customKeyboard,bool isTransitionIn)5318 void OverlayManager::PlayKeyboardTransition(const RefPtr<FrameNode>& customKeyboard, bool isTransitionIn)
5319 {
5320     CHECK_NULL_VOID(customKeyboard);
5321     AnimationOption option;
5322     if (isTransitionIn) {
5323         option.SetCurve(SHOW_CUSTOM_KEYBOARD_ANIMATION_CURVE);
5324     } else {
5325         option.SetCurve(HIDE_CUSTOM_KEYBOARD_ANIMATION_CURVE);
5326     }
5327     option.SetFillMode(FillMode::FORWARDS);
5328     auto context = customKeyboard->GetRenderContext();
5329     CHECK_NULL_VOID(context);
5330     auto keyboardOffsetInfo = CalcCustomKeyboardOffset(customKeyboard);
5331     if (isTransitionIn) {
5332         context->OnTransformTranslateUpdate({ 0.0f, keyboardOffsetInfo.inAniStartOffset, 0.0f });
5333         AnimationUtils::Animate(option, [context, finalOffset = keyboardOffsetInfo.finalOffset]() {
5334             if (context) {
5335                 context->OnTransformTranslateUpdate({ 0.0f, finalOffset, 0.0f });
5336             }
5337         });
5338     } else {
5339         context->UpdateOpacity(1.0);
5340         option.SetOnFinishEvent([customKeyboard] {
5341             auto parent = customKeyboard->GetParent();
5342             CHECK_NULL_VOID(parent);
5343             parent->RemoveChild(customKeyboard);
5344         });
5345         AnimationUtils::Animate(
5346             option,
5347             [context, outAniEndOffset = keyboardOffsetInfo.outAniEndOffset]() {
5348                 if (context) {
5349                     context->OnTransformTranslateUpdate({ 0.0f, outAniEndOffset, 0.0f });
5350                 }
5351             },
5352             option.GetOnFinishEvent());
5353     }
5354 }
5355 
UpdateCustomKeyboardPosition()5356 void OverlayManager::UpdateCustomKeyboardPosition()
5357 {
5358     for (auto iter = customKeyboardMap_.begin(); iter != customKeyboardMap_.end(); iter++) {
5359         auto customKeyboardNode = iter->second;
5360         if (!customKeyboardNode) {
5361             continue;
5362         }
5363         auto parent = customKeyboardNode->GetParent();
5364         if (!parent) {
5365             continue;
5366         }
5367         auto renderContext = customKeyboardNode->GetRenderContext();
5368         CHECK_NULL_VOID(renderContext);
5369         auto keyboardOffsetInfo = CalcCustomKeyboardOffset(customKeyboardNode);
5370         renderContext->OnTransformTranslateUpdate({ 0.0f, keyboardOffsetInfo.finalOffset, 0.0f });
5371     }
5372 }
5373 
CalcCustomKeyboardOffset(const RefPtr<FrameNode> & customKeyboard)5374 CustomKeyboardOffsetInfo OverlayManager::CalcCustomKeyboardOffset(const RefPtr<FrameNode>& customKeyboard)
5375 {
5376     CustomKeyboardOffsetInfo keyboardOffsetInfo;
5377     CHECK_NULL_RETURN(customKeyboard, keyboardOffsetInfo);
5378     auto pipeline = customKeyboard->GetContext();
5379     CHECK_NULL_RETURN(pipeline, keyboardOffsetInfo);
5380     auto pageNode = pipeline->GetStageManager()->GetLastPage();
5381     CHECK_NULL_RETURN(pageNode, keyboardOffsetInfo);
5382     auto pageHeight = pageNode->GetGeometryNode()->GetFrameSize().Height();
5383     auto keyboardHeight = customKeyboard->GetGeometryNode()->GetFrameSize().Height();
5384     auto rootNode = rootNodeWeak_.Upgrade();
5385     CHECK_NULL_RETURN(rootNode, keyboardOffsetInfo);
5386     auto finalOffset = 0.0f;
5387     if (rootNode->GetTag() == V2::STACK_ETS_TAG) {
5388         auto rootNd = AceType::DynamicCast<FrameNode>(rootNode);
5389         pageHeight = rootNd->GetGeometryNode()->GetFrameSize().Height();
5390         finalOffset = (pageHeight - keyboardHeight) - (pageHeight - keyboardHeight) / NUM_FLOAT_2;
5391     }
5392     keyboardOffsetInfo.finalOffset = finalOffset;
5393     keyboardOffsetInfo.inAniStartOffset = pageHeight;
5394     keyboardOffsetInfo.outAniEndOffset = finalOffset + keyboardHeight;
5395     return keyboardOffsetInfo;
5396 }
5397 
BindKeyboard(const std::function<void ()> & keyboardBuilder,int32_t targetId)5398 void OverlayManager::BindKeyboard(const std::function<void()>& keyboardBuilder, int32_t targetId)
5399 {
5400     if (customKeyboardMap_.find(targetId) != customKeyboardMap_.end()) {
5401         return;
5402     }
5403     auto rootNode = rootNodeWeak_.Upgrade();
5404     CHECK_NULL_VOID(rootNode);
5405     auto customKeyboard = KeyboardView::CreateKeyboard(targetId, keyboardBuilder);
5406     if (!customKeyboard) {
5407         return;
5408     }
5409     ACE_LAYOUT_SCOPED_TRACE("BindKeyboard[targetId:%d]", targetId);
5410     customKeyboard->MountToParent(rootNode);
5411     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5412     customKeyboardMap_[targetId] = customKeyboard;
5413     auto pipeline = PipelineContext::GetCurrentContext();
5414     CHECK_NULL_VOID(pipeline);
5415     pipeline->AddAfterLayoutTask([weak = WeakClaim(this), customKeyboard] {
5416         auto overlayManager = weak.Upgrade();
5417         CHECK_NULL_VOID(overlayManager);
5418         overlayManager->PlayKeyboardTransition(customKeyboard, true);
5419     });
5420 }
5421 
BindKeyboardWithNode(const RefPtr<UINode> & keyboard,int32_t targetId)5422 void OverlayManager::BindKeyboardWithNode(const RefPtr<UINode>& keyboard, int32_t targetId)
5423 {
5424     if (customKeyboardMap_.find(targetId) != customKeyboardMap_.end()) {
5425         return;
5426     }
5427     ACE_LAYOUT_SCOPED_TRACE("BindKeyboardWithNode[targetId:%d]", targetId);
5428     auto rootNode = rootNodeWeak_.Upgrade();
5429     CHECK_NULL_VOID(rootNode);
5430     auto customKeyboard = KeyboardView::CreateKeyboardWithNode(targetId, keyboard);
5431     if (!customKeyboard) {
5432         return;
5433     }
5434     customKeyboard->MountToParent(rootNode);
5435     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
5436     customKeyboardMap_[targetId] = customKeyboard;
5437     PlayKeyboardTransition(customKeyboard, true);
5438 }
5439 
CloseKeyboard(int32_t targetId)5440 void OverlayManager::CloseKeyboard(int32_t targetId)
5441 {
5442     auto it = customKeyboardMap_.find(targetId);
5443     if (it == customKeyboardMap_.end()) {
5444         return;
5445     }
5446     ACE_LAYOUT_SCOPED_TRACE("CloseKeyboard[targetId:%d]", targetId);
5447     auto customKeyboard = it->second;
5448     CHECK_NULL_VOID(customKeyboard);
5449     auto pipeline = customKeyboard->GetContext();
5450     CHECK_NULL_VOID(pipeline);
5451     auto pattern = customKeyboard->GetPattern<KeyboardPattern>();
5452     CHECK_NULL_VOID(pattern);
5453     customKeyboardMap_.erase(pattern->GetTargetId());
5454     PlayKeyboardTransition(customKeyboard, false);
5455     Rect keyboardRect = Rect(0.0f, 0.0f, 0.0f, 0.0f);
5456     pipeline->OnVirtualKeyboardAreaChange(keyboardRect);
5457 }
5458 
AvoidCustomKeyboard(int32_t targetId,float safeHeight)5459 void OverlayManager::AvoidCustomKeyboard(int32_t targetId, float safeHeight)
5460 {
5461     auto it = customKeyboardMap_.find(targetId);
5462     if (it == customKeyboardMap_.end()) {
5463         return;
5464     }
5465     auto customKeyboard = it->second;
5466     CHECK_NULL_VOID(customKeyboard);
5467     auto pattern = customKeyboard->GetPattern<KeyboardPattern>();
5468     CHECK_NULL_VOID(pattern);
5469     pattern->SetKeyboardSafeHeight(safeHeight);
5470     pattern->SetKeyboardAreaChange(keyboardAvoidance_);
5471     pattern->SetKeyboardOption(keyboardAvoidance_);
5472 }
5473 
5474 // This function will be used in SceneBoard Thread only.
5475 // if need to show the pop-up component,
5476 //   it expects to receive the target component bound by the pop-up component to find the windowScene component.
5477 // if need to hide the pop-up component,
5478 //   it expects to receive the the pop-up component to return the parent component.
5479 //   And the parent component will be the windowScene component exactly.
FindWindowScene(RefPtr<FrameNode> targetNode)5480 RefPtr<UINode> OverlayManager::FindWindowScene(RefPtr<FrameNode> targetNode)
5481 {
5482     auto container = Container::Current();
5483     if (!container || !container->IsScenceBoardWindow() || isAttachToCustomNode_) {
5484         return rootNodeWeak_.Upgrade();
5485     }
5486     CHECK_NULL_RETURN(targetNode, nullptr);
5487     auto parent = targetNode->GetParent();
5488     while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
5489         parent = parent->GetParent();
5490     }
5491     CHECK_NULL_RETURN(parent, nullptr);
5492     windowSceneSet_.insert(parent);
5493     return parent;
5494 }
5495 
MountFilterToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene)5496 void OverlayManager::MountFilterToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene)
5497 {
5498     CHECK_NULL_VOID(windowScene);
5499     columnNode->MountToParent(windowScene);
5500     columnNode->OnMountToParentDone();
5501     windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5502     filterColumnNodeWeak_ = columnNode;
5503     hasFilter_ = true;
5504 }
5505 
5506 /**
5507  * Mount pixelMap to wndow scene for lifting or for drag moving.
5508  * When isDragPixelMap is true, the pixelMap is saved by dragPixmapColumnNodeWeak_ used for moving with drag finger or
5509  * mouse, etc.
5510  * When isDragPixelMap is false, the pixelMap is saved by pixmapColumnNodeWeak_ used for lifting.
5511  */
MountPixelMapToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene,bool isDragPixelMap)5512 void OverlayManager::MountPixelMapToWindowScene(
5513     const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene, bool isDragPixelMap)
5514 {
5515     CHECK_NULL_VOID(windowScene);
5516     columnNode->MountToParent(windowScene);
5517     columnNode->OnMountToParentDone();
5518     windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5519     if (isDragPixelMap) {
5520         dragPixmapColumnNodeWeak_ = columnNode;
5521         hasDragPixelMap_ = true;
5522     } else {
5523         pixmapColumnNodeWeak_ = columnNode;
5524         hasPixelMap_ = true;
5525     }
5526 }
5527 
MountEventToWindowScene(const RefPtr<FrameNode> & columnNode,const RefPtr<UINode> & windowScene)5528 void OverlayManager::MountEventToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene)
5529 {
5530     CHECK_NULL_VOID(windowScene);
5531     columnNode->MountToParent(windowScene);
5532     columnNode->OnMountToParentDone();
5533     eventColumnNodeWeak_ = columnNode;
5534     hasEvent_ = true;
5535 }
5536 
5537 /**
5538  * Mount pixelMap to root node for lifting or for drag moving.
5539  * When isDragPixelMap is true, the pixelMap is saved by dragPixmapColumnNodeWeak_ used for moving with drag finger or
5540  * mouse, etc.
5541  * When isDragPixelMap is false, the pixelMap is saved by pixmapColumnNodeWeak_ used for lifting.
5542  */
MountPixelMapToRootNode(const RefPtr<FrameNode> & columnNode,bool isDragPixelMap)5543 void OverlayManager::MountPixelMapToRootNode(const RefPtr<FrameNode>& columnNode, bool isDragPixelMap)
5544 {
5545     auto rootNode = rootNodeWeak_.Upgrade();
5546     CHECK_NULL_VOID(rootNode);
5547     columnNode->MountToParent(rootNode);
5548     columnNode->OnMountToParentDone();
5549     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5550     if (isDragPixelMap) {
5551         dragPixmapColumnNodeWeak_ = columnNode;
5552         hasDragPixelMap_ = true;
5553     } else {
5554         pixmapColumnNodeWeak_ = columnNode;
5555         hasPixelMap_ = true;
5556     }
5557 }
5558 
MountEventToRootNode(const RefPtr<FrameNode> & columnNode)5559 void OverlayManager::MountEventToRootNode(const RefPtr<FrameNode>& columnNode)
5560 {
5561     auto rootNode = rootNodeWeak_.Upgrade();
5562     CHECK_NULL_VOID(rootNode);
5563     columnNode->MountToParent(rootNode, EVENT_COLUMN_SLOT);
5564     columnNode->OnMountToParentDone();
5565     eventColumnNodeWeak_ = columnNode;
5566     hasEvent_ = true;
5567 }
5568 
RemovePixelMap()5569 void OverlayManager::RemovePixelMap()
5570 {
5571     if (!hasPixelMap_) {
5572         return;
5573     }
5574     auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5575     if (!columnNode) {
5576         hasPixelMap_ = false;
5577         isOnAnimation_ = false;
5578         return;
5579     }
5580     auto rootNode = columnNode->GetParent();
5581     CHECK_NULL_VOID(rootNode);
5582     rootNode->RemoveChild(columnNode);
5583     rootNode->RebuildRenderContextTree();
5584     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5585     hasPixelMap_ = false;
5586     isOnAnimation_ = false;
5587 }
5588 
RemovePixelMapAnimation(bool startDrag,double x,double y,bool isSubwindowOverlay)5589 void OverlayManager::RemovePixelMapAnimation(bool startDrag, double x, double y, bool isSubwindowOverlay)
5590 {
5591     if (isOnAnimation_ || !hasPixelMap_) {
5592         return;
5593     }
5594     if (startDrag) {
5595         if (!isSubwindowOverlay) {
5596             RemovePixelMap();
5597         }
5598         return;
5599     }
5600     auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5601     if (!columnNode) {
5602         RemoveEventColumn();
5603         hasPixelMap_ = false;
5604         return;
5605     }
5606     auto imageNode = AceType::DynamicCast<FrameNode>(columnNode->GetFirstChild());
5607     CHECK_NULL_VOID(imageNode);
5608     auto imageContext = imageNode->GetRenderContext();
5609     CHECK_NULL_VOID(imageContext);
5610     auto hub = columnNode->GetOrCreateGestureEventHub();
5611     CHECK_NULL_VOID(hub);
5612     auto frameNode = hub->GetFrameNode();
5613     CHECK_NULL_VOID(frameNode);
5614     RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
5615     CHECK_NULL_VOID(pixelMap);
5616     float scale = PIXELMAP_DRAG_SCALE;
5617     UpdatePixelMapScale(scale);
5618     int32_t width = pixelMap->GetWidth();
5619     int32_t height = pixelMap->GetHeight();
5620 
5621     auto shadow = imageContext->GetBackShadow();
5622     if (!shadow.has_value()) {
5623         shadow = Shadow::CreateShadow(ShadowStyle::None);
5624     }
5625     imageContext->UpdateBackShadow(shadow.value());
5626     AnimationOption option;
5627     option.SetCurve(Curves::SHARP);
5628     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
5629     AnimationUtils::Animate(option, [imageContext, shadow]() mutable {
5630         if (imageContext) {
5631             auto color = shadow->GetColor();
5632             auto newColor = Color::FromARGB(1, color.GetRed(), color.GetGreen(), color.GetBlue());
5633             shadow->SetColor(newColor);
5634             imageContext->UpdateBackShadow(shadow.value());
5635             BorderRadiusProperty borderRadius;
5636             borderRadius.SetRadius(0.0_vp);
5637             imageContext->UpdateBorderRadius(borderRadius);
5638         }
5639     });
5640 
5641     auto pipelineContext = PipelineContext::GetCurrentContext();
5642     CHECK_NULL_VOID(pipelineContext);
5643     auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
5644     CHECK_NULL_VOID(menuTheme);
5645     auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
5646     auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
5647 
5648     AnimationOption scaleOption;
5649     auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(springMotionResponse, springMotionDampingFraction);
5650     scaleOption.SetCurve(motion);
5651 
5652     DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_STARTED);
5653     scaleOption.SetOnFinishEvent([weak = WeakClaim(this), isSubwindowOverlay] {
5654         auto pipeline = PipelineContext::GetCurrentContext();
5655         CHECK_NULL_VOID(pipeline);
5656         auto dragDropManager = pipeline->GetDragDropManager();
5657         CHECK_NULL_VOID(dragDropManager);
5658         DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LANDING_FINISHED);
5659         if (!dragDropManager->IsNeedDisplayInSubwindow() && !isSubwindowOverlay) {
5660             InteractionInterface::GetInstance()->SetDragWindowVisible(true);
5661         }
5662         auto overlayManager = weak.Upgrade();
5663         CHECK_NULL_VOID(overlayManager);
5664         if (overlayManager->hasEvent_) {
5665             overlayManager->RemoveEventColumn();
5666         }
5667         overlayManager->RemovePixelMap();
5668     });
5669 
5670     auto coordinateX = imageNode->GetOffsetRelativeToWindow().GetX() - frameNode->GetOffsetRelativeToWindow().GetX();
5671     auto coordinateY = imageNode->GetOffsetRelativeToWindow().GetY() - frameNode->GetOffsetRelativeToWindow().GetY();
5672     AnimationUtils::Animate(
5673         scaleOption,
5674         [imageContext, startDrag, x, y, width, height, scale, coordinateX, coordinateY]() {
5675             if (startDrag) {
5676                 imageContext->UpdatePosition(OffsetT<Dimension>(
5677                     Dimension(x - (x - coordinateX) * scale +
5678                               PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE * width * (scale - PIXELMAP_DRAG_SCALE)),
5679                     Dimension(y - (y - coordinateY) * scale +
5680                               PIXELMAP_ANIMATION_DEFAULT_LIMIT_SCALE * height * (scale - PIXELMAP_DRAG_SCALE))));
5681                 imageContext->UpdateTransformScale({ scale, scale });
5682                 imageContext->OnModifyDone();
5683             } else {
5684                 imageContext->UpdateTransformScale(VectorF(1.0f, 1.0f));
5685             }
5686         },
5687         scaleOption.GetOnFinishEvent());
5688     isOnAnimation_ = true;
5689 }
5690 
RemoveDragPixelMap()5691 void OverlayManager::RemoveDragPixelMap()
5692 {
5693     TAG_LOGI(AceLogTag::ACE_DRAG, "remove drag pixelMap enter");
5694     if (!hasDragPixelMap_) {
5695         return;
5696     }
5697     auto columnNode = dragPixmapColumnNodeWeak_.Upgrade();
5698     if (!columnNode) {
5699         hasDragPixelMap_ = false;
5700         return;
5701     }
5702     auto rootNode = columnNode->GetParent();
5703     CHECK_NULL_VOID(rootNode);
5704     rootNode->RemoveChild(columnNode);
5705     rootNode->RebuildRenderContextTree();
5706     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
5707     hasDragPixelMap_ = false;
5708 }
5709 
UpdatePixelMapScale(float & scale)5710 void OverlayManager::UpdatePixelMapScale(float& scale)
5711 {
5712     auto columnNode = pixmapColumnNodeWeak_.Upgrade();
5713     CHECK_NULL_VOID(columnNode);
5714     auto hub = columnNode->GetOrCreateGestureEventHub();
5715     CHECK_NULL_VOID(hub);
5716     RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
5717     CHECK_NULL_VOID(pixelMap);
5718     int32_t height = pixelMap->GetHeight();
5719     int32_t width = pixelMap->GetWidth();
5720     if (height == 0 || width == 0) {
5721         return;
5722     }
5723     int32_t deviceWidth = SystemProperties::GetDeviceWidth();
5724     int32_t deviceHeight = SystemProperties::GetDeviceHeight();
5725     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
5726     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
5727     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
5728         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
5729             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
5730         }
5731     } else {
5732         if (hub->GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
5733             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
5734             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
5735                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
5736         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
5737                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
5738             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
5739                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
5740         }
5741     }
5742 }
5743 
RemoveFilterAnimation()5744 void OverlayManager::RemoveFilterAnimation()
5745 {
5746     if (!hasFilter_) {
5747         return;
5748     }
5749     auto filterNode = filterColumnNodeWeak_.Upgrade();
5750     CHECK_NULL_VOID(filterNode);
5751     auto filterContext = filterNode->GetRenderContext();
5752     CHECK_NULL_VOID(filterContext);
5753     auto pipelineContext = PipelineContext::GetCurrentContext();
5754     CHECK_NULL_VOID(pipelineContext);
5755     auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
5756     CHECK_NULL_VOID(menuTheme);
5757     AnimationOption option;
5758     option.SetOnFinishEvent([weak = WeakClaim(this)] {
5759         auto overlayManager = weak.Upgrade();
5760         CHECK_NULL_VOID(overlayManager);
5761         if (!overlayManager->hasFilterActived) {
5762             overlayManager->RemoveFilter();
5763         }
5764     });
5765     option.SetDuration(menuTheme->GetFilterAnimationDuration());
5766     option.SetCurve(Curves::SHARP);
5767     AnimationUtils::Animate(
5768         option,
5769         [filterContext]() {
5770             CHECK_NULL_VOID(filterContext);
5771             BlurStyleOption styleOption;
5772             styleOption.blurStyle = BlurStyle::NO_MATERIAL;
5773             filterContext->UpdateBackBlurStyle(styleOption);
5774         },
5775         option.GetOnFinishEvent());
5776 }
5777 
RemoveFilter()5778 void OverlayManager::RemoveFilter()
5779 {
5780     if (!hasFilter_) {
5781         return;
5782     }
5783     auto columnNode = filterColumnNodeWeak_.Upgrade();
5784     if (columnNode) {
5785         auto rootNode = columnNode->GetParent();
5786         CHECK_NULL_VOID(rootNode);
5787         rootNode->RemoveChild(columnNode);
5788         rootNode->RebuildRenderContextTree();
5789     }
5790     hasFilter_ = false;
5791 }
5792 
RemoveEventColumn()5793 void OverlayManager::RemoveEventColumn()
5794 {
5795     if (!hasEvent_) {
5796         TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn, hasEvent is false.");
5797         return;
5798     }
5799     auto columnNode = eventColumnNodeWeak_.Upgrade();
5800     if (!columnNode) {
5801         hasEvent_ = false;
5802         TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn, columnNode is null.");
5803         return;
5804     }
5805     auto rootNode = columnNode->GetParent();
5806     CHECK_NULL_VOID(rootNode);
5807     rootNode->RemoveChild(columnNode);
5808     hasEvent_ = false;
5809     TAG_LOGI(AceLogTag::ACE_DRAG, "remove eventColumn success.");
5810 }
5811 
ResetRootNode(int32_t sessionId)5812 void OverlayManager::ResetRootNode(int32_t sessionId)
5813 {
5814     if (curSessionIds_.find(sessionId) == curSessionIds_.end()) {
5815         return;
5816     }
5817 
5818     TAG_LOGI(AceLogTag::ACE_OVERLAY, "ResetRootNode %{public}d.", sessionId);
5819     curSessionIds_.erase(sessionId);
5820     auto rootNode = FindWindowScene(nullptr);
5821     CHECK_NULL_VOID(rootNode);
5822     rootNode->UpdateModalUiextensionCount(false);
5823 }
5824 
SetIsAllowedBeCovered(bool isAllowedBeCovered)5825 void OverlayManager::SetIsAllowedBeCovered(bool isAllowedBeCovered)
5826 {
5827     isAllowedBeCovered_ = isAllowedBeCovered;
5828 }
5829 
AddCurSessionId(int32_t sessionId)5830 bool OverlayManager::AddCurSessionId(int32_t sessionId)
5831 {
5832     if (curSessionIds_.find(sessionId) != curSessionIds_.end()) {
5833         return false;
5834     }
5835 
5836     curSessionIds_.insert(sessionId);
5837     return true;
5838 }
5839 
CreateModalUIExtension(const RefPtr<WantWrap> & wantWrap,const ModalUIExtensionCallbacks & callbacks,const ModalUIExtensionConfig & config)5840 int32_t OverlayManager::CreateModalUIExtension(const RefPtr<WantWrap>& wantWrap,
5841     const ModalUIExtensionCallbacks& callbacks, const ModalUIExtensionConfig& config)
5842 {
5843     auto& want = wantWrap->GetWant();
5844     return CreateModalUIExtension(want, callbacks, config);
5845 }
5846 
HandleUIExtNodeSize(const AAFwk::Want & want,RefPtr<FrameNode> uiExtNode)5847 bool OverlayManager::HandleUIExtNodeSize(const AAFwk::Want& want, RefPtr<FrameNode> uiExtNode)
5848 {
5849 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
5850     auto uiExtNodeWidth = want.GetIntParam(WANT_PARAM_UIEXTNODE_WIDTH_KEY, 0);
5851     auto uiExtNodeHeight = want.GetIntParam(WANT_PARAM_UIEXTNODE_HEIGHT_KEY, 0);
5852 #else
5853     auto uiExtNodeWidth = 0;
5854     auto uiExtNodeHeight = 0;
5855 #endif
5856     auto layoutProperty = uiExtNode->GetLayoutProperty();
5857     CHECK_NULL_RETURN(layoutProperty, false);
5858     auto calcWidth =
5859         CalcLength((uiExtNodeWidth > 0) ? Dimension(uiExtNodeWidth) : Dimension(1.0, DimensionUnit::PERCENT));
5860     auto calcHeight =
5861         CalcLength((uiExtNodeHeight > 0) ? Dimension(uiExtNodeHeight) : Dimension(1.0, DimensionUnit::PERCENT));
5862     TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
5863         "UIExtensionNode Size[%{public}d, [%{public}d].", uiExtNodeWidth, uiExtNodeHeight);
5864     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(calcWidth, calcHeight));
5865     return true;
5866 }
5867 
HandleUIExtNodeAngle(int32_t uiExtNodeAngle,RefPtr<FrameNode> uiExtNode)5868 bool OverlayManager::HandleUIExtNodeAngle(int32_t uiExtNodeAngle, RefPtr<FrameNode> uiExtNode)
5869 {
5870     auto layoutProperty = uiExtNode->GetLayoutProperty();
5871     CHECK_NULL_RETURN(layoutProperty, false);
5872     const auto& renderContext = uiExtNode->GetRenderContext();
5873     CHECK_NULL_RETURN(renderContext, false);
5874     TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "RootSize[%{public}f, %{public}f], Angle[%{public}d].",
5875         GetRootWidth(), GetRootHeight(), uiExtNodeAngle);
5876     switch (uiExtNodeAngle) {
5877         case UIEXTNODE_ANGLE_90: {
5878             layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(Dimension(GetRootHeight())),
5879                 CalcLength(Dimension(GetRootWidth()))));
5880             TranslateOptions translate(GetRootWidth(), 0, 0);
5881             renderContext->UpdateTransformTranslate(translate);
5882             NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 90.0f, 0.0f);
5883             DimensionOffset offset(Dimension(0), Dimension(0));
5884             renderContext->UpdateTransformRotate(rotate);
5885             renderContext->UpdateTransformCenter(offset);
5886             break;
5887         }
5888         case UIEXTNODE_ANGLE_180: {
5889             auto full = CalcLength(Dimension(1.0, DimensionUnit::PERCENT));
5890             layoutProperty->UpdateUserDefinedIdealSize(CalcSize(full, full));
5891             NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 180.0f, 0.0f);
5892             DimensionOffset offset(0.5_pct, 0.5_pct);
5893             renderContext->UpdateTransformRotate(rotate);
5894             renderContext->UpdateTransformCenter(offset);
5895             break;
5896         }
5897         case UIEXTNODE_ANGLE_270: {
5898             layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(Dimension(GetRootHeight())),
5899                 CalcLength(Dimension(GetRootWidth()))));
5900             TranslateOptions translate(0, GetRootHeight(), 0);
5901             renderContext->UpdateTransformTranslate(translate);
5902             NG::Vector5F rotate(0.0f, 0.0f, 1.0f, 270.0f, 0.0f);
5903             DimensionOffset offset(Dimension(0), Dimension(0));
5904             renderContext->UpdateTransformRotate(rotate);
5905             renderContext->UpdateTransformCenter(offset);
5906             break;
5907         }
5908     }
5909     return true;
5910 }
5911 
HandleUIExtNodeTransform(const AAFwk::Want & want,RefPtr<FrameNode> uiExtNode)5912 bool OverlayManager::HandleUIExtNodeTransform(const AAFwk::Want& want, RefPtr<FrameNode> uiExtNode)
5913 {
5914     auto containerId = Container::CurrentId();
5915     auto foldWindow = FoldableWindow::CreateFoldableWindow(containerId);
5916     bool isFoldExpand = foldWindow && (foldWindow->IsFoldExpand());
5917 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
5918     auto uiExtNodeAngle = want.GetIntParam(WANT_PARAM_UIEXTNODE_ANGLE_KEY, 0);
5919 #else
5920     auto uiExtNodeAngle = 0;
5921 #endif
5922     if (!(isFoldExpand) && UIExtNodeAngleValid(uiExtNodeAngle)) {
5923         return HandleUIExtNodeAngle(uiExtNodeAngle, uiExtNode);
5924     } else if (!UIExtNodeAngleValid(uiExtNodeAngle)) {
5925         return HandleUIExtNodeSize(want, uiExtNode);
5926     }
5927     return true;
5928 }
5929 
UIExtNodeAngleValid(int32_t uiExtNodeAngle)5930 bool OverlayManager::UIExtNodeAngleValid(int32_t uiExtNodeAngle)
5931 {
5932     return (uiExtNodeAngle == UIEXTNODE_ANGLE_90) ||
5933         (uiExtNodeAngle == UIEXTNODE_ANGLE_180) || (uiExtNodeAngle == UIEXTNODE_ANGLE_270);
5934 }
5935 
CreateModalUIExtension(const AAFwk::Want & want,const ModalUIExtensionCallbacks & callbacks,const ModalUIExtensionConfig & config)5936 int32_t OverlayManager::CreateModalUIExtension(
5937     const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks,
5938     const ModalUIExtensionConfig& config)
5939 {
5940     isProhibitBack_ = config.isProhibitBack;
5941     NG::InnerModalUIExtensionConfig innerModalUIExtensionConfig = { .isAsyncModalBinding = config.isAsyncModalBinding,
5942         .isDensityFollowHost = config.isDensityFollowHost };
5943     auto uiExtNode = ModalUIExtension::Create(want, callbacks, innerModalUIExtensionConfig);
5944     if (!HandleUIExtNodeTransform(want, uiExtNode)) {
5945         return 0;
5946     }
5947     auto buildNodeFunc = [uiExtNode]() -> RefPtr<UINode> {
5948         uiExtNode->MarkModifyDone();
5949         return uiExtNode;
5950     };
5951     auto sessionId = ModalUIExtension::GetSessionId(uiExtNode);
5952     if (!config.isAsyncModalBinding) {
5953         ModalStyle modalStyle = OverlayManager::SetUIExtensionModalStyleAndGet(config.prohibitedRemoveByRouter,
5954             config.prohibitedRemoveByNavigation);
5955         SetIsAllowedBeCovered(config.isAllowedBeCovered);
5956         // Convert the sessionId into a negative number to distinguish it from the targetId of other modal pages
5957         BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr, nullptr, nullptr,
5958             ContentCoverParam(), nullptr, -(sessionId));
5959         SetIsAllowedBeCovered(true); // Reset isAllowedBeCovered
5960     } else {
5961         auto bindModalCallback = [weak = WeakClaim(this), buildNodeFunc, sessionId, id = Container::CurrentId(),
5962             isAllowedBeCovered = config.isAllowedBeCovered,
5963             prohibitedRemoveByRouter = config.prohibitedRemoveByRouter,
5964             prohibitedRemoveByNavigation = config.prohibitedRemoveByNavigation,
5965             doAfterAsyncModalBinding = std::move(config.doAfterAsyncModalBinding)]() {
5966             ContainerScope scope(id);
5967             auto overlayManager = weak.Upgrade();
5968             CHECK_NULL_VOID(overlayManager);
5969             overlayManager->SetIsAllowedBeCovered(isAllowedBeCovered);
5970             ModalStyle modalStyle = OverlayManager::SetUIExtensionModalStyleAndGet(prohibitedRemoveByRouter,
5971                 prohibitedRemoveByNavigation);
5972             overlayManager->BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr,
5973                 nullptr, nullptr, ContentCoverParam(), nullptr, -(sessionId));
5974             overlayManager->SetIsAllowedBeCovered(true);
5975             if (doAfterAsyncModalBinding) {
5976                 doAfterAsyncModalBinding();
5977             }
5978         };
5979         ModalUIExtension::SetBindModalCallback(uiExtNode, std::move(bindModalCallback));
5980         uiExtNodes_[sessionId] = WeakClaim(RawPtr(uiExtNode));
5981     }
5982     return sessionId;
5983 }
5984 
SetUIExtensionModalStyleAndGet(bool prohibitedRemoveByRouter,bool prohibitedRemoveByNavigation)5985 ModalStyle OverlayManager::SetUIExtensionModalStyleAndGet(bool prohibitedRemoveByRouter,
5986     bool prohibitedRemoveByNavigation)
5987 {
5988     ModalStyle modalStyle;
5989     modalStyle.modalTransition = NG::ModalTransition::NONE;
5990     modalStyle.isUIExtension = true;
5991     modalStyle.prohibitedRemoveByRouter = prohibitedRemoveByRouter;
5992     modalStyle.prohibitedRemoveByNavigation = prohibitedRemoveByNavigation;
5993 
5994     return modalStyle;
5995 }
5996 
ClearUIExtensionNode()5997 void OverlayManager::ClearUIExtensionNode()
5998 {
5999     for (auto& item: uiExtNodes_) {
6000         auto uiExtNode = item.second.Upgrade();
6001         if (uiExtNode) {
6002             ModalUIExtension::SetBindModalCallback(uiExtNode, nullptr);
6003         }
6004     }
6005     uiExtNodes_.clear();
6006 }
6007 
DeleteUIExtensionNode(int32_t sessionId)6008 void OverlayManager::DeleteUIExtensionNode(int32_t sessionId)
6009 {
6010     auto iter = uiExtNodes_.find(sessionId);
6011     if (iter != uiExtNodes_.end()) {
6012         auto uiExtNode = iter->second.Upgrade();
6013         if (uiExtNode) {
6014             ModalUIExtension::SetBindModalCallback(uiExtNode, nullptr);
6015         }
6016         uiExtNodes_.erase(sessionId);
6017     }
6018 }
6019 
CloseModalUIExtension(int32_t sessionId)6020 void OverlayManager::CloseModalUIExtension(int32_t sessionId)
6021 {
6022     DeleteUIExtensionNode(sessionId);
6023     ModalStyle modalStyle;
6024     modalStyle.modalTransition = NG::ModalTransition::NONE;
6025     BindContentCover(false, nullptr, nullptr, modalStyle, nullptr, nullptr, nullptr, nullptr, ContentCoverParam(),
6026         nullptr, -(sessionId));
6027     ResetRootNode(-(sessionId));
6028 }
6029 
UpdateModalUIExtensionConfig(int32_t sessionId,const ModalUIExtensionAllowedUpdateConfig & config)6030 void OverlayManager::UpdateModalUIExtensionConfig(
6031     int32_t sessionId, const ModalUIExtensionAllowedUpdateConfig& config)
6032 {
6033     auto targetModalNode = GetModal((-(sessionId)));
6034     if (!targetModalNode) {
6035         TAG_LOGE(AceLogTag::ACE_OVERLAY,
6036             "not has sessionId(%{public}d) when UpdateModalUIExtensionConfig", sessionId);
6037         return;
6038     }
6039 
6040     const auto& targetModalPattern = targetModalNode->GetPattern<ModalPresentationPattern>();
6041     CHECK_NULL_VOID(targetModalPattern);
6042     targetModalPattern->SetProhibitedRemoveByNavigation(config.prohibitedRemoveByNavigation);
6043     targetModalPattern->SetProhibitedRemoveByRouter(config.prohibitedRemoveByRouter);
6044     TAG_LOGE(AceLogTag::ACE_OVERLAY,
6045         "UpdateModalUIExtensionConfig seccess with sessionId(%{public}d)", sessionId);
6046 }
6047 
BuildAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions)6048 RefPtr<FrameNode> OverlayManager::BuildAIEntityMenu(
6049     const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions)
6050 {
6051     TAG_LOGI(AceLogTag::ACE_OVERLAY, "build AI entity menu enter");
6052     auto menuNode = FrameNode::CreateFrameNode(V2::MENU_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
6053         AceType::MakeRefPtr<InnerMenuPattern>(-1, V2::MENU_ETS_TAG, MenuType::MULTI_MENU));
6054     CHECK_NULL_RETURN(menuNode, nullptr);
6055     for (const auto& menuOption : menuOptions) {
6056         MenuItemGroupView::Create();
6057         auto menuItemGroupNode = DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
6058         CHECK_NULL_RETURN(menuItemGroupNode, nullptr);
6059         MenuItemProperties menuItemProperties;
6060         menuItemProperties.content = menuOption.first;
6061         MenuItemModelNG menuItemModel;
6062         menuItemModel.Create(menuItemProperties);
6063         auto menuItemNode = DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
6064         CHECK_NULL_RETURN(menuItemNode, nullptr);
6065         auto menuItemPattern = menuItemNode->GetPattern<MenuItemPattern>();
6066         CHECK_NULL_RETURN(menuItemPattern, nullptr);
6067         menuItemPattern->SetOnClickAIMenuItem(menuOption.second);
6068         menuItemNode->MountToParent(menuItemGroupNode);
6069         menuItemGroupNode->MountToParent(menuNode);
6070     }
6071     return menuNode;
6072 }
6073 
CreateAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions,const RefPtr<FrameNode> & targetNode)6074 RefPtr<FrameNode> OverlayManager::CreateAIEntityMenu(
6075     const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions, const RefPtr<FrameNode>& targetNode)
6076 {
6077     TAG_LOGI(AceLogTag::ACE_OVERLAY, "create AI entity menu enter");
6078     CHECK_NULL_RETURN(targetNode, nullptr);
6079     auto pipeline = PipelineContext::GetCurrentContext();
6080     CHECK_NULL_RETURN(pipeline, nullptr);
6081     MenuParam menuParam;
6082     menuParam.type = MenuType::MENU;
6083     menuParam.placement = Placement::BOTTOM_LEFT;
6084     auto menuWrapperNode =
6085         MenuView::Create(BuildAIEntityMenu(menuOptions), targetNode->GetId(), targetNode->GetTag(), menuParam, true);
6086     return menuWrapperNode;
6087 }
6088 
ShowAIEntityMenu(const std::vector<std::pair<std::string,std::function<void ()>>> & menuOptions,const RectF & aiRect,const RefPtr<FrameNode> & targetNode)6089 bool OverlayManager::ShowAIEntityMenu(const std::vector<std::pair<std::string, std::function<void()>>>& menuOptions,
6090     const RectF& aiRect, const RefPtr<FrameNode>& targetNode)
6091 {
6092     TAG_LOGI(AceLogTag::ACE_OVERLAY, "show AI entity menu enter");
6093     CHECK_NULL_RETURN(targetNode, false);
6094     auto menuWrapperNode = CreateAIEntityMenu(menuOptions, targetNode);
6095     CHECK_NULL_RETURN(menuWrapperNode, false);
6096     menuWrapperNode->GetOrCreateFocusHub()->SetFocusable(false);
6097     auto wrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
6098     CHECK_NULL_RETURN(wrapperPattern, false);
6099     auto pipeline = targetNode->GetContext();
6100     CHECK_NULL_RETURN(pipeline, false);
6101     auto safeAreaManager = pipeline->GetSafeAreaManager();
6102     CHECK_NULL_RETURN(safeAreaManager, false);
6103     auto targetId = targetNode->GetId();
6104     wrapperPattern->RegisterMenuAppearCallback([overlayWk = WeakClaim(this),
6105         safeAreaWK = WeakClaim(RawPtr(safeAreaManager)), targetId, containerId = Container::CurrentId()]() {
6106             ContainerScope scope(containerId);
6107             auto safeAreaManager = safeAreaWK.Upgrade();
6108             CHECK_NULL_VOID(safeAreaManager);
6109             safeAreaManager->AddKeyboardChangeCallbackConsideringUIExt(targetId, [overlayWk, targetId, containerId]() {
6110                     ContainerScope scope(containerId);
6111                     auto overlayManager = overlayWk.Upgrade();
6112                     CHECK_NULL_VOID(overlayManager);
6113                     overlayManager->CloseAIEntityMenu(targetId);
6114                 });
6115         });
6116     wrapperPattern->RegisterMenuDisappearCallback(
6117         [safeAreaWK = WeakClaim(RawPtr(safeAreaManager)), targetId, containerId = Container::CurrentId()]() {
6118             ContainerScope scope(containerId);
6119             auto safeAreaManager = safeAreaWK.Upgrade();
6120             CHECK_NULL_VOID(safeAreaManager);
6121             safeAreaManager->RemoveKeyboardChangeCallbackConsideringUIExt(targetId);
6122         });
6123     auto menuNode = DynamicCast<FrameNode>(menuWrapperNode->GetFirstChild());
6124     CHECK_NULL_RETURN(menuNode, false);
6125     auto menuLayoutProperty = menuNode->GetLayoutProperty<MenuLayoutProperty>();
6126     CHECK_NULL_RETURN(menuLayoutProperty, false);
6127     menuLayoutProperty->UpdateIsRectInTarget(true);
6128     menuLayoutProperty->UpdateTargetSize(aiRect.GetSize());
6129 
6130     auto theme = pipeline->GetTheme<SelectTheme>();
6131     CHECK_NULL_RETURN(theme, false);
6132     if (theme->GetExpandDisplay()) {
6133         MenuParam menuParam {};
6134         SubwindowManager::GetInstance()->ShowMenuNG(menuWrapperNode, menuParam, targetNode, aiRect.GetOffset());
6135     } else {
6136         ShowMenu(targetNode->GetId(), aiRect.GetOffset(), menuWrapperNode);
6137     }
6138     return true;
6139 }
6140 
CloseAIEntityMenu(int32_t targetId)6141 void OverlayManager::CloseAIEntityMenu(int32_t targetId)
6142 {
6143     auto pipeline = PipelineContext::GetCurrentContextSafely();
6144     CHECK_NULL_VOID(pipeline);
6145     auto theme = pipeline->GetTheme<SelectTheme>();
6146     CHECK_NULL_VOID(theme);
6147     auto expandDisplay = theme->GetExpandDisplay();
6148     if (expandDisplay) {
6149         SubwindowManager::GetInstance()->ClearMenu();
6150         SubwindowManager::GetInstance()->ClearMenuNG(Container::CurrentId(), targetId);
6151     } else {
6152         auto menuNode = GetMenuNode(targetId);
6153         CHECK_NULL_VOID(menuNode);
6154         HideMenu(menuNode, targetId);
6155     }
6156 }
6157 
CreateOverlayNode()6158 void OverlayManager::CreateOverlayNode()
6159 {
6160     TAG_LOGD(AceLogTag::ACE_OVERLAY, "create overlay node enter");
6161     if (overlayNode_) {
6162         return;
6163     }
6164     auto rootNode = rootNodeWeak_.Upgrade();
6165     CHECK_NULL_VOID(rootNode);
6166     auto pipelineContext = PipelineContext::GetCurrentContext();
6167     CHECK_NULL_VOID(pipelineContext);
6168     auto stageManager = pipelineContext->GetStageManager();
6169     CHECK_NULL_VOID(stageManager);
6170     auto stageNode = stageManager->GetStageNode();
6171     CHECK_NULL_VOID(stageNode);
6172     overlayNode_ = FrameNode::CreateFrameNode(V2::OVERLAY_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
6173         AceType::MakeRefPtr<OverlayContainerPattern>());
6174     CHECK_NULL_VOID(overlayNode_);
6175     overlayNode_->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
6176     auto layoutProperty = overlayNode_->GetLayoutProperty();
6177     CHECK_NULL_VOID(layoutProperty);
6178     auto full = CalcLength(Dimension(1.0, DimensionUnit::PERCENT));
6179     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(full, full));
6180     rootNode->AddChildAfter(overlayNode_, stageNode);
6181 }
6182 
AddFrameNodeToOverlay(const RefPtr<NG::FrameNode> & node,std::optional<int32_t> index)6183 void OverlayManager::AddFrameNodeToOverlay(const RefPtr<NG::FrameNode>& node, std::optional<int32_t> index)
6184 {
6185     TAG_LOGD(AceLogTag::ACE_OVERLAY, "add FrameNode to the overlay node enter");
6186     CHECK_NULL_VOID(node);
6187     int32_t level = -1;
6188     if (index.has_value() && index.value() >= 0) {
6189         level = index.value();
6190     }
6191     CreateOverlayNode();
6192     CHECK_NULL_VOID(overlayNode_);
6193     if (frameNodeMapOnOverlay_.find(node->GetId()) != frameNodeMapOnOverlay_.end()) {
6194         overlayNode_->RemoveChild(node);
6195         frameNodeMapOnOverlay_.erase(node->GetId());
6196     }
6197     const auto& children = overlayNode_->GetChildren();
6198     if (level == -1) {
6199         overlayNode_->AddChild(node);
6200     } else if (children.empty() || frameNodeMapOnOverlay_[overlayNode_->GetFirstChild()->GetId()] == -1 ||
6201                level < frameNodeMapOnOverlay_[overlayNode_->GetFirstChild()->GetId()]) {
6202         overlayNode_->AddChild(node, 0);
6203     } else {
6204         for (auto it = children.rbegin(); it != children.rend(); ++it) {
6205             auto childLevel = frameNodeMapOnOverlay_[(*it)->GetId()];
6206             if (childLevel < 0) {
6207                 continue;
6208             }
6209             if (childLevel <= level) {
6210                 auto beforeNode = DynamicCast<FrameNode>(*it);
6211                 CHECK_NULL_VOID(beforeNode);
6212                 overlayNode_->AddChildAfter(node, beforeNode);
6213                 break;
6214             }
6215         }
6216     }
6217     overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6218     frameNodeMapOnOverlay_[node->GetId()] = level;
6219     auto focusHub = node->GetFocusHub();
6220     CHECK_NULL_VOID(focusHub);
6221     focusHub->RequestFocus();
6222 }
6223 
RemoveFrameNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6224 void OverlayManager::RemoveFrameNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6225 {
6226     TAG_LOGD(AceLogTag::ACE_OVERLAY, "delete the FrameNode on the overlay node enter");
6227     CHECK_NULL_VOID(node);
6228     if (frameNodeMapOnOverlay_.find(node->GetId()) == frameNodeMapOnOverlay_.end()) {
6229         TAG_LOGW(AceLogTag::ACE_OVERLAY, "the node does not exist in the overlay");
6230         return;
6231     }
6232     CHECK_NULL_VOID(overlayNode_);
6233     overlayNode_->RemoveChild(node);
6234     frameNodeMapOnOverlay_.erase(node->GetId());
6235     if (overlayNode_->GetChildren().empty()) {
6236         auto rootNode = rootNodeWeak_.Upgrade();
6237         CHECK_NULL_VOID(rootNode);
6238         rootNode->RemoveChild(overlayNode_);
6239         overlayNode_.Reset();
6240         frameNodeMapOnOverlay_.clear();
6241         rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6242         return;
6243     }
6244     overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6245 }
6246 
ShowNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6247 void OverlayManager::ShowNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6248 {
6249     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show the FrameNode on the overlay node enter");
6250     CHECK_NULL_VOID(node);
6251     CHECK_NULL_VOID(overlayNode_);
6252     auto layoutProperty = node->GetLayoutProperty();
6253     CHECK_NULL_VOID(layoutProperty);
6254     if (layoutProperty->GetVisibility().has_value() && layoutProperty->GetVisibilityValue() == VisibleType::VISIBLE) {
6255         return;
6256     }
6257     layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
6258     node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6259     auto focusHub = node->GetFocusHub();
6260     CHECK_NULL_VOID(focusHub);
6261     focusHub->RequestFocus();
6262 }
6263 
HideNodeOnOverlay(const RefPtr<NG::FrameNode> & node)6264 void OverlayManager::HideNodeOnOverlay(const RefPtr<NG::FrameNode>& node)
6265 {
6266     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide the FrameNode on the overlay node enter");
6267     CHECK_NULL_VOID(node);
6268     CHECK_NULL_VOID(overlayNode_);
6269     auto layoutProperty = node->GetLayoutProperty();
6270     CHECK_NULL_VOID(layoutProperty);
6271     if (layoutProperty->GetVisibility().has_value() && layoutProperty->GetVisibilityValue() == VisibleType::GONE) {
6272         return;
6273     }
6274     layoutProperty->UpdateVisibility(VisibleType::GONE);
6275     node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6276     auto focusHub = node->GetFocusHub();
6277     CHECK_NULL_VOID(focusHub);
6278     focusHub->LostFocusToViewRoot();
6279 }
6280 
ShowAllNodesOnOverlay()6281 void OverlayManager::ShowAllNodesOnOverlay()
6282 {
6283     TAG_LOGD(AceLogTag::ACE_OVERLAY, "show all FrameNodes on the overlay node enter");
6284     CHECK_NULL_VOID(overlayNode_);
6285     for (auto& child : overlayNode_->GetChildren()) {
6286         auto frameNode = DynamicCast<FrameNode>(child);
6287         CHECK_NULL_VOID(frameNode);
6288         auto layoutProperty = frameNode->GetLayoutProperty();
6289         CHECK_NULL_VOID(layoutProperty);
6290         layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
6291     }
6292     overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6293     auto focusView = overlayNode_->GetPattern<FocusView>();
6294     CHECK_NULL_VOID(focusView);
6295     focusView->FocusViewShow();
6296 }
6297 
HideAllNodesOnOverlay()6298 void OverlayManager::HideAllNodesOnOverlay()
6299 {
6300     TAG_LOGD(AceLogTag::ACE_OVERLAY, "hide all FrameNodes on the overlay node enter");
6301     CHECK_NULL_VOID(overlayNode_);
6302     for (auto& child : overlayNode_->GetChildren()) {
6303         auto frameNode = DynamicCast<FrameNode>(child);
6304         CHECK_NULL_VOID(frameNode);
6305         auto layoutProperty = frameNode->GetLayoutProperty();
6306         CHECK_NULL_VOID(layoutProperty);
6307         layoutProperty->UpdateVisibility(VisibleType::GONE);
6308     }
6309     overlayNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
6310     auto focusView = overlayNode_->GetPattern<FocusView>();
6311     CHECK_NULL_VOID(focusView);
6312     focusView->FocusViewClose();
6313 }
6314 
MarkDirty(PropertyChangeFlag flag)6315 void OverlayManager::MarkDirty(PropertyChangeFlag flag)
6316 {
6317     auto root = rootNodeWeak_.Upgrade();
6318     CHECK_NULL_VOID(root);
6319     auto pipeline = PipelineContext::GetCurrentContext();
6320     CHECK_NULL_VOID(pipeline);
6321     auto markNode = root;
6322     if (pipeline->GetInstallationFree()) {
6323         markNode = root->GetFirstChild();
6324         TAG_LOGD(AceLogTag::ACE_OVERLAY, "atomicService node need marked");
6325     }
6326     for (auto&& child : markNode->GetChildren()) {
6327         // first child is Stage node in main window, subwindow not has Stage node.
6328         if (child != root->GetFirstChild() || pipeline->IsSubPipeline()) {
6329             child->MarkDirtyNode(flag);
6330             // sheetPage Node will MarkDirty when VirtualKeyboard Height Changes
6331             auto sheetParent = DynamicCast<FrameNode>(child);
6332             if (sheetParent && sheetParent->GetTag() == V2::SHEET_WRAPPER_TAG) {
6333                 auto sheet = sheetParent->GetChildAtIndex(0);
6334                 if (sheet) {
6335                     sheet->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6336                 }
6337             }
6338         }
6339     }
6340 }
6341 
MarkDirtyOverlay()6342 void OverlayManager::MarkDirtyOverlay()
6343 {
6344     auto root = rootNodeWeak_.Upgrade();
6345     CHECK_NULL_VOID(root);
6346     auto child = root->GetLastChild();
6347     CHECK_NULL_VOID(child);
6348     // sheetPage Node will MarkDirty when VirtualKeyboard Height Changes
6349     auto sheetParent = DynamicCast<FrameNode>(child);
6350     if (sheetParent && sheetParent->GetTag() == V2::SHEET_WRAPPER_TAG) {
6351         auto sheet = sheetParent->GetChildAtIndex(0);
6352         if (sheet) {
6353             sheet->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6354         }
6355     }
6356 }
6357 
CheckPageNeedAvoidKeyboard() const6358 bool OverlayManager::CheckPageNeedAvoidKeyboard() const
6359 {
6360     auto root = rootNodeWeak_.Upgrade();
6361     CHECK_NULL_RETURN(root, true);
6362     auto child = root->GetLastChild();
6363     CHECK_NULL_RETURN(child, true);
6364     // page will not avoid keyboard when lastChild is sheet
6365     if (child->GetTag() != V2::SHEET_WRAPPER_TAG) {
6366         return true;
6367     }
6368     auto frameNode = DynamicCast<FrameNode>(child);
6369     return !(frameNode && frameNode->GetFocusHub() && frameNode->GetFocusHub()->IsCurrentFocus());
6370 }
6371 
GetRootWidth() const6372 float OverlayManager::GetRootWidth() const
6373 {
6374     auto rootNode = rootNodeWeak_.Upgrade();
6375     CHECK_NULL_RETURN(rootNode, 0.0);
6376     auto rootGeometryNode = AceType::DynamicCast<FrameNode>(rootNode)->GetGeometryNode();
6377     CHECK_NULL_RETURN(rootGeometryNode, 0.0);
6378     auto rootWidth = rootGeometryNode->GetFrameSize().Width();
6379     return rootWidth;
6380 }
6381 
GetRootHeight() const6382 float OverlayManager::GetRootHeight() const
6383 {
6384     auto rootNode = rootNodeWeak_.Upgrade();
6385     CHECK_NULL_RETURN(rootNode, 0.0);
6386     auto rootGeometryNode = AceType::DynamicCast<FrameNode>(rootNode)->GetGeometryNode();
6387     CHECK_NULL_RETURN(rootGeometryNode, 0.0);
6388     auto rootHeight = rootGeometryNode->GetFrameSize().Height();
6389     return rootHeight;
6390 }
6391 
CheckReturnFocus(RefPtr<FrameNode> node)6392 void OverlayManager::CheckReturnFocus(RefPtr<FrameNode> node) {}
6393 
isMaskNode(int32_t maskId)6394 bool OverlayManager::isMaskNode(int32_t maskId)
6395 {
6396     for (const auto& [key, value] : maskNodeIdMap_) {
6397         if (value == maskId) {
6398             return true;
6399         }
6400     }
6401     return false;
6402 }
6403 
GetMaskNodeIdWithDialogId(int32_t dialogId)6404 int32_t OverlayManager::GetMaskNodeIdWithDialogId(int32_t dialogId)
6405 {
6406     auto iter = maskNodeIdMap_.find(dialogId);
6407     return (iter == maskNodeIdMap_.end()) ? -1 : iter->second;
6408 }
6409 
MountGatherNodeToRootNode(const RefPtr<FrameNode> & frameNode,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo)6410 void OverlayManager::MountGatherNodeToRootNode(const RefPtr<FrameNode>& frameNode,
6411     const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo)
6412 {
6413     auto rootNode = rootNodeWeak_.Upgrade();
6414     CHECK_NULL_VOID(rootNode);
6415     frameNode->MountToParent(rootNode);
6416     frameNode->OnMountToParentDone();
6417     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6418     gatherNodeWeak_ = frameNode;
6419     hasGatherNode_ = true;
6420     gatherNodeChildrenInfo_ = gatherNodeChildrenInfo;
6421 }
6422 
MountGatherNodeToWindowScene(const RefPtr<FrameNode> & frameNode,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo,const RefPtr<UINode> & windowScene)6423 void OverlayManager::MountGatherNodeToWindowScene(const RefPtr<FrameNode>& frameNode,
6424     const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo,
6425     const RefPtr<UINode>& windowScene)
6426 {
6427     CHECK_NULL_VOID(windowScene);
6428     frameNode->MountToParent(windowScene);
6429     frameNode->OnMountToParentDone();
6430     windowScene->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6431     gatherNodeWeak_ = frameNode;
6432     hasGatherNode_ = true;
6433     gatherNodeChildrenInfo_ = gatherNodeChildrenInfo;
6434 }
6435 
RemoveGatherNode()6436 void OverlayManager::RemoveGatherNode()
6437 {
6438     CHECK_EQUAL_VOID(hasGatherNode_, false);
6439     auto frameNode = gatherNodeWeak_.Upgrade();
6440     CHECK_NULL_VOID(frameNode);
6441     TAG_LOGI(AceLogTag::ACE_DRAG, "Remove gather node");
6442     auto rootNode = frameNode->GetParent();
6443     CHECK_NULL_VOID(rootNode);
6444     rootNode->RemoveChild(frameNode);
6445     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6446     hasGatherNode_ = false;
6447     gatherNodeWeak_ = nullptr;
6448     gatherNodeChildrenInfo_.clear();
6449 }
6450 
RemoveGatherNodeWithAnimation()6451 void OverlayManager::RemoveGatherNodeWithAnimation()
6452 {
6453     if (!hasGatherNode_) {
6454         return;
6455     }
6456     TAG_LOGI(AceLogTag::ACE_DRAG, "Remove gather node with animation");
6457     AnimationOption option;
6458     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
6459     option.SetCurve(Curves::SHARP);
6460 
6461     option.SetOnFinishEvent([weak = gatherNodeWeak_] {
6462         auto context = PipelineContext::GetCurrentContext();
6463         CHECK_NULL_VOID(context);
6464         auto taskExecutor = context->GetTaskExecutor();
6465         CHECK_NULL_VOID(taskExecutor);
6466         // animation finish event should be posted to UI thread.
6467         taskExecutor->PostTask(
6468             [weak, id = Container::CurrentId()]() {
6469                 ContainerScope scope(id);
6470                 auto frameNode = weak.Upgrade();
6471                 CHECK_NULL_VOID(frameNode);
6472                 auto rootNode = frameNode->GetParent();
6473                 CHECK_NULL_VOID(rootNode);
6474                 rootNode->RemoveChild(frameNode);
6475                 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6476             },
6477             TaskExecutor::TaskType::UI, "ArkUIOverlayRemoveGatherNodeEvent");
6478     });
6479     gatherNodeWeak_ = nullptr;
6480     hasGatherNode_ = false;
6481     AnimationUtils::Animate(
6482         option,
6483         [gatherNodeChildrenInfo = gatherNodeChildrenInfo_]() {
6484             for (auto& child : gatherNodeChildrenInfo) {
6485                 auto imageNode = child.imageNode.Upgrade();
6486                 CHECK_NULL_VOID(imageNode);
6487                 auto imageContext = imageNode->GetRenderContext();
6488                 CHECK_NULL_VOID(imageContext);
6489                 imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(child.offset.GetX()),
6490                     Dimension(child.offset.GetY())));
6491                 imageContext->UpdateTransformScale({ 1.0f, 1.0f });
6492                 Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
6493                 imageContext->UpdateTransformRotate(rotate);
6494                 imageContext->UpdateOpacity(1.0);
6495                 BorderRadiusProperty borderRadius;
6496                 borderRadius.SetRadius(0.0_vp);
6497                 imageContext->UpdateBorderRadius(borderRadius);
6498             }
6499         },
6500         option.GetOnFinishEvent());
6501 }
6502 
UpdateGatherNodeToTop()6503 void OverlayManager::UpdateGatherNodeToTop()
6504 {
6505     auto frameNode = gatherNodeWeak_.Upgrade();
6506     CHECK_NULL_VOID(frameNode);
6507     auto rootNode = frameNode->GetParent();
6508     CHECK_NULL_VOID(rootNode);
6509     rootNode->RemoveChild(frameNode);
6510     frameNode->MountToParent(rootNode);
6511     frameNode->OnMountToParentDone();
6512     rootNode->RebuildRenderContextTree();
6513     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6514 }
6515 
GetPixelMapContentNode(bool isSubwindowOverlay) const6516 RefPtr<FrameNode> OverlayManager::GetPixelMapContentNode(bool isSubwindowOverlay) const
6517 {
6518     if (isSubwindowOverlay) {
6519         RefPtr<FrameNode> imageNode = GetPixelMapContentNodeForSubwindow();
6520         return imageNode;
6521     }
6522     auto column = pixmapColumnNodeWeak_.Upgrade();
6523     CHECK_NULL_RETURN(column, nullptr);
6524     auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
6525     return imageNode;
6526 }
6527 
GetPixelMapContentNodeForSubwindow() const6528 RefPtr<FrameNode> OverlayManager::GetPixelMapContentNodeForSubwindow() const
6529 {
6530     auto rootNode = rootNodeWeak_.Upgrade();
6531     CHECK_NULL_RETURN(rootNode, nullptr);
6532     for (const auto& child : rootNode->GetChildren()) {
6533         auto node = DynamicCast<FrameNode>(child);
6534         if (node && node->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
6535             continue;
6536         }
6537         for (auto& childNode : node->GetChildren()) {
6538             auto frameNode = DynamicCast<FrameNode>(childNode);
6539             if (frameNode &&
6540                 (frameNode->GetTag() == V2::MENU_PREVIEW_ETS_TAG || frameNode->GetTag() == V2::IMAGE_ETS_TAG)) {
6541                 return frameNode;
6542             }
6543         }
6544     }
6545     return nullptr;
6546 }
6547 
UpdatePixelMapPosition(bool isSubwindowOverlay)6548 void OverlayManager::UpdatePixelMapPosition(bool isSubwindowOverlay)
6549 {
6550     if (!isSubwindowOverlay && !hasPixelMap_) {
6551         return;
6552     }
6553     if (IsOriginDragMoveVector() || !IsUpdateDragMoveVector()) {
6554         return;
6555     }
6556     auto moveVector = GetUpdateDragMoveVector();
6557     RefPtr<FrameNode> imageNode = GetPixelMapContentNode(isSubwindowOverlay);
6558     CHECK_NULL_VOID(imageNode);
6559     auto imageContext = imageNode->GetRenderContext();
6560     CHECK_NULL_VOID(imageContext);
6561     auto rect = imageNode->GetOffsetRelativeToWindow();
6562     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(moveVector.GetX() + rect.GetX()),
6563         Dimension(moveVector.GetY() + rect.GetY())));
6564     imageContext->OnModifyDone();
6565 }
6566 
GetDragPixelMapContentNode() const6567 RefPtr<FrameNode> OverlayManager::GetDragPixelMapContentNode() const
6568 {
6569     auto column = dragPixmapColumnNodeWeak_.Upgrade();
6570     CHECK_NULL_RETURN(column, nullptr);
6571     auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
6572     return imageNode;
6573 }
6574 
GetPixelMapBadgeNode() const6575 RefPtr<FrameNode> OverlayManager::GetPixelMapBadgeNode() const
6576 {
6577     auto column = pixmapColumnNodeWeak_.Upgrade();
6578     CHECK_NULL_RETURN(column, nullptr);
6579     auto textNode = AceType::DynamicCast<FrameNode>(column->GetLastChild());
6580     CHECK_NULL_RETURN(textNode, nullptr);
6581     return textNode;
6582 }
6583 
GetDragPixelMapBadgeNode() const6584 RefPtr<FrameNode> OverlayManager::GetDragPixelMapBadgeNode() const
6585 {
6586     auto column = dragPixmapColumnNodeWeak_.Upgrade();
6587     CHECK_NULL_RETURN(column, nullptr);
6588     auto textNode = AceType::DynamicCast<FrameNode>(column->GetLastChild());
6589     CHECK_NULL_RETURN(textNode, nullptr);
6590     return textNode;
6591 }
6592 
RemoveMenuBadgeNode(const RefPtr<FrameNode> & menuWrapperNode)6593 void OverlayManager::RemoveMenuBadgeNode(const RefPtr<FrameNode>& menuWrapperNode)
6594 {
6595     CHECK_NULL_VOID(menuWrapperNode);
6596     auto pattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
6597     CHECK_NULL_VOID(pattern);
6598     auto badgeNode = pattern->GetBadgeNode();
6599     CHECK_NULL_VOID(badgeNode);
6600     menuWrapperNode->RemoveChild(badgeNode);
6601     menuWrapperNode->RebuildRenderContextTree();
6602     menuWrapperNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6603 }
6604 
RemovePreviewBadgeNode()6605 void OverlayManager::RemovePreviewBadgeNode()
6606 {
6607     auto columnNode = pixmapColumnNodeWeak_.Upgrade();
6608     CHECK_NULL_VOID(columnNode);
6609     auto textNode = AceType::DynamicCast<FrameNode>(columnNode->GetChildAtIndex(1));
6610     CHECK_NULL_VOID(textNode);
6611     columnNode->RemoveChild(textNode);
6612     columnNode->RebuildRenderContextTree();
6613     columnNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
6614 }
6615 
GetRootNode() const6616 const WeakPtr<UINode>& OverlayManager::GetRootNode() const
6617 {
6618     return rootNodeWeak_;
6619 }
6620 
GetGroupManager() const6621 const RefPtr<GroupManager>& OverlayManager::GetGroupManager() const
6622 {
6623     return groupManager_;
6624 }
6625 
ShowFilterAnimation(const RefPtr<FrameNode> & columnNode)6626 void OverlayManager::ShowFilterAnimation(const RefPtr<FrameNode>& columnNode)
6627 {
6628     CHECK_NULL_VOID(columnNode);
6629 
6630     auto filterRenderContext = columnNode->GetRenderContext();
6631     CHECK_NULL_VOID(filterRenderContext);
6632 
6633     auto pipelineContext = PipelineContext::GetCurrentContext();
6634     CHECK_NULL_VOID(pipelineContext);
6635     auto menuTheme = pipelineContext->GetTheme<NG::MenuTheme>();
6636     CHECK_NULL_VOID(menuTheme);
6637 
6638     auto maskColor = menuTheme->GetPreviewMenuMaskColor();
6639     BlurStyleOption styleOption;
6640     styleOption.blurStyle = BlurStyle::BACKGROUND_THIN;
6641     styleOption.colorMode = ThemeColorMode::SYSTEM;
6642 
6643     AnimationOption option;
6644     option.SetDuration(menuTheme->GetFilterAnimationDuration());
6645     option.SetCurve(Curves::SHARP);
6646     option.SetOnFinishEvent([] {
6647         auto pipelineContext = PipelineContext::GetCurrentContext();
6648         auto manager = pipelineContext->GetOverlayManager();
6649         CHECK_NULL_VOID(manager);
6650         manager->SetFilterActive(false);
6651     });
6652     filterRenderContext->UpdateBackBlurRadius(Dimension(0.0f));
6653     AnimationUtils::Animate(
6654         option,
6655         [filterRenderContext, styleOption, maskColor, menuTheme]() {
6656             CHECK_NULL_VOID(filterRenderContext);
6657             if (menuTheme->GetHasBackBlur()) {
6658                 filterRenderContext->UpdateBackBlurStyle(styleOption);
6659             } else {
6660                 filterRenderContext->UpdateBackgroundColor(maskColor);
6661             }
6662         },
6663         option.GetOnFinishEvent());
6664 }
6665 
RemoveMenuNotInSubWindow(const WeakPtr<FrameNode> & menuWK,const WeakPtr<UINode> & rootWeak,const WeakPtr<OverlayManager> & overlayWeak)6666 void OverlayManager::RemoveMenuNotInSubWindow(
6667     const WeakPtr<FrameNode>& menuWK, const WeakPtr<UINode>& rootWeak, const WeakPtr<OverlayManager>& overlayWeak)
6668 {
6669     auto menu = menuWK.Upgrade();
6670     CHECK_NULL_VOID(menu);
6671     auto rootNode = rootWeak.Upgrade();
6672     CHECK_NULL_VOID(rootNode);
6673     auto overlayManager = overlayWeak.Upgrade();
6674     CHECK_NULL_VOID(overlayManager);
6675 
6676     auto container = Container::Current();
6677     if (container && container->IsScenceBoardWindow()) {
6678         rootNode = overlayManager->FindWindowScene(menu);
6679     }
6680     CHECK_NULL_VOID(rootNode);
6681     RemoveChildWithService(rootNode, menu);
6682     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
6683 }
6684 
DumpOverlayInfo() const6685 void OverlayManager::DumpOverlayInfo() const
6686 {
6687     auto container = Container::Current();
6688     if (container) {
6689         DumpLog::GetInstance().Print("Container: ");
6690         DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "ContainerId: " + std::to_string(container->GetInstanceId()));
6691         DumpLog::GetInstance().Print(
6692             DUMP_LOG_DEPTH_1, "IsSubContainer: " + std::string(container->IsSubContainer() ? "true" : "false"));
6693     }
6694 
6695     DumpLog::GetInstance().Print("----------PopupMapInfo----------");
6696     DumpPopupMapInfo();
6697 
6698     DumpLog::GetInstance().Print("----------MenuMapInfo----------");
6699     DumpMapInfo(menuMap_, "MenuMap");
6700 
6701     DumpLog::GetInstance().Print("----------DialogMapInfo----------");
6702     DumpMapInfo(dialogMap_, "DialogMap", false);
6703 
6704     DumpLog::GetInstance().Print("----------CustomPopupMapInfo----------");
6705     DumpMapInfo(customPopupMap_, "CustomPopupMap");
6706 
6707     DumpLog::GetInstance().Print("----------CustomKeyboardMapInfo----------");
6708     DumpMapInfo(customKeyboardMap_, "CustomKeyboardMap");
6709 
6710     DumpLog::GetInstance().Print("----------ToastMapInfo----------");
6711     DumpMapInfo(toastMap_, "ToastMap", false);
6712 
6713     DumpLog::GetInstance().Print("----------SheetMapInfo----------");
6714     DumpSheetMapInfo(sheetMap_, "SheetMap");
6715 
6716     DumpLog::GetInstance().Print("----------MaskNodeIdMapInfo----------");
6717     DumpMaskNodeIdMapInfo();
6718 
6719     DumpLog::GetInstance().Print("----------ModalListInfo----------");
6720     DumpModalListInfo();
6721 }
6722 
DumpPopupMapInfo() const6723 void OverlayManager::DumpPopupMapInfo() const
6724 {
6725     DumpLog::GetInstance().Print("PopupMap: ");
6726     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(popupMap_.size()));
6727     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6728 
6729     for (const auto& entry : popupMap_) {
6730         std::string entryLog = "";
6731         auto targetId = entry.first;
6732         auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6733         auto popupInfo = entry.second;
6734         auto popupNode = popupInfo.popupNode;
6735         DumpEntry(targetNode, targetId, popupNode);
6736     }
6737 
6738     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6739 }
6740 
DumpMapInfo(std::unordered_map<int32_t,RefPtr<FrameNode>> map,const std::string mapName,bool hasTarget) const6741 void OverlayManager::DumpMapInfo(
6742     std::unordered_map<int32_t, RefPtr<FrameNode>> map, const std::string mapName, bool hasTarget) const
6743 {
6744     DumpLog::GetInstance().Print(mapName + ": ");
6745     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6746     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6747 
6748     for (const auto& entry : map) {
6749         auto targetId = entry.first;
6750         auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6751         auto node = entry.second;
6752 
6753         if (hasTarget) {
6754             DumpEntry(targetNode, targetId, node);
6755         } else {
6756             std::string entryLog = GetMapNodeLog(node, hasTarget);
6757             DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6758         }
6759     }
6760 
6761     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6762 }
6763 
DumpMapInfo(std::unordered_map<int32_t,WeakPtr<FrameNode>> map,const std::string mapName,bool hasTarget) const6764 void OverlayManager::DumpMapInfo(
6765     std::unordered_map<int32_t, WeakPtr<FrameNode>> map, const std::string mapName, bool hasTarget) const
6766 {
6767     DumpLog::GetInstance().Print(mapName + ": ");
6768     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6769     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6770 
6771     for (const auto& entry : map) {
6772         auto targetId = entry.first;
6773         auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6774         auto node = entry.second.Upgrade();
6775         if (hasTarget) {
6776             DumpEntry(targetNode, targetId, node);
6777         } else {
6778             std::string entryLog = GetMapNodeLog(node, hasTarget);
6779             DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6780         }
6781     }
6782 
6783     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6784 }
6785 
DumpSheetMapInfo(const std::unordered_map<SheetKey,WeakPtr<FrameNode>,SheetKeyHash> & map,const std::string mapName) const6786 void OverlayManager::DumpSheetMapInfo(
6787     const std::unordered_map<SheetKey, WeakPtr<FrameNode>, SheetKeyHash>& map,
6788     const std::string mapName) const
6789 {
6790     DumpLog::GetInstance().Print(mapName + ": ");
6791     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(map.size()));
6792     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6793 
6794     for (const auto& entry : map) {
6795         auto targetId = entry.first.targetId;
6796         auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6797         auto node = entry.second.Upgrade();
6798         DumpEntry(targetNode, targetId, node);
6799     }
6800 
6801     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6802 }
6803 
DumpMaskNodeIdMapInfo() const6804 void OverlayManager::DumpMaskNodeIdMapInfo() const
6805 {
6806     DumpLog::GetInstance().Print("MaskNodeIdMap: ");
6807     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(maskNodeIdMap_.size()));
6808     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6809 
6810     for (const auto& entry : maskNodeIdMap_) {
6811         auto targetId = entry.first;
6812         auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(targetId);
6813         auto nodeId = entry.second;
6814         auto node = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(nodeId);
6815         std::string entryLog = "DialogId: " + std::to_string(targetId);
6816         entryLog += ", DialogTag: " + (targetNode ? targetNode->GetTag() : "NULL");
6817         entryLog += ", NodeId: " + std::to_string(nodeId);
6818         entryLog += ", NodeTag: " + (node ? node->GetTag() : "NULL");
6819         DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6820     }
6821 
6822     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6823 }
6824 
DumpModalListInfo() const6825 void OverlayManager::DumpModalListInfo() const
6826 {
6827     DumpLog::GetInstance().Print("ModalList: ");
6828     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Size: " + std::to_string(modalList_.size()));
6829     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "Entries: [");
6830 
6831     for (auto modal = modalList_.begin(); modal != modalList_.end(); ++modal) {
6832         std::string entryLog = "";
6833         auto modalNode = modal->Upgrade();
6834         entryLog += GetMapNodeLog(modalNode, false);
6835         DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6836     }
6837 
6838     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_1, "]");
6839 }
6840 
DumpEntry(const RefPtr<FrameNode> & targetNode,int32_t targetId,const RefPtr<FrameNode> & node) const6841 void OverlayManager::DumpEntry(
6842     const RefPtr<FrameNode>& targetNode, int32_t targetId, const RefPtr<FrameNode>& node) const
6843 {
6844     std::string entryLog = "TargetId: " + std::to_string(targetId);
6845     entryLog += ", TargetTag: " + (targetNode ? targetNode->GetTag() : "NULL");
6846     entryLog += GetMapNodeLog(node);
6847     DumpLog::GetInstance().Print(DUMP_LOG_DEPTH_2, entryLog);
6848 }
6849 
GetMapNodeLog(const RefPtr<FrameNode> & node,bool hasTarget) const6850 std::string OverlayManager::GetMapNodeLog(const RefPtr<FrameNode>& node, bool hasTarget) const
6851 {
6852     CHECK_NULL_RETURN(node, "");
6853     std::string entryLog = (hasTarget ? ", " : "");
6854     entryLog += "NodeId: " + std::to_string(node->GetId()) + ", NodeTag: " + node->GetTag();
6855     return entryLog;
6856 }
6857 
OnUIExtensionWindowSizeChange()6858 void OverlayManager::OnUIExtensionWindowSizeChange()
6859 {
6860     for (auto iter = dialogMap_.begin(); iter != dialogMap_.end(); iter++) {
6861         auto dialogNode = (*iter).second;
6862         CHECK_NULL_VOID(dialogNode);
6863         auto dialogPattern = dialogNode->GetPattern<DialogPattern>();
6864         CHECK_NULL_VOID(dialogPattern);
6865         dialogPattern->InitHostWindowRect();
6866         dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
6867     }
6868 }
6869 
MountToParentWithService(const RefPtr<UINode> & rootNode,const RefPtr<FrameNode> & node)6870 void OverlayManager::MountToParentWithService(const RefPtr<UINode>& rootNode, const RefPtr<FrameNode>& node)
6871 {
6872     CHECK_NULL_VOID(node);
6873     CHECK_NULL_VOID(rootNode);
6874     auto pipeline = rootNode->GetContextRefPtr();
6875     CHECK_NULL_VOID(pipeline);
6876     if (pipeline->GetInstallationFree()) {
6877         // it is in atomicservice
6878         SetNodeBeforeAppbar(rootNode, node);
6879     } else {
6880         node->MountToParent(rootNode);
6881     }
6882 }
6883 
RemoveChildWithService(const RefPtr<UINode> & rootNode,const RefPtr<FrameNode> & node)6884 void OverlayManager::RemoveChildWithService(const RefPtr<UINode>& rootNode, const RefPtr<FrameNode>& node)
6885 {
6886     CHECK_NULL_VOID(rootNode);
6887     CHECK_NULL_VOID(node);
6888     auto parent = node->GetParent();
6889     CHECK_NULL_VOID(parent);
6890     parent->RemoveChild(node);
6891 }
6892 
SetNodeBeforeAppbar(const RefPtr<NG::UINode> & rootNode,const RefPtr<FrameNode> & node)6893 void OverlayManager::SetNodeBeforeAppbar(const RefPtr<NG::UINode>& rootNode, const RefPtr<FrameNode>& node)
6894 {
6895     CHECK_NULL_VOID(rootNode);
6896     CHECK_NULL_VOID(node);
6897     for (auto child : rootNode->GetChildren()) {
6898         CHECK_NULL_VOID(child);
6899         if (child->GetTag() != V2::ATOMIC_SERVICE_ETS_TAG) {
6900             continue;
6901         }
6902         for (auto childNode : child->GetChildren()) {
6903             CHECK_NULL_VOID(childNode);
6904             if (childNode->GetTag() == V2::APP_BAR_ETS_TAG) {
6905                 TAG_LOGD(AceLogTag::ACE_OVERLAY, "setNodeBeforeAppbar AddChildBefore");
6906                 child->AddChildBefore(node, childNode);
6907                 return;
6908             }
6909         }
6910     }
6911 }
6912 
IsRootExpansive() const6913 bool OverlayManager::IsRootExpansive() const
6914 {
6915     auto rootNode = rootNodeWeak_.Upgrade();
6916     CHECK_NULL_RETURN(rootNode, false);
6917     auto pipelineContext = rootNode->GetContext();
6918     CHECK_NULL_RETURN(pipelineContext, false);
6919     auto manager = pipelineContext->GetSafeAreaManager();
6920     CHECK_NULL_RETURN(manager, false);
6921     if (manager->IsFullScreen()) {
6922         // if window is full screen, sheetPage should layout under 8vp + status bar height under parent
6923         return false;
6924     }
6925 
6926     // if page parent is full screen, sheetPage should layout 8vp under parent
6927     auto layoutProp = DynamicCast<FrameNode>(rootNode)->GetLayoutProperty();
6928     CHECK_NULL_RETURN(layoutProp, false);
6929     const auto& opts = layoutProp->GetSafeAreaExpandOpts();
6930     return opts && opts->Expansive();
6931 }
6932 
SetDragNodeNeedClean()6933 void OverlayManager::SetDragNodeNeedClean()
6934 {
6935     auto mainPipeline = PipelineContext::GetMainPipelineContext();
6936     CHECK_NULL_VOID(mainPipeline);
6937     auto dragDropManager = mainPipeline->GetDragDropManager();
6938     CHECK_NULL_VOID(dragDropManager);
6939     dragDropManager->SetIsDragNodeNeedClean(true);
6940 }
6941 } // namespace OHOS::Ace::NG
6942