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