1  /*
2   * Copyright (c) 2022-2023 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 "adapter/ohos/entrance/subwindow/subwindow_ohos.h"
17  
18  #include "dm/display_manager.h"
19  #include "interfaces/inner_api/ace/viewport_config.h"
20  #include "render_service_client/core/ui/rs_surface_node.h"
21  #include "window.h"
22  
23  #include "adapter/ohos/entrance/ace_application_info.h"
24  #include "base/geometry/rect.h"
25  #include "base/log/log_wrapper.h"
26  #include "core/components/root/root_element.h"
27  #include "core/components_ng/base/frame_node.h"
28  #include "core/components_ng/base/ui_node.h"
29  #include "core/components_ng/property/property.h"
30  #include "core/components_v2/inspector/inspector_constants.h"
31  #include "core/pipeline_ng/pipeline_context.h"
32  #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
33  #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
34  #endif
35  
36  #include "adapter/ohos/entrance/ace_container.h"
37  #include "adapter/ohos/entrance/ace_view_ohos.h"
38  #include "adapter/ohos/entrance/dialog_container.h"
39  #include "adapter/ohos/entrance/ui_content_impl.h"
40  #include "adapter/ohos/entrance/utils.h"
41  #include "base/log/frame_report.h"
42  #include "base/utils/system_properties.h"
43  #include "base/utils/utils.h"
44  #include "bundlemgr/bundle_mgr_interface.h"
45  #include "core/common/connect_server_manager.h"
46  #include "core/common/container_scope.h"
47  #include "core/common/frontend.h"
48  #include "core/common/hdc_register.h"
49  #include "core/common/text_field_manager.h"
50  #include "core/components/bubble/bubble_component.h"
51  #include "core/components/popup/popup_component.h"
52  #include "core/components_ng/pattern/menu/menu_view.h"
53  #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
54  #include "core/components_ng/pattern/overlay/overlay_manager.h"
55  #include "core/components_ng/render/adapter/rosen_render_context.h"
56  #include "core/components_ng/render/adapter/rosen_window.h"
57  #include "frameworks/bridge/common/utils/engine_helper.h"
58  #include "frameworks/bridge/declarative_frontend/declarative_frontend.h"
59  #include "iservice_registry.h"
60  #ifdef OS_ACCOUNT_EXISTS
61  #include "os_account_manager.h"
62  #endif
63  #include "system_ability_definition.h"
64  
65  namespace OHOS::Ace {
66  namespace {
67  const Rect MIN_WINDOW_HOT_AREA = Rect(0.0f, 0.0f, 1.0f, 1.0f);
68  #ifndef NG_BUILD
69  constexpr int32_t PLATFORM_VERSION_TEN = 10;
70  #endif
71  } // namespace
72  
73  int32_t SubwindowOhos::id_ = 0;
74  static std::atomic<int32_t> gToastDialogId = 0;
75  
76  class SwitchFreeMultiWindowListener : public OHOS::Rosen::ISwitchFreeMultiWindowListener {
77  public:
SwitchFreeMultiWindowListener(int32_t instanceId)78      explicit SwitchFreeMultiWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
79      ~SwitchFreeMultiWindowListener() = default;
80  
OnSwitchFreeMultiWindow(bool enable)81      void OnSwitchFreeMultiWindow(bool enable)
82      {
83          TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Window status changes, freeMultiWindow is %{public}d", enable);
84          auto container = Platform::AceContainer::GetContainer(instanceId_);
85          CHECK_NULL_VOID(container);
86          auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(instanceId_);
87          auto subWindow = SubwindowManager::GetInstance()->GetSubwindow(parentContainerId);
88          CHECK_NULL_VOID(subWindow);
89  
90          auto taskExecutor = container->GetTaskExecutor();
91          CHECK_NULL_VOID(taskExecutor);
92          ContainerScope scope(instanceId_);
93          taskExecutor->PostTask(
94              [subWindow, enable]() {
95                  CHECK_NULL_VOID(subWindow);
96                  subWindow->OnFreeMultiWindowSwitch(enable);
97              },
98              TaskExecutor::TaskType::UI, "ArkUIFreeMultiWindowSwitch");
99      }
100  
101  private:
102      int32_t instanceId_ = -1;
103  };
104  
CreateSubwindow(int32_t instanceId)105  RefPtr<Subwindow> Subwindow::CreateSubwindow(int32_t instanceId)
106  {
107      return AceType::MakeRefPtr<SubwindowOhos>(instanceId);
108  }
109  
SubwindowOhos(int32_t instanceId)110  SubwindowOhos::SubwindowOhos(int32_t instanceId) : windowId_(id_), parentContainerId_(instanceId)
111  {
112      SetSubwindowId(windowId_);
113      id_++;
114      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Create Subwindow, subwindow id %{public}d, container id %{public}d", windowId_,
115          instanceId);
116  }
117  
GetToastRosenType(bool IsSceneBoardEnabled)118  Rosen::WindowType SubwindowOhos::GetToastRosenType(bool IsSceneBoardEnabled)
119  {
120      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW,
121          "SubwindowOhos::GetToastRosenType, windowType: %{public}d, IsSceneBoardEnabled: %{public}d",
122          GetToastWindowType(), IsSceneBoardEnabled);
123      if (GetToastWindowType() == ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW) {
124          if (!IsSceneBoardEnabled) {
125              return Rosen::WindowType::WINDOW_TYPE_TOAST;
126          }
127          return Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
128      } else if (GetToastWindowType() ==  ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW) {
129          return Rosen::WindowType::WINDOW_TYPE_TOAST;
130      } else if (GetToastWindowType() == ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT) {
131          return Rosen::WindowType::WINDOW_TYPE_SYSTEM_FLOAT;
132      }
133      return Rosen::WindowType::WINDOW_TYPE_TOAST;
134  }
135  
SetToastWindowOption(RefPtr<Platform::AceContainer> & parentContainer,OHOS::sptr<OHOS::Rosen::WindowOption> & windowOption,const Rosen::WindowType & toastWindowType,uint32_t mainWindowId)136  void SetToastWindowOption(RefPtr<Platform::AceContainer>& parentContainer,
137      OHOS::sptr<OHOS::Rosen::WindowOption>& windowOption,
138      const Rosen::WindowType& toastWindowType, uint32_t mainWindowId)
139  {
140      if (toastWindowType == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
141          windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
142          windowOption->AddWindowFlag(Rosen::WindowFlag::WINDOW_FLAG_IS_TOAST);
143      }
144      windowOption->SetWindowType(toastWindowType);
145      if (parentContainer->IsUIExtensionWindow()) {
146          auto parentPipeline = parentContainer->GetPipelineContext();
147          CHECK_NULL_VOID(parentPipeline);
148          auto hostWindowId = parentPipeline->GetFocusWindowId();
149          windowOption->SetIsUIExtensionSubWindowFlag(true);
150          windowOption->SetParentId(hostWindowId);
151      } else {
152          windowOption->SetParentId(mainWindowId);
153      }
154  }
155  
SetUIExtensionSubwindowFlag(OHOS::sptr<OHOS::Rosen::WindowOption> & windowOption,bool isAppSubwindow,sptr<OHOS::Rosen::Window> & parentWindow)156  void SetUIExtensionSubwindowFlag(OHOS::sptr<OHOS::Rosen::WindowOption>& windowOption,
157      bool isAppSubwindow, sptr<OHOS::Rosen::Window>& parentWindow)
158  {
159      if (isAppSubwindow && (parentWindow->GetIsUIExtensionFlag() ||
160          parentWindow->GetIsUIExtensionSubWindowFlag())) {
161          windowOption->SetIsUIExtensionSubWindowFlag(true);
162      }
163  }
164  
InitContainer()165  void SubwindowOhos::InitContainer()
166  {
167      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
168      CHECK_NULL_VOID(parentContainer);
169      auto parentPipeline = parentContainer->GetPipelineContext();
170      CHECK_NULL_VOID(parentPipeline);
171      if (!window_) {
172          OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
173          auto parentWindowName = parentContainer->GetWindowName();
174          auto parentWindowId = parentContainer->GetWindowId();
175          sptr<OHOS::Rosen::Window> parentWindow = parentContainer->GetUIWindow(parentContainerId_);
176          CHECK_NULL_VOID(parentWindow);
177          parentWindow_ = parentWindow;
178          auto windowType = parentWindow->GetType();
179          std::string windowTag = "";
180          bool isAppSubwindow = false;
181          if (IsSystemTopMost()) {
182              windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SYSTEM_TOAST);
183          } else if (GetAboveApps()) {
184              auto toastWindowType = GetToastRosenType(parentContainer->IsSceneBoardEnabled());
185              isAppSubwindow = toastWindowType == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
186              auto mainWindowId = GetMainWindowId();
187              SetToastWindowOption(parentContainer, windowOption, toastWindowType, mainWindowId);
188              windowTag = "TOPMOST_TOAST_";
189          } else if (parentContainer->IsScenceBoardWindow() || windowType == Rosen::WindowType::WINDOW_TYPE_DESKTOP) {
190              windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SYSTEM_FLOAT);
191          } else if (windowType == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION) {
192              auto hostWindowId = parentPipeline->GetFocusWindowId();
193              windowOption->SetExtensionTag(true);
194              windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
195              windowOption->SetParentId(hostWindowId);
196              SetUIExtensionHostWindowId(hostWindowId);
197              isAppSubwindow = true;
198          } else if (windowType >= Rosen::WindowType::SYSTEM_WINDOW_BASE) {
199              windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW);
200              windowOption->SetParentId(parentWindowId);
201          } else {
202              windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
203              windowOption->SetParentId(parentWindowId);
204              isAppSubwindow = true;
205          }
206          auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
207          if (!defaultDisplay) {
208              TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "DisplayManager GetDefaultDisplay failed");
209          }
210          CHECK_NULL_VOID(defaultDisplay);
211          windowOption->SetWindowRect({ 0, 0, defaultDisplay->GetWidth(), defaultDisplay->GetHeight() });
212          windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
213          SetUIExtensionSubwindowFlag(windowOption, isAppSubwindow, parentWindow);
214          window_ = OHOS::Rosen::Window::Create("ARK_APP_SUBWINDOW_" + windowTag + parentWindowName +
215              std::to_string(windowId_), windowOption, parentWindow->GetContext());
216          if (!window_) {
217              SetIsRosenWindowCreate(false);
218              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window create failed");
219          }
220          CHECK_NULL_VOID(window_);
221      }
222      std::string url = "";
223      auto subSurface = window_->GetSurfaceNode();
224      CHECK_NULL_VOID(subSurface);
225      subSurface->SetShadowElevation(0.0f);
226      window_->NapiSetUIContent(url, nullptr, nullptr, Rosen::BackupAndRestoreType::NONE);
227      childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(window_->GetWindowId());
228      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Window child containerId : %{public}d", childContainerId_);
229      SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
230  
231      auto container = Platform::AceContainer::GetContainer(childContainerId_);
232      if (!container) {
233          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window get ace container failed");
234      }
235      CHECK_NULL_VOID(container);
236  
237      auto parentToken = parentContainer->GetToken();
238      container->SetToken(parentToken);
239      container->SetWindowId(window_->GetWindowId());
240      container->SetParentId(parentContainerId_);
241      container->GetSettings().SetUsingSharedRuntime(true);
242      container->SetSharedRuntime(parentContainer->GetSharedRuntime());
243      container->Initialize();
244      container->SetAssetManager(parentContainer->GetAssetManager());
245      container->SetResourceConfiguration(parentContainer->GetResourceConfiguration());
246      container->SetPackagePathStr(parentContainer->GetPackagePathStr());
247      container->SetHapPath(parentContainer->GetHapPath());
248      container->SetIsSubContainer(true);
249      container->InitializeSubContainer(parentContainerId_);
250      SetIsRosenWindowCreate(true);
251      ViewportConfig config;
252      // create ace_view
253      auto aceView =
254          Platform::AceViewOhos::CreateView(childContainerId_, false, container->GetSettings().usePlatformAsUIThread);
255      Platform::AceViewOhos::SurfaceCreated(aceView, window_);
256  
257      int32_t width = static_cast<int32_t>(window_->GetRequestRect().width_);
258      int32_t height = static_cast<int32_t>(window_->GetRequestRect().height_);
259      auto density = parentPipeline->GetDensity();
260      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
261          "UIContent Initialize: width: %{public}d, height: %{public}d, density: %{public}lf", width, height, density);
262  
263      Ace::Platform::UIEnvCallback callback = nullptr;
264      // set view
265      Platform::AceContainer::SetView(aceView, density, width, height, window_, callback);
266      Platform::AceViewOhos::SurfaceChanged(aceView, width, height, config.Orientation());
267  
268      auto uiContentImpl = reinterpret_cast<UIContentImpl*>(window_->GetUIContent());
269      CHECK_NULL_VOID(uiContentImpl);
270      uiContentImpl->SetFontScaleAndWeightScale(container, childContainerId_);
271      freeMultiWindowListener_ = new SwitchFreeMultiWindowListener(childContainerId_);
272      window_->RegisterSwitchFreeMultiWindowListener(freeMultiWindowListener_);
273  
274  #ifndef NG_BUILD
275  #ifdef ENABLE_ROSEN_BACKEND
276      if (SystemProperties::GetRosenBackendEnabled()) {
277          rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
278          if (rsUiDirector != nullptr) {
279              rsUiDirector->SetRSSurfaceNode(window_->GetSurfaceNode());
280              auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
281              if (context != nullptr) {
282                  context->SetRSUIDirector(rsUiDirector);
283              }
284              rsUiDirector->Init();
285              TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "UIContent Init Rosen Backend");
286          }
287      }
288  #endif
289  #endif
290  #ifdef NG_BUILD
291      auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(
292          Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
293      CHECK_NULL_VOID(subPipelineContextNG);
294      subPipelineContextNG->SetParentPipeline(parentContainer->GetPipelineContext());
295      subPipelineContextNG->SetupSubRootElement();
296      subPipelineContextNG->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
297      subPipelineContextNG->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
298      subPipelineContextNG->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
299      subPipelineContextNG->SetFollowSystem(parentPipeline->IsFollowSystem());
300      subPipelineContextNG->SetFontScale(parentPipeline->GetFontScale());
301  #else
302      if (container->IsCurrentUseNewPipeline()) {
303          auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(
304              Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
305          CHECK_NULL_VOID(subPipelineContextNG);
306          subPipelineContextNG->SetParentPipeline(parentContainer->GetPipelineContext());
307          subPipelineContextNG->SetupSubRootElement();
308          subPipelineContextNG->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
309          subPipelineContextNG->SetKeyboardAnimationConfig(parentPipeline->GetKeyboardAnimationConfig());
310          subPipelineContextNG->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
311          subPipelineContextNG->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
312          subPipelineContextNG->SetFollowSystem(parentPipeline->IsFollowSystem());
313          subPipelineContextNG->SetFontScale(parentPipeline->GetFontScale());
314          return;
315      }
316      auto subPipelineContext =
317          DynamicCast<PipelineContext>(Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
318      CHECK_NULL_VOID(subPipelineContext);
319      subPipelineContext->SetParentPipeline(parentContainer->GetPipelineContext());
320      subPipelineContext->SetupSubRootElement();
321      subPipelineContext->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
322      subPipelineContext->SetKeyboardAnimationConfig(parentPipeline->GetKeyboardAnimationConfig());
323      subPipelineContext->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
324      subPipelineContext->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
325      subPipelineContext->SetFollowSystem(parentPipeline->IsFollowSystem());
326      subPipelineContext->SetFontScale(parentPipeline->GetFontScale());
327  #endif
328  }
329  
GetChildPipelineContext() const330  RefPtr<PipelineBase> SubwindowOhos::GetChildPipelineContext() const
331  {
332      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
333      CHECK_NULL_RETURN(aceContainer, nullptr);
334      return aceContainer->GetPipelineContext();
335  }
336  
GetInitToastDelayTask(const NG::ToastInfo & toastInfo)337  std::function<void()> SubwindowOhos::GetInitToastDelayTask(const NG::ToastInfo& toastInfo)
338  {
339      return [toastInfo]() {
340          int32_t posX = 0;
341          int32_t posY = 0;
342          int32_t width = 0;
343          int32_t height = 0;
344          float density = 1.0f;
345          auto subwindowOhos =
346              AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
347          CHECK_NULL_VOID(subwindowOhos);
348          subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
349          auto childContainerId = subwindowOhos->GetChildContainerId();
350          auto window = Platform::DialogContainer::GetUIWindow(childContainerId);
351          auto dialogWindow = subwindowOhos->GetDialogWindow();
352          if (!dialogWindow || !window || !subwindowOhos->IsToastWindow()) {
353              bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY, true);
354              if (!ret) {
355                  TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
356                  return;
357              }
358              ret = subwindowOhos->InitToastDialogView(width, height, density);
359              if (!ret) {
360                  TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
361                  return;
362              }
363              subwindowOhos->SetIsToastWindow(true);
364          }
365          childContainerId = subwindowOhos->GetChildContainerId();
366          ContainerScope scope(childContainerId);
367          subwindowOhos->UpdateAceView(width, height, density, childContainerId);
368          TAG_LOGD(AceLogTag::ACE_SUB_WINDOW,
369              "update ace view width : %{public}d,  height : %{public}d, density : %{public}f,childContainerId : "
370              "%{public}d",
371              width, height, density, childContainerId);
372          auto container = Platform::DialogContainer::GetContainer(childContainerId);
373          CHECK_NULL_VOID(container);
374          container->SetFontScaleAndWeightScale(childContainerId);
375          auto ret = subwindowOhos->InitToastServiceConfig();
376          if (!ret) {
377              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast service conf failed");
378          }
379          Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height, true);
380          Platform::DialogContainer::ShowToast(childContainerId, toastInfo.message, toastInfo.duration, toastInfo.bottom);
381      };
382  }
383  
ResizeWindow()384  void SubwindowOhos::ResizeWindow()
385  {
386      auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
387      CHECK_NULL_VOID(defaultDisplay);
388      CHECK_NULL_VOID(window_);
389      auto ret = window_->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
390      if (ret != Rosen::WMError::WM_OK) {
391          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
392              static_cast<int32_t>(ret));
393          return;
394      }
395      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
396          "SubwindowOhos window rect is resized to x: %{public}d, y: %{public}d, width: %{public}u, height: %{public}u",
397          window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
398  }
399  
GetRect()400  NG::RectF SubwindowOhos::GetRect()
401  {
402      NG::RectF rect;
403      CHECK_NULL_RETURN(window_, rect);
404      rect.SetRect(
405          window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
406      return rect;
407  }
408  
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)409  void SubwindowOhos::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
410  {
411      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup enter");
412  #ifndef NG_BUILD
413      ShowWindow();
414      auto stack = GetStack();
415      CHECK_NULL_VOID(stack);
416      auto popup = AceType::DynamicCast<TweenComponent>(newComponent);
417      CHECK_NULL_VOID(popup);
418      stack->PopPopup(popup->GetId());
419      stack->PushComponent(newComponent, disableTouchEvent);
420      auto bubble = AceType::DynamicCast<BubbleComponent>(popup->GetChild());
421      if (bubble) {
422          bubble->SetWeakStack(WeakClaim(RawPtr(stack)));
423      }
424  #endif
425  }
426  
CancelPopup(const std::string & id)427  bool SubwindowOhos::CancelPopup(const std::string& id)
428  {
429      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "cancel popup enter");
430  #ifndef NG_BUILD
431      auto stack = GetStack();
432      CHECK_NULL_RETURN(stack, false);
433      stack->PopPopup(id);
434      auto context = stack->GetContext().Upgrade();
435      CHECK_NULL_RETURN(context, false);
436      context->FlushPipelineImmediately();
437      HideWindow();
438  #endif
439      return true;
440  }
441  
ShowPopupNG(int32_t targetId,const NG::PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)442  void SubwindowOhos::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo,
443      const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
444  {
445      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show popup ng enter, subwindowId: %{public}d", window_->GetWindowId());
446      popupTargetId_ = targetId;
447      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
448      CHECK_NULL_VOID(aceContainer);
449      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
450      CHECK_NULL_VOID(context);
451      auto overlayManager = context->GetOverlayManager();
452      CHECK_NULL_VOID(overlayManager);
453      ResizeWindow();
454      ShowWindow(popupInfo.focusable);
455      CHECK_NULL_VOID(window_);
456      window_->SetTouchable(true);
457      ContainerScope scope(childContainerId_);
458      overlayManager->ShowPopup(targetId, popupInfo, std::move(onWillDismiss), interactiveDismiss);
459      window_->SetFocusable(true);
460  }
461  
HidePopupNG(int32_t targetId)462  void SubwindowOhos::HidePopupNG(int32_t targetId)
463  {
464      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
465          "hide popup ng enter, subwindowId: %{public}d, subwindowName: %{public}s",
466          window_->GetWindowId(), window_->GetWindowName().c_str());
467      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
468      CHECK_NULL_VOID(aceContainer);
469      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
470      CHECK_NULL_VOID(context);
471      auto overlayManager = context->GetOverlayManager();
472      CHECK_NULL_VOID(overlayManager);
473      auto popupInfo = overlayManager->GetPopupInfo(targetId == -1 ? popupTargetId_ : targetId);
474      popupInfo.markNeedUpdate = true;
475      ContainerScope scope(childContainerId_);
476      overlayManager->HidePopup(targetId == -1 ? popupTargetId_ : targetId, popupInfo);
477      context->FlushPipelineImmediately();
478      HideEventColumn();
479      HidePixelMap();
480      HideFilter(false);
481  }
482  
GetPopupInfoNG(int32_t targetId,NG::PopupInfo & popupInfo)483  void SubwindowOhos::GetPopupInfoNG(int32_t targetId, NG::PopupInfo& popupInfo)
484  {
485      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get popup info ng enter");
486      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
487      CHECK_NULL_VOID(aceContainer);
488      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
489      CHECK_NULL_VOID(context);
490      auto overlayManager = context->GetOverlayManager();
491      CHECK_NULL_VOID(overlayManager);
492      popupInfo = overlayManager->GetPopupInfo(targetId);
493  }
494  
GetOverlayManager()495  const RefPtr<NG::OverlayManager> SubwindowOhos::GetOverlayManager()
496  {
497      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
498      CHECK_NULL_RETURN(aceContainer, nullptr);
499      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
500      CHECK_NULL_RETURN(context, nullptr);
501      return context->GetOverlayManager();
502  }
503  
ShowWindow(bool needFocus)504  void SubwindowOhos::ShowWindow(bool needFocus)
505  {
506      CHECK_NULL_VOID(window_);
507      if (isShowed_) {
508          TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u is on display", window_->GetWindowId());
509          if (needFocus) {
510              window_->SetFocusable(needFocus);
511              RequestFocus();
512          }
513          return;
514      }
515      // Set min window hot area so that sub window can transparent event.
516      std::vector<Rosen::Rect> hotAreas;
517      Rosen::Rect rosenRect {};
518      RectConverter(MIN_WINDOW_HOT_AREA, rosenRect);
519      hotAreas.emplace_back(rosenRect);
520      window_->SetTouchHotAreas(hotAreas);
521  
522      window_->SetNeedDefaultAnimation(false);
523      auto ret = window_->SetFocusable(needFocus);
524      if (ret != OHOS::Rosen::WMError::WM_OK) {
525          TAG_LOGE(AceLogTag::ACE_SUB_WINDOW,
526              "subwindow id:%{public}u set focusable %{public}d failed with WMError: %{public}d", window_->GetWindowId(),
527              needFocus, static_cast<int32_t>(ret));
528      }
529      ret = window_->Show(0, false, needFocus);
530      if (ret != OHOS::Rosen::WMError::WM_OK) {
531          TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Show subwindow id:%{public}u failed with WMError: %{public}d",
532              window_->GetWindowId(), static_cast<int32_t>(ret));
533          return;
534      }
535      if (needFocus) {
536          RequestFocus();
537      }
538  
539      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
540      CHECK_NULL_VOID(aceContainer);
541      auto context = aceContainer->GetPipelineContext();
542      CHECK_NULL_VOID(context);
543      AccessibilityEvent event;
544      event.type = AccessibilityEventType::PAGE_CHANGE;
545      event.windowId = context->GetWindowId();
546      event.windowChangeTypes = WINDOW_UPDATE_ADDED;
547      context->SendEventToAccessibility(event);
548      isShowed_ = true;
549      SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
550  }
551  
HideWindow()552  void SubwindowOhos::HideWindow()
553  {
554      CHECK_NULL_VOID(window_);
555      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Hide the subwindow %{public}s", window_->GetWindowName().c_str());
556  
557      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
558      CHECK_NULL_VOID(aceContainer);
559  
560  #ifdef NG_BUILD
561      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
562      CHECK_NULL_VOID(context);
563      auto rootNode = context->GetRootElement();
564      CHECK_NULL_VOID(rootNode);
565      if (!rootNode->GetChildren().empty() &&
566          !(rootNode->GetChildren().size() == 1 && rootNode->GetLastChild()->GetTag() == V2::KEYBOARD_ETS_TAG)) {
567          auto lastChildId = rootNode->GetLastChild()->GetId();
568          auto iter = hotAreasMap_.find(lastChildId);
569          if (iter != hotAreasMap_.end()) {
570              auto hotAreaRect = iter->second;
571              OHOS::Rosen::WMError ret = window_->SetTouchHotAreas(hotAreaRect);
572              if (ret != OHOS::Rosen::WMError::WM_OK) {
573                  TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Set hot areas failed with errCode: %{public}d",
574                      static_cast<int32_t>(ret));
575              }
576          }
577          return;
578      }
579      auto focusHub = rootNode->GetFocusHub();
580      CHECK_NULL_VOID(focusHub);
581      focusHub->SetIsDefaultHasFocused(false);
582      context->SetIsFocusActive(false);
583  #else
584      if (Container::IsCurrentUseNewPipeline()) {
585          auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
586          CHECK_NULL_VOID(context);
587          auto rootNode = context->GetRootElement();
588          CHECK_NULL_VOID(rootNode);
589          if (!rootNode->GetChildren().empty() &&
590              !(rootNode->GetChildren().size() == 1 && rootNode->GetLastChild()->GetTag() == V2::KEYBOARD_ETS_TAG)) {
591              TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow has other node, the last child is %{public}s",
592                  rootNode->GetLastChild()->GetTag().c_str());
593              return;
594          }
595          auto focusHub = rootNode->GetFocusHub();
596          CHECK_NULL_VOID(focusHub);
597          focusHub->SetIsDefaultHasFocused(false);
598          context->SetIsFocusActive(false);
599      } else {
600          auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
601          CHECK_NULL_VOID(context);
602          auto rootNode = context->GetRootElement();
603          CHECK_NULL_VOID(rootNode);
604          rootNode->SetIsDefaultHasFocused(false);
605      }
606  #endif
607  
608      if (!window_->IsFocused()) {
609          ContainerModalUnFocus();
610      }
611  
612      OHOS::Rosen::WMError ret = window_->Hide();
613      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
614      CHECK_NULL_VOID(parentContainer);
615      if (parentContainer->IsScenceBoardWindow()) {
616          window_->SetTouchable(true);
617      }
618  
619      if (ret != OHOS::Rosen::WMError::WM_OK) {
620          TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Hide window failed with errCode: %{public}d", static_cast<int32_t>(ret));
621          return;
622      }
623      isShowed_ = false;
624      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Hide the subwindow successfully.");
625  #ifndef NG_BUILD
626      auto context = aceContainer->GetPipelineContext();
627      CHECK_NULL_VOID(context);
628  #endif
629      AccessibilityEvent event;
630      event.type = AccessibilityEventType::PAGE_CHANGE;
631      event.windowId = context->GetWindowId();
632      event.windowChangeTypes = WINDOW_UPDATE_REMOVED;
633      context->SendEventToAccessibility(event);
634  }
635  
ContainerModalUnFocus()636  void SubwindowOhos::ContainerModalUnFocus()
637  {
638      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
639      CHECK_NULL_VOID(parentContainer);
640      auto parentWindowName = parentContainer->GetWindowName();
641      sptr<OHOS::Rosen::Window> parentWindow = OHOS::Rosen::Window::Find(parentWindowName);
642      CHECK_NULL_VOID(parentWindow);
643      if (parentWindow->GetFocusable() && !parentWindow->IsFocused()) {
644          auto pipelineContext = parentContainer->GetPipelineContext();
645          CHECK_NULL_VOID(pipelineContext);
646          pipelineContext->ContainerModalUnFocus();
647      }
648  }
649  
AddMenu(const RefPtr<Component> & newComponent)650  void SubwindowOhos::AddMenu(const RefPtr<Component>& newComponent)
651  {
652      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "add menu enter");
653  #ifndef NG_BUILD
654      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow push new component start.");
655      auto stack = GetStack();
656      CHECK_NULL_VOID(stack);
657      // Push the component
658      stack->PopMenu();
659      stack->PushComponent(newComponent);
660      popup_ = AceType::DynamicCast<SelectPopupComponent>(newComponent);
661  #endif
662  }
663  
ClearMenu()664  void SubwindowOhos::ClearMenu()
665  {
666      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu enter");
667      if (haveDialog_) {
668          return;
669      }
670  #ifndef NG_BUILD
671      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow Clear menu start.");
672      auto stack = GetStack();
673      CHECK_NULL_VOID(stack);
674      // Pop the component
675      stack->PopMenu();
676      auto context = stack->GetContext().Upgrade();
677      CHECK_NULL_VOID(context);
678      context->FlushPipelineImmediately();
679      HideWindow();
680  #endif
681  }
682  
ShowPreviewNG(bool isStartDraggingFromSubWindow)683  bool SubwindowOhos::ShowPreviewNG(bool isStartDraggingFromSubWindow)
684  {
685      CHECK_NULL_RETURN(window_, false);
686      ShowWindow(false);
687      ResizeWindow();
688      if (!isStartDraggingFromSubWindow) {
689          window_->SetTouchable(false);
690      }
691      return true;
692  }
693  
HidePreviewNG()694  void SubwindowOhos::HidePreviewNG()
695  {
696      auto overlayManager = GetOverlayManager();
697      CHECK_NULL_VOID(overlayManager);
698      overlayManager->RemovePixelMap();
699      overlayManager->RemovePreviewBadgeNode();
700      overlayManager->RemoveGatherNode();
701      overlayManager->RemoveEventColumn();
702      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
703      CHECK_NULL_VOID(aceContainer);
704      auto pipeline = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
705      CHECK_NULL_VOID(pipeline);
706      pipeline->FlushPipelineImmediately();
707      HideSubWindowNG();
708  }
709  
ShowMenuNG(const RefPtr<NG::FrameNode> customNode,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)710  void SubwindowOhos::ShowMenuNG(const RefPtr<NG::FrameNode> customNode, const NG::MenuParam& menuParam,
711      const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
712  {
713      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
714      CHECK_NULL_VOID(customNode);
715      CHECK_NULL_VOID(targetNode);
716      ContainerScope scope(childContainerId_);
717      auto container = Container::Current();
718      CHECK_NULL_VOID(container);
719      auto context = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
720      CHECK_NULL_VOID(context);
721      auto overlay = context->GetOverlayManager();
722      CHECK_NULL_VOID(overlay);
723      auto menuNode = customNode;
724      if (customNode->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
725          menuNode = NG::MenuView::Create(customNode, targetNode->GetId(), targetNode->GetTag(), menuParam, true);
726          auto menuWrapperPattern = menuNode->GetPattern<NG::MenuWrapperPattern>();
727          CHECK_NULL_VOID(menuWrapperPattern);
728          menuWrapperPattern->RegisterMenuCallback(menuNode, menuParam);
729          menuWrapperPattern->SetMenuTransitionEffect(menuNode, menuParam);
730      }
731      ShowWindow();
732      ResizeWindow();
733      CHECK_NULL_VOID(window_);
734      window_->SetTouchable(true);
735      overlay->ShowMenuInSubWindow(targetNode->GetId(), offset, menuNode);
736  }
737  
ShowMenuNG(std::function<void ()> && buildFunc,std::function<void ()> && previewBuildFunc,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)738  void SubwindowOhos::ShowMenuNG(std::function<void()>&& buildFunc, std::function<void()>&& previewBuildFunc,
739      const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
740  {
741      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
742      ContainerScope scope(childContainerId_);
743      auto container = Container::Current();
744      CHECK_NULL_VOID(container);
745      auto context = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
746      CHECK_NULL_VOID(context);
747      auto overlay = context->GetOverlayManager();
748      CHECK_NULL_VOID(overlay);
749      ShowWindow();
750      ResizeWindow();
751      CHECK_NULL_VOID(window_);
752      window_->SetTouchable(true);
753      NG::ScopedViewStackProcessor builderViewStackProcessor;
754      buildFunc();
755      auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
756      RefPtr<NG::UINode> previewCustomNode;
757      if (previewBuildFunc && menuParam.previewMode == MenuPreviewMode::CUSTOM) {
758          previewBuildFunc();
759          previewCustomNode = NG::ViewStackProcessor::GetInstance()->Finish();
760      }
761      auto menuNode =
762          NG::MenuView::Create(customNode, targetNode->GetId(), targetNode->GetTag(), menuParam, true, previewCustomNode);
763      auto menuWrapperPattern = menuNode->GetPattern<NG::MenuWrapperPattern>();
764      CHECK_NULL_VOID(menuWrapperPattern);
765      menuWrapperPattern->RegisterMenuCallback(menuNode, menuParam);
766      menuWrapperPattern->SetMenuTransitionEffect(menuNode, menuParam);
767      overlay->ShowMenuInSubWindow(targetNode->GetId(), offset, menuNode);
768  }
769  
HideMenuNG(bool showPreviewAnimation,bool startDrag)770  void SubwindowOhos::HideMenuNG(bool showPreviewAnimation, bool startDrag)
771  {
772      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
773      if (!isShowed_) {
774          return;
775      }
776      ContainerScope scope(childContainerId_);
777      auto container = Container::Current();
778      CHECK_NULL_VOID(container);
779      auto context = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
780      CHECK_NULL_VOID(context);
781      auto overlay = context->GetOverlayManager();
782      CHECK_NULL_VOID(overlay);
783      overlay->HideMenuInSubWindow(showPreviewAnimation, startDrag);
784      HideEventColumn();
785      HidePixelMap(startDrag, 0, 0, false);
786      HideFilter(false);
787      HideFilter(true);
788  }
789  
HideMenuNG(const RefPtr<NG::FrameNode> & menu,int32_t targetId)790  void SubwindowOhos::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)
791  {
792      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
793      if (!isShowed_) {
794          return;
795      }
796      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow hide menu for target id %{public}d", targetId);
797      targetId_ = targetId;
798      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
799      CHECK_NULL_VOID(aceContainer);
800      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
801      CHECK_NULL_VOID(context);
802      auto overlay = context->GetOverlayManager();
803      CHECK_NULL_VOID(overlay);
804      overlay->HideMenuInSubWindow(menu, targetId_);
805      HideEventColumn();
806      HidePixelMap(false, 0, 0, false);
807      HideFilter(false);
808      HideFilter(true);
809  }
810  
UpdatePreviewPosition()811  void SubwindowOhos::UpdatePreviewPosition()
812  {
813      ContainerScope scope(childContainerId_);
814      auto pipelineContext = NG::PipelineContext::GetCurrentContext();
815      CHECK_NULL_VOID(pipelineContext);
816      auto overlay = pipelineContext->GetOverlayManager();
817      CHECK_NULL_VOID(overlay);
818      if (overlay->GetHasPixelMap()) {
819          return;
820      }
821      overlay->UpdatePixelMapPosition(true);
822  }
823  
GetMenuPreviewCenter(NG::OffsetF & offset)824  bool SubwindowOhos::GetMenuPreviewCenter(NG::OffsetF& offset)
825  {
826      ContainerScope scope(childContainerId_);
827      auto pipelineContext = NG::PipelineContext::GetCurrentContext();
828      CHECK_NULL_RETURN(pipelineContext, false);
829      auto overlay = pipelineContext->GetOverlayManager();
830      CHECK_NULL_RETURN(overlay, false);
831      return overlay->GetMenuPreviewCenter(offset);
832  }
833  
UpdateHideMenuOffsetNG(const NG::OffsetF & offset,float menuScale,bool isRedragStart,int32_t menuWrapperId)834  void SubwindowOhos::UpdateHideMenuOffsetNG(
835      const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
836  {
837      ContainerScope scope(childContainerId_);
838      auto pipelineContext = NG::PipelineContext::GetCurrentContext();
839      CHECK_NULL_VOID(pipelineContext);
840      auto overlay = pipelineContext->GetOverlayManager();
841      CHECK_NULL_VOID(overlay);
842      if (overlay->IsContextMenuDragHideFinished()) {
843          return;
844      }
845      overlay->UpdateContextMenuDisappearPosition(offset, menuScale, isRedragStart, menuWrapperId);
846  }
847  
ContextMenuSwitchDragPreviewAnimationtNG(const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)848  void SubwindowOhos::ContextMenuSwitchDragPreviewAnimationtNG(const RefPtr<NG::FrameNode>& dragPreviewNode,
849      const NG::OffsetF& offset)
850  {
851      CHECK_NULL_VOID(dragPreviewNode);
852      ContainerScope scope(childContainerId_);
853      auto pipelineContext = NG::PipelineContext::GetCurrentContext();
854      CHECK_NULL_VOID(pipelineContext);
855      auto overlay = pipelineContext->GetOverlayManager();
856      CHECK_NULL_VOID(overlay);
857      overlay->ContextMenuSwitchDragPreviewAnimation(dragPreviewNode, offset);
858  }
859  
ClearMenuNG(int32_t targetId,bool inWindow,bool showAnimation)860  void SubwindowOhos::ClearMenuNG(int32_t targetId, bool inWindow, bool showAnimation)
861  {
862      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "clear menu ng enter");
863      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
864      CHECK_NULL_VOID(aceContainer);
865      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
866      CHECK_NULL_VOID(context);
867      auto overlay = context->GetOverlayManager();
868      CHECK_NULL_VOID(overlay);
869      if (showAnimation) {
870          overlay->CleanMenuInSubWindowWithAnimation();
871          HideFilter(true);
872      } else {
873          overlay->CleanMenuInSubWindow(targetId);
874          overlay->RemoveFilter();
875      }
876      overlay->EraseMenuInfo(targetId);
877      HideWindow();
878      context->FlushPipelineImmediately();
879      if (inWindow) {
880          HideEventColumn();
881      }
882      HidePixelMap(false, 0, 0, false);
883      HideFilter(false);
884  }
885  
ClearPopupNG()886  void SubwindowOhos::ClearPopupNG()
887  {
888      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear popup ng enter");
889      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
890      CHECK_NULL_VOID(aceContainer);
891      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
892      CHECK_NULL_VOID(context);
893      auto overlay = context->GetOverlayManager();
894      CHECK_NULL_VOID(overlay);
895      overlay->CleanPopupInSubWindow();
896      HideWindow();
897      context->FlushPipelineImmediately();
898  }
899  
ShowMenu(const RefPtr<Component> & newComponent)900  void SubwindowOhos::ShowMenu(const RefPtr<Component>& newComponent)
901  {
902      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu enter");
903      ShowWindow();
904      AddMenu(newComponent);
905  }
906  
CloseMenu()907  void SubwindowOhos::CloseMenu()
908  {
909      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close menu enter");
910  #ifndef NG_BUILD
911      if (!isShowed_) {
912          return;
913      }
914      if (popup_) {
915          popup_->CloseContextMenu();
916      }
917  #endif
918  }
919  
GetStack()920  RefPtr<StackElement> SubwindowOhos::GetStack()
921  {
922  #ifndef NG_BUILD
923      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
924      CHECK_NULL_RETURN(aceContainer, nullptr);
925  
926      auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
927      CHECK_NULL_RETURN(context, nullptr);
928      return context->GetLastStack();
929  #else
930      return nullptr;
931  #endif
932  }
933  
DeleteHotAreas(int32_t nodeId)934  void SubwindowOhos::DeleteHotAreas(int32_t nodeId)
935  {
936      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "delete hot area %{public}d", nodeId);
937      hotAreasMap_.erase(nodeId);
938  
939      std::vector<Rosen::Rect> hotAreas;
940      for (auto it = hotAreasMap_.begin(); it != hotAreasMap_.end(); it++) {
941          hotAreas.insert(hotAreas.end(), it->second.begin(), it->second.end());
942      }
943      CHECK_NULL_VOID(window_);
944      window_->SetTouchHotAreas(hotAreas);
945  }
946  
SetHotAreas(const std::vector<Rect> & rects,int32_t nodeId)947  void SubwindowOhos::SetHotAreas(const std::vector<Rect>& rects, int32_t nodeId)
948  {
949      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot areas enter");
950      CHECK_NULL_VOID(window_);
951  
952      std::vector<Rosen::Rect> hotAreas;
953      Rosen::Rect rosenRect {};
954  
955      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "set hot area %{public}d", nodeId);
956      for (const auto& rect : rects) {
957          TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot area rect %{public}s", rect.ToString().c_str());
958          RectConverter(rect, rosenRect);
959          hotAreas.emplace_back(rosenRect);
960      }
961      if (nodeId >= 0) {
962          hotAreasMap_[nodeId] = hotAreas;
963      }
964  
965      std::vector<Rosen::Rect> hotAreasNow;
966      for (auto it = hotAreasMap_.begin(); it != hotAreasMap_.end(); it++) {
967          hotAreasNow.insert(hotAreasNow.end(), it->second.begin(), it->second.end());
968      }
969      window_->SetTouchHotAreas(hotAreasNow);
970  }
971  
RectConverter(const Rect & rect,Rosen::Rect & rosenRect)972  void SubwindowOhos::RectConverter(const Rect& rect, Rosen::Rect& rosenRect)
973  {
974      rosenRect.posX_ = static_cast<int>(rect.GetOffset().GetX());
975      rosenRect.posY_ = static_cast<int>(rect.GetOffset().GetY());
976      rosenRect.width_ = static_cast<uint32_t>(rect.GetSize().Width());
977      rosenRect.height_ = static_cast<uint32_t>(rect.GetSize().Height());
978      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
979          "Convert rect to rosenRect, x is %{public}d, y is %{public}d, width is %{public}d, height is %{public}d",
980          rosenRect.posX_, rosenRect.posY_, rosenRect.width_, rosenRect.height_);
981  }
982  
ShowDialogNG(const DialogProperties & dialogProps,std::function<void ()> && buildFunc)983  RefPtr<NG::FrameNode> SubwindowOhos::ShowDialogNG(
984      const DialogProperties& dialogProps, std::function<void()>&& buildFunc)
985  {
986      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
987      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
988      CHECK_NULL_RETURN(aceContainer, nullptr);
989      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
990      CHECK_NULL_RETURN(context, nullptr);
991      auto overlay = context->GetOverlayManager();
992      CHECK_NULL_RETURN(overlay, nullptr);
993      std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
994      int dialogMapSize = static_cast<int>(DialogMap.size());
995      if (dialogMapSize == 0) {
996          auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
997          CHECK_NULL_RETURN(parentAceContainer, nullptr);
998          auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
999          CHECK_NULL_RETURN(parentcontext, nullptr);
1000          auto parentOverlay = parentcontext->GetOverlayManager();
1001          CHECK_NULL_RETURN(parentOverlay, nullptr);
1002          parentOverlay->SetSubWindowId(SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1003      }
1004      SubwindowManager::GetInstance()->SetDialogSubWindowId(
1005          SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1006      ShowWindow();
1007      CHECK_NULL_RETURN(window_, nullptr);
1008      window_->SetFullScreen(true);
1009      window_->SetTouchable(true);
1010      ResizeWindow();
1011      ContainerScope scope(childContainerId_);
1012      auto dialog = overlay->ShowDialog(dialogProps, std::move(buildFunc));
1013      CHECK_NULL_RETURN(dialog, nullptr);
1014      haveDialog_ = true;
1015      return dialog;
1016  }
1017  
ShowDialogNGWithNode(const DialogProperties & dialogProps,const RefPtr<NG::UINode> & customNode)1018  RefPtr<NG::FrameNode> SubwindowOhos::ShowDialogNGWithNode(
1019      const DialogProperties& dialogProps, const RefPtr<NG::UINode>& customNode)
1020  {
1021      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
1022      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1023      CHECK_NULL_RETURN(aceContainer, nullptr);
1024      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1025      CHECK_NULL_RETURN(context, nullptr);
1026      auto overlay = context->GetOverlayManager();
1027      CHECK_NULL_RETURN(overlay, nullptr);
1028      std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
1029      int dialogMapSize = static_cast<int>(DialogMap.size());
1030      if (dialogMapSize == 0) {
1031          auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1032          CHECK_NULL_RETURN(parentAceContainer, nullptr);
1033          auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1034          CHECK_NULL_RETURN(parentcontext, nullptr);
1035          auto parentOverlay = parentcontext->GetOverlayManager();
1036          CHECK_NULL_RETURN(parentOverlay, nullptr);
1037          parentOverlay->SetSubWindowId(SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1038      }
1039      SubwindowManager::GetInstance()->SetDialogSubWindowId(
1040          SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1041      ShowWindow();
1042      CHECK_NULL_RETURN(window_, nullptr);
1043      window_->SetFullScreen(true);
1044      window_->SetTouchable(true);
1045      ResizeWindow();
1046      ContainerScope scope(childContainerId_);
1047      auto dialog = overlay->ShowDialogWithNode(dialogProps, customNode);
1048      CHECK_NULL_RETURN(dialog, nullptr);
1049      haveDialog_ = true;
1050      return dialog;
1051  }
1052  
CloseDialogNG(const RefPtr<NG::FrameNode> & dialogNode)1053  void SubwindowOhos::CloseDialogNG(const RefPtr<NG::FrameNode>& dialogNode)
1054  {
1055      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog ng enter");
1056      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1057      CHECK_NULL_VOID(aceContainer);
1058      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1059      CHECK_NULL_VOID(context);
1060      auto overlay = context->GetOverlayManager();
1061      CHECK_NULL_VOID(overlay);
1062      ContainerScope scope(childContainerId_);
1063      return overlay->CloseDialog(dialogNode);
1064  }
1065  
OpenCustomDialogNG(const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)1066  void SubwindowOhos::OpenCustomDialogNG(const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
1067  {
1068      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "open customDialog ng subwindow enter");
1069      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1070      CHECK_NULL_VOID(aceContainer);
1071      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1072      CHECK_NULL_VOID(context);
1073      auto overlay = context->GetOverlayManager();
1074      CHECK_NULL_VOID(overlay);
1075      std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
1076      int dialogMapSize = static_cast<int>(DialogMap.size());
1077      if (dialogMapSize == 0) {
1078          auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1079          CHECK_NULL_VOID(parentAceContainer);
1080          auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1081          CHECK_NULL_VOID(parentcontext);
1082          auto parentOverlay = parentcontext->GetOverlayManager();
1083          CHECK_NULL_VOID(parentOverlay);
1084          parentOverlay->SetSubWindowId(SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1085          TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "overlay in parent container %{public}d, SetSubWindowId %{public}d",
1086              parentContainerId_, GetSubwindowId());
1087      }
1088      SubwindowManager::GetInstance()->SetDialogSubWindowId(
1089          SubwindowManager::GetInstance()->GetDialogSubwindowInstanceId(GetSubwindowId()));
1090      ShowWindow();
1091      CHECK_NULL_VOID(window_);
1092      window_->SetFullScreen(true);
1093      window_->SetTouchable(true);
1094      ResizeWindow();
1095      ContainerScope scope(childContainerId_);
1096      overlay->OpenCustomDialog(dialogProps, std::move(callback));
1097      haveDialog_ = true;
1098  }
1099  
CloseCustomDialogNG(int32_t dialogId)1100  void SubwindowOhos::CloseCustomDialogNG(int32_t dialogId)
1101  {
1102      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng subwindow enter, child container id %{public}d",
1103          childContainerId_);
1104      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1105      CHECK_NULL_VOID(aceContainer);
1106      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1107      CHECK_NULL_VOID(context);
1108      auto overlay = context->GetOverlayManager();
1109      CHECK_NULL_VOID(overlay);
1110      ContainerScope scope(childContainerId_);
1111      return overlay->CloseCustomDialog(dialogId);
1112  }
1113  
CloseCustomDialogNG(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)1114  void SubwindowOhos::CloseCustomDialogNG(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
1115  {
1116      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng subwindow enter, child container id %{public}d",
1117          childContainerId_);
1118      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1119      CHECK_NULL_VOID(aceContainer);
1120      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1121      CHECK_NULL_VOID(context);
1122      auto overlay = context->GetOverlayManager();
1123      CHECK_NULL_VOID(overlay);
1124      ContainerScope scope(childContainerId_);
1125      return overlay->CloseCustomDialog(node, std::move(callback));
1126  }
1127  
UpdateCustomDialogNG(const WeakPtr<NG::UINode> & node,const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)1128  void SubwindowOhos::UpdateCustomDialogNG(
1129      const WeakPtr<NG::UINode>& node, const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
1130  {
1131      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "update customDialog ng subwindow enter");
1132      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1133      CHECK_NULL_VOID(aceContainer);
1134      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1135      CHECK_NULL_VOID(context);
1136      auto overlay = context->GetOverlayManager();
1137      CHECK_NULL_VOID(overlay);
1138      ContainerScope scope(childContainerId_);
1139      return overlay->UpdateCustomDialog(node, dialogProps, std::move(callback));
1140  }
1141  
HideSubWindowNG()1142  void SubwindowOhos::HideSubWindowNG()
1143  {
1144      ContainerScope scope(childContainerId_);
1145      auto container = Container::Current();
1146      CHECK_NULL_VOID(container);
1147      if (container->IsDialogContainer()) {
1148          if (IsToastWindow()) {
1149              Platform::DialogContainer::HideWindow(Container::CurrentId());
1150          } else {
1151              Platform::DialogContainer::CloseWindow(Container::CurrentId());
1152              Platform::DialogContainer::DestroyContainer(Container::CurrentId());
1153          }
1154      } else {
1155          HideWindow();
1156      }
1157  }
1158  
GetToastDialogWindowProperty(int32_t & width,int32_t & height,int32_t & posX,int32_t & posY,float & density) const1159  void SubwindowOhos::GetToastDialogWindowProperty(
1160      int32_t& width, int32_t& height, int32_t& posX, int32_t& posY, float& density) const
1161  {
1162      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get toast dialog window property enter");
1163      auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
1164      if (defaultDisplay) {
1165          posX = 0;
1166          posY = 0;
1167          width = defaultDisplay->GetWidth();
1168          height = defaultDisplay->GetHeight();
1169          density = defaultDisplay->GetVirtualPixelRatio();
1170      }
1171      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
1172          "Toast posX: %{public}d, posY: %{public}d, width: %{public}d, height: %{public}d, density: %{public}f", posX,
1173          posY, width, height, density);
1174  }
1175  
InitToastDialogWindow(int32_t width,int32_t height,int32_t posX,int32_t posY,bool isToast)1176  bool SubwindowOhos::InitToastDialogWindow(int32_t width, int32_t height, int32_t posX, int32_t posY, bool isToast)
1177  {
1178      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window enter");
1179      OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
1180      if (isToast) {
1181          auto windowType =
1182              IsSystemTopMost() ? Rosen::WindowType::WINDOW_TYPE_SYSTEM_TOAST : Rosen::WindowType::WINDOW_TYPE_TOAST;
1183          windowOption->SetWindowType(windowType);
1184      } else {
1185          windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1186      }
1187      windowOption->SetWindowRect({ posX, posY, width, height });
1188      windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
1189      windowOption->SetFocusable(!isToast);
1190      int32_t dialogId = gToastDialogId.fetch_add(1, std::memory_order_relaxed);
1191      std::string windowName = "ARK_APP_SUBWINDOW_TOAST_DIALOG_" + std::to_string(dialogId);
1192      if (isToast) {
1193          auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
1194          dialogWindow_ = OHOS::Rosen::Window::Create(windowName, windowOption, context);
1195      } else {
1196          dialogWindow_ = OHOS::Rosen::Window::Create(windowName, windowOption);
1197      }
1198      CHECK_NULL_RETURN(dialogWindow_, false);
1199      dialogWindow_->SetLayoutFullScreen(true);
1200      return true;
1201  }
1202  
InitToastDialogView(int32_t width,int32_t height,float density)1203  bool SubwindowOhos::InitToastDialogView(int32_t width, int32_t height, float density)
1204  {
1205      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view enter");
1206  #ifndef NG_BUILD
1207      dialogWindow_->NapiSetUIContent("", nullptr, nullptr, Rosen::BackupAndRestoreType::NONE);
1208      childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(dialogWindow_->GetWindowId());
1209      SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
1210      ContainerScope scope(childContainerId_);
1211  
1212      auto container = Platform::DialogContainer::GetContainer(childContainerId_);
1213      CHECK_NULL_RETURN(container, false);
1214      // create ace_view
1215      auto aceView = Platform::AceViewOhos::CreateView(childContainerId_, true, true);
1216      Platform::AceViewOhos::SurfaceCreated(aceView, dialogWindow_);
1217      // set view
1218      Platform::DialogContainer::SetView(aceView, density, width, height, dialogWindow_);
1219      Ace::Platform::DialogContainer::SetUIWindow(childContainerId_, dialogWindow_);
1220      ViewportConfig config(width, height, density);
1221      Platform::AceViewOhos::SetViewportMetrics(aceView, config);
1222      Platform::AceViewOhos::SurfaceChanged(aceView, width, height, 0);
1223  
1224  #ifdef ENABLE_ROSEN_BACKEND
1225      if (SystemProperties::GetRosenBackendEnabled()) {
1226          rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
1227          if (rsUiDirector != nullptr) {
1228              rsUiDirector->SetRSSurfaceNode(dialogWindow_->GetSurfaceNode());
1229              auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
1230              if (context != nullptr) {
1231                  context->SetRSUIDirector(rsUiDirector);
1232              }
1233              rsUiDirector->Init();
1234          }
1235      }
1236  #endif
1237  
1238      auto pipelineContext = container->GetPipelineContext();
1239      CHECK_NULL_RETURN(pipelineContext, false);
1240      pipelineContext->SetupRootElement();
1241      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1242      if (parentContainer) {
1243          auto parentPipeline = parentContainer->GetPipelineContext();
1244          CHECK_NULL_RETURN(parentPipeline, false);
1245          pipelineContext->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
1246      } else {
1247          pipelineContext->SetMinPlatformVersion(PLATFORM_VERSION_TEN);
1248      }
1249      return true;
1250  #else
1251      return true;
1252  #endif
1253  }
1254  
InitToastServiceConfig()1255  bool SubwindowOhos::InitToastServiceConfig()
1256  {
1257      auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
1258      CHECK_NULL_RETURN(context, false);
1259      auto config = context->GetConfiguration();
1260      CHECK_NULL_RETURN(config, false);
1261      auto maxAppFontScale = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_MAX_SCALE);
1262      auto followSystem = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_SIZE_SCALE);
1263      auto container = Platform::DialogContainer::GetContainer(childContainerId_);
1264      CHECK_NULL_RETURN(container, false);
1265      auto pipelineContext = container->GetPipelineContext();
1266      CHECK_NULL_RETURN(pipelineContext, false);
1267      auto isFollowSystem = followSystem == "followSystem";
1268      if (!followSystem.empty()) {
1269          pipelineContext->SetFollowSystem(isFollowSystem);
1270      }
1271      if (!maxAppFontScale.empty()) {
1272          pipelineContext->SetMaxAppFontScale(StringUtils::StringToFloat(maxAppFontScale));
1273      }
1274      if (!isFollowSystem) {
1275          pipelineContext->SetFontScale(1.0f);
1276      }
1277      auto fontScale = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE);
1278      if (!fontScale.empty()) {
1279          pipelineContext->SetFontScale(StringUtils::StringToFloat(fontScale));
1280      }
1281  
1282      return true;
1283  }
1284  
CreateEventRunner()1285  bool SubwindowOhos::CreateEventRunner()
1286  {
1287      if (!eventLoop_) {
1288          eventLoop_ = AppExecFwk::EventRunner::Create("Subwindow_Toast_Dialog");
1289          CHECK_NULL_RETURN(eventLoop_, false);
1290          handler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
1291          CHECK_NULL_RETURN(handler_, false);
1292      }
1293      return true;
1294  }
1295  
ClearToast()1296  void SubwindowOhos::ClearToast()
1297  {
1298      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast enter");
1299      if (!IsToastWindow()) {
1300          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "default toast needs not to be clear");
1301          return;
1302      }
1303      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1304      CHECK_NULL_VOID(aceContainer);
1305      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1306      CHECK_NULL_VOID(context);
1307      auto overlayManager = context->GetOverlayManager();
1308      CHECK_NULL_VOID(overlayManager);
1309      ContainerScope scope(childContainerId_);
1310      overlayManager->ClearToast();
1311      context->FlushPipelineImmediately();
1312      HideWindow();
1313  }
1314  
ShowToastForAbility(const NG::ToastInfo & toastInfo)1315  void SubwindowOhos::ShowToastForAbility(const NG::ToastInfo& toastInfo)
1316  {
1317      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast for ability enter, containerId : %{public}d", childContainerId_);
1318      SetIsToastWindow(
1319          toastInfo.showMode == NG::ToastShowMode::TOP_MOST || toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
1320      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1321      if (!aceContainer) {
1322          TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get container failed, child containerId : %{public}d", childContainerId_);
1323          return;
1324      }
1325  
1326      auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1327      RefPtr<Framework::FrontendDelegate> delegate;
1328      if (!engine) {
1329          auto frontend = AceType::DynamicCast<DeclarativeFrontend>(aceContainer->GetFrontend());
1330          CHECK_NULL_VOID(frontend);
1331          delegate = frontend->GetDelegate();
1332          if (!delegate) {
1333              TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get engine failed, containerId : %{public}d",
1334                  aceContainer->GetInstanceId());
1335              return;
1336          }
1337      } else {
1338          delegate = engine->GetFrontend();
1339          if (!delegate) {
1340              TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get frontend failed, child containerId : %{public}d",
1341                  childContainerId_);
1342              return;
1343          }
1344      }
1345      ContainerScope scope(childContainerId_);
1346      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1347      CHECK_NULL_VOID(parentContainer);
1348      if (parentContainer->IsScenceBoardWindow() || toastInfo.showMode == NG::ToastShowMode::TOP_MOST ||
1349          toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1350          ResizeWindow();
1351          // Recover current subwindow in subwindow manager to ensure popup/menu can close the right subwindow
1352          auto currentWindow = SubwindowManager::GetInstance()->GetCurrentWindow();
1353          ShowWindow(false);
1354          SubwindowManager::GetInstance()->SetCurrentSubwindow(currentWindow);
1355          CHECK_NULL_VOID(window_);
1356          window_->SetTouchable(false);
1357      }
1358      delegate->ShowToast(toastInfo);
1359  }
1360  
ShowToastForService(const NG::ToastInfo & toastInfo)1361  void SubwindowOhos::ShowToastForService(const NG::ToastInfo& toastInfo)
1362  {
1363      bool ret = CreateEventRunner();
1364      if (!ret) {
1365          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1366          return;
1367      }
1368  
1369      SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1370      if (!handler_->PostTask(GetInitToastDelayTask(toastInfo))) {
1371          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1372          return;
1373      }
1374  }
1375  
ShowToast(const NG::ToastInfo & toastInfo)1376  void SubwindowOhos::ShowToast(const NG::ToastInfo& toastInfo)
1377  {
1378      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show toast, window parent id is %{public}d", parentContainerId_);
1379      bool isTopMost = toastInfo.showMode == NG::ToastShowMode::TOP_MOST;
1380      // for pa service
1381      if ((isTopMost && parentContainerId_ >= MIN_PA_SERVICE_ID && parentContainerId_ < MIN_SUBCONTAINER_ID) ||
1382          (!isTopMost && parentContainerId_ >= MIN_PA_SERVICE_ID) || parentContainerId_ < 0) {
1383          ShowToastForService(toastInfo);
1384      } else {
1385          ShowToastForAbility(toastInfo);
1386      }
1387  }
1388  
ShowDialogForAbility(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1389  void SubwindowOhos::ShowDialogForAbility(const std::string& title, const std::string& message,
1390      const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1391      const std::set<std::string>& callbacks)
1392  {
1393      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog for ability enter");
1394      SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1395  
1396      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1397      if (!aceContainer) {
1398          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get container failed, child containerId : %{public}d", childContainerId_);
1399          return;
1400      }
1401  
1402      auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1403      auto delegate = engine->GetFrontend();
1404      if (!delegate) {
1405          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed, child containerId : %{public}d", childContainerId_);
1406          return;
1407      }
1408      delegate->ShowDialog(title, message, buttons, autoCancel, std::move(callback), callbacks);
1409  }
1410  
ShowDialogForService(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1411  void SubwindowOhos::ShowDialogForService(const std::string& title, const std::string& message,
1412      const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1413      const std::set<std::string>& callbacks)
1414  {
1415      bool ret = CreateEventRunner();
1416      if (!ret) {
1417          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1418          return;
1419      }
1420  
1421      SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1422      auto showDialogCallback = [title, message, &buttons, autoCancel, callbackParam = std::move(callback),
1423                                    &callbacks]() {
1424          int32_t posX = 0;
1425          int32_t posY = 0;
1426          int32_t width = 0;
1427          int32_t height = 0;
1428          float density = 1.0f;
1429          auto subwindowOhos =
1430              AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1431          CHECK_NULL_VOID(subwindowOhos);
1432          subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
1433          bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
1434          if (!ret) {
1435              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
1436              return;
1437          }
1438          ret = subwindowOhos->InitToastDialogView(width, height, density);
1439          if (!ret) {
1440              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
1441              return;
1442          }
1443          auto childContainerId = subwindowOhos->GetChildContainerId();
1444          ContainerScope scope(childContainerId);
1445          auto container = Platform::DialogContainer::GetContainer(childContainerId);
1446          CHECK_NULL_VOID(container);
1447          container->SetFontScaleAndWeightScale(childContainerId);
1448          Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
1449          Platform::DialogContainer::ShowDialog(childContainerId, title, message, buttons, autoCancel,
1450              std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)), callbacks);
1451      };
1452      isToastWindow_ = false;
1453      if (!handler_->PostTask(showDialogCallback)) {
1454          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1455          return;
1456      }
1457  }
1458  
ShowDialogForAbility(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1459  void SubwindowOhos::ShowDialogForAbility(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1460      std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1461  {
1462      SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1463  
1464      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1465      if (!aceContainer) {
1466          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get ace container failed");
1467          return;
1468      }
1469  
1470      auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1471      auto delegate = engine->GetFrontend();
1472      if (!delegate) {
1473          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed");
1474          return;
1475      }
1476      delegate->ShowDialog(dialogAttr, buttons, std::move(callback), callbacks);
1477  }
1478  
ShowDialogForService(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1479  void SubwindowOhos::ShowDialogForService(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1480      std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1481  {
1482      bool ret = CreateEventRunner();
1483      if (!ret) {
1484          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1485          return;
1486      }
1487  
1488      SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1489      auto showDialogCallback = [dialogAttr, &buttons, callbackParam = std::move(callback), &callbacks]() {
1490          int32_t posX = 0;
1491          int32_t posY = 0;
1492          int32_t width = 0;
1493          int32_t height = 0;
1494          float density = 1.0f;
1495          auto subwindowOhos =
1496              AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1497          CHECK_NULL_VOID(subwindowOhos);
1498          subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
1499          bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
1500          if (!ret) {
1501              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
1502              return;
1503          }
1504          ret = subwindowOhos->InitToastDialogView(width, height, density);
1505          if (!ret) {
1506              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
1507              return;
1508          }
1509          auto childContainerId = subwindowOhos->GetChildContainerId();
1510          ContainerScope scope(childContainerId);
1511          Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
1512          Platform::DialogContainer::ShowDialog(childContainerId, dialogAttr, buttons,
1513              std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)), callbacks);
1514      };
1515      isToastWindow_ = false;
1516      if (!handler_->PostTask(showDialogCallback)) {
1517          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1518          return;
1519      }
1520  }
1521  
ShowDialog(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1522  void SubwindowOhos::ShowDialog(const std::string& title, const std::string& message,
1523      const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1524      const std::set<std::string>& callbacks)
1525  {
1526      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show dialog, window parent id is %{public}d", parentContainerId_);
1527      if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1528          ShowDialogForService(title, message, buttons, autoCancel, std::move(callback), callbacks);
1529      } else {
1530          ShowDialogForAbility(title, message, buttons, autoCancel, std::move(callback), callbacks);
1531      }
1532  }
1533  
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1534  void SubwindowOhos::ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1535      std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1536  {
1537      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show dialog with attr, window parent id is %{public}d", parentContainerId_);
1538      if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1539          ShowDialogForService(dialogAttr, buttons, std::move(callback), callbacks);
1540      } else {
1541          ShowDialogForAbility(dialogAttr, buttons, std::move(callback), callbacks);
1542      }
1543  }
1544  
OpenCustomDialogForAbility(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1545  void SubwindowOhos::OpenCustomDialogForAbility(
1546      const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1547  {
1548      SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1549  
1550      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1551      if (!aceContainer) {
1552          TAG_LOGW(
1553              AceLogTag::ACE_SUB_WINDOW, "open dialog fail, the container %{public}d can not find", childContainerId_);
1554          return;
1555      }
1556  
1557      auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1558      auto delegate = engine->GetFrontend();
1559      if (!delegate) {
1560          return;
1561      }
1562      delegate->OpenCustomDialog(dialogAttr, std::move(callback));
1563  }
1564  
OpenCustomDialogForService(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1565  void SubwindowOhos::OpenCustomDialogForService(
1566      const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1567  {
1568      // temporary not support
1569      TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "temporary not support for service by promptAction with CustomBuilder");
1570  }
1571  
OpenCustomDialog(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1572  void SubwindowOhos::OpenCustomDialog(const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1573  {
1574      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "open custom dialog, window parent id is %{public}d", parentContainerId_);
1575      if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1576          OpenCustomDialogForService(dialogAttr, std::move(callback));
1577      } else {
1578          OpenCustomDialogForAbility(dialogAttr, std::move(callback));
1579      }
1580  }
1581  
CloseCustomDialog(const int32_t dialogId)1582  void SubwindowOhos::CloseCustomDialog(const int32_t dialogId)
1583  {
1584      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close custom dialog with id, childContainerId_ is %{public}d",
1585          childContainerId_);
1586      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1587      CHECK_NULL_VOID(aceContainer);
1588      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1589      CHECK_NULL_VOID(context);
1590      auto overlay = context->GetOverlayManager();
1591      CHECK_NULL_VOID(overlay);
1592      ContainerScope scope(childContainerId_);
1593      return overlay->CloseCustomDialog(dialogId);
1594  }
1595  
CloseCustomDialog(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)1596  void SubwindowOhos::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
1597  {
1598      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close custom dialog with node, childContainerId_ is %{public}d",
1599          childContainerId_);
1600      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1601      CHECK_NULL_VOID(aceContainer);
1602      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1603      CHECK_NULL_VOID(context);
1604      auto overlay = context->GetOverlayManager();
1605      CHECK_NULL_VOID(overlay);
1606      ContainerScope scope(childContainerId_);
1607      return overlay->CloseCustomDialog(node, std::move(callback));
1608  }
1609  
ShowActionMenuForAbility(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)1610  void SubwindowOhos::ShowActionMenuForAbility(
1611      const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
1612  {
1613      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu for ability enter");
1614      SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1615  
1616      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1617      if (!aceContainer) {
1618          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get container failed");
1619          return;
1620      }
1621  
1622      auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1623      auto delegate = engine->GetFrontend();
1624      if (!delegate) {
1625          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed");
1626          return;
1627      }
1628      delegate->ShowActionMenu(title, button, std::move(callback));
1629  }
1630  
ShowActionMenuForService(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)1631  void SubwindowOhos::ShowActionMenuForService(
1632      const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
1633  {
1634      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu for service enter");
1635      bool ret = CreateEventRunner();
1636      if (!ret) {
1637          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1638          return;
1639      }
1640  
1641      SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1642      auto showDialogCallback = [title, &button, callbackParam = std::move(callback)]() {
1643          int32_t posX = 0;
1644          int32_t posY = 0;
1645          int32_t width = 0;
1646          int32_t height = 0;
1647          float density = 1.0f;
1648          auto subwindowOhos =
1649              AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1650          CHECK_NULL_VOID(subwindowOhos);
1651          subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
1652          bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
1653          if (!ret) {
1654              return;
1655          }
1656          ret = subwindowOhos->InitToastDialogView(width, height, density);
1657          if (!ret) {
1658              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
1659              return;
1660          }
1661          auto childContainerId = subwindowOhos->GetChildContainerId();
1662          ContainerScope scope(childContainerId);
1663          auto container = Platform::DialogContainer::GetContainer(childContainerId);
1664          CHECK_NULL_VOID(container);
1665          container->SetFontScaleAndWeightScale(childContainerId);
1666          Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
1667          Platform::DialogContainer::ShowActionMenu(childContainerId, title, button,
1668              std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)));
1669      };
1670      isToastWindow_ = false;
1671      if (!handler_->PostTask(showDialogCallback)) {
1672          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1673          return;
1674      }
1675  }
1676  
CloseDialog(int32_t instanceId)1677  void SubwindowOhos::CloseDialog(int32_t instanceId)
1678  {
1679      TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog enter");
1680      Platform::DialogContainer::CloseWindow(instanceId);
1681  }
1682  
UpdateAceView(int32_t width,int32_t height,float density,int32_t containerId)1683  void SubwindowOhos::UpdateAceView(int32_t width, int32_t height, float density, int32_t containerId)
1684  {
1685      auto container = Platform::DialogContainer::GetContainer(containerId);
1686      CHECK_NULL_VOID(container);
1687      auto aceView = AceType::DynamicCast<Platform::AceViewOhos>(container->GetAceView());
1688      CHECK_NULL_VOID(aceView);
1689      if (aceView->GetWidth() != width || aceView->GetHeight() != height) {
1690          ViewportConfig config(width, height, density);
1691          Platform::AceViewOhos::SetViewportMetrics(aceView, config);
1692          Platform::AceViewOhos::SurfaceChanged(aceView, width, height, 0);
1693      }
1694  }
1695  
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)1696  void SubwindowOhos::ShowActionMenu(
1697      const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
1698  {
1699      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show custom dialog, window parent id is %{public}d", parentContainerId_);
1700      if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1701          ShowActionMenuForService(title, button, std::move(callback));
1702      } else {
1703          ShowActionMenuForAbility(title, button, std::move(callback));
1704      }
1705  }
1706  
GetParentWindowRect() const1707  Rect SubwindowOhos::GetParentWindowRect() const
1708  {
1709      Rect rect;
1710      CHECK_NULL_RETURN(parentWindow_, rect);
1711      auto parentWindowRect = parentWindow_->GetRect();
1712      return Rect(parentWindowRect.posX_, parentWindowRect.posY_, parentWindowRect.width_, parentWindowRect.height_);
1713  }
1714  
GetUIExtensionHostWindowRect() const1715  Rect SubwindowOhos::GetUIExtensionHostWindowRect() const
1716  {
1717      Rect rect;
1718      CHECK_NULL_RETURN(parentWindow_, rect);
1719      auto id = GetUIExtensionHostWindowId();
1720      auto hostWindowRect = parentWindow_->GetHostWindowRect(id);
1721      return Rect(hostWindowRect.posX_, hostWindowRect.posY_, hostWindowRect.width_, hostWindowRect.height_);
1722  }
1723  
RequestFocus()1724  void SubwindowOhos::RequestFocus()
1725  {
1726      CHECK_NULL_VOID(window_);
1727      if (window_->IsFocused()) {
1728          TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u already focused", window_->GetWindowId());
1729          // already focused, no need to focus
1730          return;
1731      }
1732      OHOS::Rosen::WMError ret = window_->RequestFocus();
1733      if (ret != OHOS::Rosen::WMError::WM_OK) {
1734          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subindow id:%{public}u request focus failed with WMError: %{public}d",
1735              window_->GetWindowId(), static_cast<int32_t>(ret));
1736          return;
1737      }
1738      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u request focus successfully.", window_->GetWindowId());
1739  }
1740  
IsFocused()1741  bool SubwindowOhos::IsFocused()
1742  {
1743      CHECK_NULL_RETURN(window_, false);
1744      return window_->IsFocused();
1745  }
1746  
HideFilter(bool isInSubWindow)1747  void SubwindowOhos::HideFilter(bool isInSubWindow)
1748  {
1749      RefPtr<Container> aceContainer = nullptr;
1750      if (isInSubWindow) {
1751          aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1752      } else {
1753          aceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1754      }
1755  
1756      CHECK_NULL_VOID(aceContainer);
1757      auto pipelineContext = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1758      CHECK_NULL_VOID(pipelineContext);
1759      auto overlayManager = pipelineContext->GetOverlayManager();
1760      CHECK_NULL_VOID(overlayManager);
1761  
1762      auto containerId = isInSubWindow ? childContainerId_ : parentContainerId_;
1763      ContainerScope scope(containerId);
1764      overlayManager->RemoveFilterAnimation();
1765  }
1766  
HidePixelMap(bool startDrag,double x,double y,bool showAnimation)1767  void SubwindowOhos::HidePixelMap(bool startDrag, double x, double y, bool showAnimation)
1768  {
1769      auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1770      CHECK_NULL_VOID(parentAceContainer);
1771      auto parentPipeline = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1772      CHECK_NULL_VOID(parentPipeline);
1773      auto manager = parentPipeline->GetOverlayManager();
1774      CHECK_NULL_VOID(manager);
1775      ContainerScope scope(parentContainerId_);
1776      if (!startDrag) {
1777          manager->RemovePreviewBadgeNode();
1778          manager->RemoveGatherNodeWithAnimation();
1779      }
1780      if (showAnimation) {
1781          manager->RemovePixelMapAnimation(startDrag, x, y, true);
1782      } else {
1783          manager->RemovePixelMap();
1784      }
1785  }
1786  
HideEventColumn()1787  void SubwindowOhos::HideEventColumn()
1788  {
1789      auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1790      CHECK_NULL_VOID(parentAceContainer);
1791      auto parentPipeline = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1792      CHECK_NULL_VOID(parentPipeline);
1793      auto manager = parentPipeline->GetOverlayManager();
1794      CHECK_NULL_VOID(manager);
1795      ContainerScope scope(parentContainerId_);
1796      manager->RemoveEventColumn();
1797  }
1798  
ResizeWindowForFoldStatus(int32_t parentContainerId)1799  void SubwindowOhos::ResizeWindowForFoldStatus(int32_t parentContainerId)
1800  {
1801      auto callback = []() {
1802          auto subwindowOhos =
1803              AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1804          CHECK_NULL_VOID(subwindowOhos);
1805          auto childContainerId = subwindowOhos->GetChildContainerId();
1806          ContainerScope scope(childContainerId);
1807          auto window = Platform::DialogContainer::GetUIWindow(childContainerId);
1808          CHECK_NULL_VOID(window);
1809          auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
1810          CHECK_NULL_VOID(defaultDisplay);
1811          auto ret = window->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
1812          if (ret != Rosen::WMError::WM_OK) {
1813              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
1814                  static_cast<int32_t>(ret));
1815              return;
1816          }
1817          auto container = Platform::DialogContainer::GetContainer(childContainerId);
1818          CHECK_NULL_VOID(container);
1819          // get ace_view
1820          auto aceView = AceType::DynamicCast<Platform::AceViewOhos>(container->GetAceView());
1821          CHECK_NULL_VOID(aceView);
1822          Platform::AceViewOhos::SurfaceChanged(aceView, defaultDisplay->GetWidth(), defaultDisplay->GetHeight(), 0);
1823      };
1824      if (parentContainerId > 0) {
1825          ResizeWindowForFoldStatus();
1826          return;
1827      }
1828      if (!handler_->PostTask(callback)) {
1829          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize Toast Window failed");
1830      }
1831  }
1832  
ResizeWindowForFoldStatus()1833  void SubwindowOhos::ResizeWindowForFoldStatus()
1834  {
1835      auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
1836      CHECK_NULL_VOID(defaultDisplay);
1837      CHECK_NULL_VOID(window_);
1838      auto ret = window_->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
1839      if (ret != Rosen::WMError::WM_OK) {
1840          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
1841              static_cast<int32_t>(ret));
1842          return;
1843      }
1844      TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
1845          "SubwindowOhos window rect is resized to x: %{public}d, y: %{public}d, width: %{public}u, height: %{public}u",
1846          window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
1847  }
1848  
MarkDirtyDialogSafeArea()1849  void SubwindowOhos::MarkDirtyDialogSafeArea()
1850  {
1851      auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1852      CHECK_NULL_VOID(aceContainer);
1853      auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1854      CHECK_NULL_VOID(context);
1855      auto rootNode = context->GetRootElement();
1856      CHECK_NULL_VOID(rootNode);
1857      auto lastChild = rootNode->GetLastChild();
1858      CHECK_NULL_VOID(lastChild);
1859      lastChild->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
1860  }
1861  
CheckHostWindowStatus() const1862  bool SubwindowOhos::CheckHostWindowStatus() const
1863  {
1864      auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1865      CHECK_NULL_RETURN(parentContainer, false);
1866      sptr<OHOS::Rosen::Window> parentWindow = parentContainer->GetUIWindow(parentContainerId_);
1867      CHECK_NULL_RETURN(parentWindow, false);
1868      if (parentWindow->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION) {
1869          auto parentPipeline = parentContainer->GetPipelineContext();
1870          CHECK_NULL_RETURN(parentPipeline, false);
1871          auto hostWindowId = parentPipeline->GetFocusWindowId();
1872          auto hostWindowRect = parentWindow->GetHostWindowRect(hostWindowId);
1873          auto isValid = GreatNotEqual(hostWindowRect.width_, 0) && GreatNotEqual(hostWindowRect.height_, 0);
1874          if (!isValid) {
1875              TAG_LOGW(AceLogTag::ACE_SUB_WINDOW,
1876                  "UIExtension Window failed to obtain host window information. Please check if permissions are enabled");
1877              return false;
1878          }
1879      }
1880      return true;
1881  }
1882  
Close()1883  bool SubwindowOhos::Close()
1884  {
1885      CHECK_NULL_RETURN(window_, false);
1886      window_->UnregisterSwitchFreeMultiWindowListener(freeMultiWindowListener_);
1887      OHOS::Rosen::WMError ret = window_->Close();
1888      if (ret != OHOS::Rosen::WMError::WM_OK) {
1889          TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "SubwindowOhos failed to close the dialog subwindow.");
1890          return false;
1891      }
1892      sptr<OHOS::Rosen::Window> uiWindow = nullptr;
1893      Ace::Platform::DialogContainer::SetUIWindow(childContainerId_, uiWindow);
1894      return true;
1895  }
1896  
IsFreeMultiWindow() const1897  bool SubwindowOhos::IsFreeMultiWindow() const
1898  {
1899      if (!parentWindow_) {
1900          TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window is null, failed to get freeMultiWindow status");
1901          return false;
1902      }
1903  
1904      return parentWindow_->GetFreeMultiWindowModeEnabledState();
1905  }
1906  
OnFreeMultiWindowSwitch(bool enable)1907  void SubwindowOhos::OnFreeMultiWindowSwitch(bool enable)
1908  {
1909      for (auto&& [id, callback] : freeMultiWindowSwitchCallbackMap_) {
1910          if (callback) {
1911              callback(enable);
1912          }
1913      }
1914  }
1915  
RegisterFreeMultiWindowSwitchCallback(std::function<void (bool)> && callback)1916  int32_t SubwindowOhos::RegisterFreeMultiWindowSwitchCallback(std::function<void(bool)>&& callback)
1917  {
1918      if (callback) {
1919          freeMultiWindowSwitchCallbackMap_.emplace(++callbackId_, std::move(callback));
1920          return callbackId_;
1921      }
1922      return 0;
1923  }
1924  
UnRegisterFreeMultiWindowSwitchCallback(int32_t callbackId)1925  void SubwindowOhos::UnRegisterFreeMultiWindowSwitchCallback(int32_t callbackId)
1926  {
1927      freeMultiWindowSwitchCallbackMap_.erase(callbackId);
1928  }
1929  } // namespace OHOS::Ace
1930