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