• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "display_info.h"
19 #include "dm/display_manager.h"
20 #include "interfaces/inner_api/ace/viewport_config.h"
21 #include "render_service_client/core/ui/rs_surface_node.h"
22 #include "window.h"
23 
24 #include "adapter/ohos/entrance/ace_application_info.h"
25 #include "base/geometry/rect.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 
33 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
34 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
35 #endif
36 
37 #include "bundlemgr/bundle_mgr_interface.h"
38 #include "iservice_registry.h"
39 
40 #include "adapter/ohos/entrance/ace_view_ohos.h"
41 #include "adapter/ohos/entrance/dialog_container.h"
42 #include "adapter/ohos/entrance/ui_content_impl.h"
43 #include "adapter/ohos/entrance/utils.h"
44 #include "base/log/frame_report.h"
45 #include "base/subwindow/subwindow_manager.h"
46 #include "base/utils/system_properties.h"
47 #include "base/utils/utils.h"
48 #include "core/common/connect_server_manager.h"
49 #include "core/common/container_scope.h"
50 #include "core/common/frontend.h"
51 #include "core/common/hdc_register.h"
52 #include "core/common/text_field_manager.h"
53 #include "core/components/bubble/bubble_component.h"
54 #include "core/components/popup/popup_component.h"
55 #include "core/components_ng/pattern/menu/menu_view.h"
56 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
57 #include "core/components_ng/pattern/overlay/overlay_manager.h"
58 #include "core/components_ng/render/adapter/rosen_render_context.h"
59 #include "core/components_ng/render/adapter/rosen_window.h"
60 #include "frameworks/bridge/common/utils/engine_helper.h"
61 #include "frameworks/bridge/declarative_frontend/declarative_frontend.h"
62 
63 #ifdef OS_ACCOUNT_EXISTS
64 #include "os_account_manager.h"
65 #endif
66 
67 #include "system_ability_definition.h"
68 
69 namespace OHOS::Ace {
70 namespace {
71 const Rect MIN_WINDOW_HOT_AREA = Rect(0.0f, 0.0f, 1.0f, 1.0f);
72 constexpr uint32_t ENABLE_SYSTEM_WINDOW_AVOID_AREA = 1;
73 constexpr uint32_t ENABLE_APP_SUB_WINDOW_AVOID_AREA = 1 << 1;
74 #ifndef NG_BUILD
75 constexpr int32_t PLATFORM_VERSION_TEN = 10;
76 #endif
77 constexpr uint64_t DEFAULT_DISPLAY_ID = 0;
78 constexpr int32_t DEFAULT_NODE_ID = -1;
79 } // namespace
80 
81 int32_t SubwindowOhos::id_ = 0;
82 static std::atomic<int32_t> gToastDialogId = 0;
83 
84 class SwitchFreeMultiWindowListener : public OHOS::Rosen::ISwitchFreeMultiWindowListener {
85 public:
SwitchFreeMultiWindowListener(int32_t instanceId)86     explicit SwitchFreeMultiWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
87     ~SwitchFreeMultiWindowListener() = default;
88 
OnSwitchFreeMultiWindow(bool enable)89     void OnSwitchFreeMultiWindow(bool enable)
90     {
91         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Window status changes, freeMultiWindow is %{public}d", enable);
92         auto container = Platform::AceContainer::GetContainer(instanceId_);
93         CHECK_NULL_VOID(container);
94         auto subWindow = SubwindowManager::GetInstance()->GetSubwindowById(instanceId_);
95         CHECK_NULL_VOID(subWindow);
96 
97         auto taskExecutor = container->GetTaskExecutor();
98         CHECK_NULL_VOID(taskExecutor);
99         ContainerScope scope(instanceId_);
100         taskExecutor->PostTask(
101             [subWindow, enable]() {
102                 CHECK_NULL_VOID(subWindow);
103                 subWindow->OnFreeMultiWindowSwitch(enable);
104                 subWindow->SwitchFollowParentWindowLayout(enable);
105             },
106             TaskExecutor::TaskType::UI, "ArkUIFreeMultiWindowSwitch");
107     }
108 
109 private:
110     int32_t instanceId_ = -1;
111 };
112 
CreateSubwindow(int32_t instanceId)113 RefPtr<Subwindow> Subwindow::CreateSubwindow(int32_t instanceId)
114 {
115     return AceType::MakeRefPtr<SubwindowOhos>(instanceId);
116 }
117 
SubwindowOhos(int32_t instanceId)118 SubwindowOhos::SubwindowOhos(int32_t instanceId) : windowId_(id_), parentContainerId_(instanceId)
119 {
120     SetSubwindowId(windowId_);
121     id_++;
122     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Create Subwindow, subwindow id %{public}d, container id %{public}d", windowId_,
123         instanceId);
124 }
125 
GetToastRosenType(bool IsSceneBoardEnabled)126 Rosen::WindowType SubwindowOhos::GetToastRosenType(bool IsSceneBoardEnabled)
127 {
128     auto toastType = GetToastWindowType();
129     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW,
130         "GetToastRosenType windowType: %{public}d, IsSceneBoardEnabled: %{public}d",
131         toastType, IsSceneBoardEnabled);
132     if (toastType == ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW) {
133         if (!IsSceneBoardEnabled && !GetIsSelectOverlaySubWindow()) {
134             return Rosen::WindowType::WINDOW_TYPE_TOAST;
135         }
136         return Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
137     } else if (toastType == ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW) {
138         return Rosen::WindowType::WINDOW_TYPE_TOAST;
139     } else if (toastType == ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT) {
140         return Rosen::WindowType::WINDOW_TYPE_SYSTEM_FLOAT;
141     }
142     return Rosen::WindowType::WINDOW_TYPE_TOAST;
143 }
144 
SetToastWindowOption(RefPtr<Platform::AceContainer> & parentContainer,OHOS::sptr<OHOS::Rosen::WindowOption> & windowOption,const Rosen::WindowType & toastWindowType,uint32_t mainWindowId)145 void SubwindowOhos::SetToastWindowOption(RefPtr<Platform::AceContainer>& parentContainer,
146     OHOS::sptr<OHOS::Rosen::WindowOption>& windowOption,
147     const Rosen::WindowType& toastWindowType, uint32_t mainWindowId)
148 {
149     if (toastWindowType == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
150         windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
151         if (GetIsSelectOverlaySubWindow()) {
152             windowOption->AddWindowFlag(Rosen::WindowFlag::WINDOW_FLAG_IS_TEXT_MENU);
153         } else {
154             windowOption->AddWindowFlag(Rosen::WindowFlag::WINDOW_FLAG_IS_TOAST);
155         }
156     }
157     windowOption->SetWindowType(toastWindowType);
158     if (parentContainer->IsUIExtensionWindow()) {
159         auto parentPipeline = parentContainer->GetPipelineContext();
160         CHECK_NULL_VOID(parentPipeline);
161         auto hostWindowId = parentPipeline->GetFocusWindowId();
162         windowOption->SetIsUIExtAnySubWindow(true);
163         windowOption->SetParentId(hostWindowId);
164         SetUIExtensionHostWindowId(hostWindowId);
165     } else {
166         windowOption->SetParentId(mainWindowId);
167     }
168 }
169 
SetUIExtensionSubwindowFlag(OHOS::sptr<OHOS::Rosen::WindowOption> & windowOption,bool isAppSubwindow,sptr<OHOS::Rosen::Window> & parentWindow)170 void SetUIExtensionSubwindowFlag(OHOS::sptr<OHOS::Rosen::WindowOption>& windowOption,
171     bool isAppSubwindow, sptr<OHOS::Rosen::Window>& parentWindow)
172 {
173     if (isAppSubwindow && (parentWindow->GetIsUIExtFirstSubWindow() ||
174         parentWindow->GetIsUIExtAnySubWindow())) {
175         windowOption->SetIsUIExtAnySubWindow(true);
176     }
177 }
178 
SetSubWindowCutout(const RefPtr<PipelineBase> parentPipeline,int32_t childContainerId)179 void SetSubWindowCutout(const RefPtr<PipelineBase> parentPipeline, int32_t childContainerId)
180 {
181     auto parentPipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentPipeline);
182     CHECK_NULL_VOID(parentPipelineContext);
183     auto parentSafeAreaManager = parentPipelineContext->GetSafeAreaManager();
184     CHECK_NULL_VOID(parentSafeAreaManager);
185     auto parentUseCutout = parentSafeAreaManager->GetUseCutout();
186 
187     auto subPipelineContext = Platform::AceContainer::GetContainer(childContainerId)->GetPipelineContext();
188     auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(subPipelineContext);
189     CHECK_NULL_VOID(subPipelineContextNG);
190     auto subSafeAreaManager = subPipelineContextNG->GetSafeAreaManager();
191     CHECK_NULL_VOID(subSafeAreaManager);
192     subSafeAreaManager->SetUseCutout(parentUseCutout);
193 }
194 
GetSubWindowSize(int32_t parentContainerId,uint32_t displayId)195 Size GetSubWindowSize(int32_t parentContainerId, uint32_t displayId)
196 {
197     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
198     CHECK_NULL_RETURN(defaultDisplay, Size());
199 
200     auto size = Size(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
201     if (!SystemProperties::IsSuperFoldDisplayDevice()) {
202         return size;
203     }
204 
205     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId);
206     CHECK_NULL_RETURN(parentContainer, size);
207     if (parentContainer->GetCurrentFoldStatus() == FoldStatus::EXPAND) {
208         return size;
209     }
210 
211     auto isCrossWindow = parentContainer->IsCrossAxisWindow();
212     auto isSceneBoard = parentContainer->IsSceneBoardWindow();
213     if (isCrossWindow || isSceneBoard) {
214         auto display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(DEFAULT_DISPLAY_ID);
215         if (!display) {
216             TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "failed to GetVisibleAreaDisplayInfoById");
217             return size;
218         }
219         size = Size(display->GetWidth(), display->GetHeight());
220     }
221 
222     auto parentWindowId = parentContainer->GetWindowId();
223     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
224         "parentWindow windowId: %{public}d isSceneBoard: %{public}d isCrossWindow: %{public}d displaySize: %{public}s",
225         parentWindowId, isSceneBoard, isCrossWindow, size.ToString().c_str());
226     return size;
227 }
228 
InitWindowRSUIDirector(const RefPtr<Platform::AceContainer> & container)229 void SubwindowOhos::InitWindowRSUIDirector(const RefPtr<Platform::AceContainer>& container)
230 {
231 #ifdef ENABLE_ROSEN_BACKEND
232     if (!SystemProperties::GetMultiInstanceEnabled()) {
233         rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
234         if (rsUiDirector != nullptr) {
235             rsUiDirector->SetRSSurfaceNode(window_->GetSurfaceNode());
236             auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
237             if (context != nullptr) {
238                 context->SetRSUIDirector(rsUiDirector);
239             }
240             rsUiDirector->Init();
241             TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "UIContent Init Rosen Backend");
242         }
243     } else {
244         rsUiDirector = window_->GetRSUIDirector();
245         if (!rsUiDirector) {
246             rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
247         }
248         rsUiDirector->SetRSSurfaceNode(window_->GetSurfaceNode());
249         auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
250         if (context != nullptr) {
251             context->SetRSUIDirector(rsUiDirector);
252         }
253         rsUiDirector->Init(true, true);
254         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "UIContent Init Rosen Backend");
255     }
256 #endif
257 }
258 
SetWindowAnchorInfo(const NG::OffsetF & offset,SubwindowType type,int32_t nodeId)259 void SubwindowOhos::SetWindowAnchorInfo(const NG::OffsetF &offset, SubwindowType type, int32_t nodeId)
260 {
261     CHECK_NULL_VOID(window_);
262     auto windowAnchorInfo = WindowAnchorInfoConverter(offset, type);
263     window_->SetWindowAnchorInfo(windowAnchorInfo);
264 }
265 
WindowAnchorInfoConverter(const NG::OffsetF & offset,SubwindowType type)266 Rosen::WindowAnchorInfo SubwindowOhos::WindowAnchorInfoConverter(const NG::OffsetF& offset, SubwindowType type)
267 {
268     Rosen::WindowAnchorInfo windowAnchorInfo(true);
269     switch (type) {
270         case SubwindowType::TYPE_SYSTEM_TOP_MOST_TOAST:
271         case SubwindowType::TYPE_TOP_MOST_TOAST:
272         case SubwindowType::TYPE_MENU:
273         case SubwindowType::TYPE_POPUP:
274         case SubwindowType::TYPE_DIALOG:
275         case SubwindowType::TYPE_SELECT_MENU:
276         case SubwindowType::TYPE_TIPS:
277         case SubwindowType::SUB_WINDOW_TYPE_COUNT:
278             break;
279         case SubwindowType::TYPE_SHEET:
280         default:
281             windowAnchorInfo.windowAnchor_ = Rosen::WindowAnchor::CENTER;
282     }
283     windowAnchorInfo.offsetX_ = offset.GetX();
284     windowAnchorInfo.offsetY_ = offset.GetY();
285     return windowAnchorInfo;
286 }
287 
InitContainer()288 void SubwindowOhos::InitContainer()
289 {
290     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
291     CHECK_NULL_VOID(parentContainer);
292     auto parentPipeline = parentContainer->GetPipelineContext();
293     CHECK_NULL_VOID(parentPipeline);
294     if (!window_) {
295         OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
296         auto parentWindowName = parentContainer->GetWindowName();
297         auto parentWindowId = parentContainer->GetWindowId();
298         sptr<OHOS::Rosen::Window> parentWindow = parentContainer->GetUIWindow(parentContainerId_);
299         CHECK_NULL_VOID(parentWindow);
300         parentWindow_ = parentWindow;
301         auto parentWindowType = parentWindow->GetType();
302         std::string windowTag = "";
303         bool isAppSubwindow = false;
304         bool needFollowScreen = false;
305         std::string windowName = "";
306         if (IsSystemTopMost()) {
307             windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SYSTEM_TOAST);
308             windowTag = "TOAST_SYSTEM_";
309             needFollowScreen = true;
310             windowName = "ARK_APP_SUBWINDOW_" + windowTag + parentWindowName + std::to_string(windowId_);
311         } else if (GetAboveApps()) {
312             auto toastWindowType = GetToastRosenType(parentContainer->IsSceneBoardEnabled());
313             isAppSubwindow = toastWindowType == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
314             auto isSelectOverlay = GetIsSelectOverlaySubWindow();
315             auto mainWindowId = isSelectOverlay ? parentWindowId : GetMainWindowId();
316             SetToastWindowOption(parentContainer, windowOption, toastWindowType, mainWindowId);
317             windowTag = isSelectOverlay ? "TEXT_MENU_" : "TOAST_TOPMOST_";
318             windowName = "ARK_APP_SUBWINDOW_" + windowTag + parentWindowName + std::to_string(windowId_);
319         } else {
320             windowName = "ARK_APP_SUBWINDOW_" + windowTag + parentWindowName + std::to_string(windowId_);
321             Rosen::WindowType subwindowType = Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
322             OHOS::Rosen::WMError ret = OHOS::Rosen::Window::GetAndVerifyWindowTypeForArkUI(parentWindowId, windowName,
323                 parentWindowType, subwindowType);
324             TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "get and verify window type, ret = %{public}d,"
325                 " parentWindowType = %{public}d, subwindowType = %{public}d", static_cast<int32_t>(ret),
326                 static_cast<int32_t>(parentWindowType), static_cast<int32_t>(subwindowType));
327             if (ret != OHOS::Rosen::WMError::WM_OK) {
328                 return;
329             }
330             windowOption->SetWindowType(subwindowType);
331             needFollowScreen = parentContainer->IsSceneBoardWindow() ||
332                 parentWindowType >= Rosen::WindowType::SYSTEM_WINDOW_BASE;
333             isAppSubwindow = subwindowType == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
334             bool isUIExt = parentWindowType == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION;
335             if (isAppSubwindow || subwindowType == Rosen::WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
336                 windowOption->SetParentId(isUIExt ? parentPipeline->GetFocusWindowId() : parentWindowId);
337             }
338             if (isUIExt) {
339                 windowOption->SetIsUIExtFirstSubWindow(true);
340                 SetUIExtensionHostWindowId(parentPipeline->GetFocusWindowId());
341             }
342         }
343         auto displayId = parentContainer->GetCurrentDisplayId();
344         auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
345         if (!defaultDisplay) {
346             TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "DisplayManager failed to getDisplay by id: %{public}u",
347                 (uint32_t)displayId);
348         }
349         CHECK_NULL_VOID(defaultDisplay);
350 
351         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Parent window displayId: %{public}u width: %{public}d height: %{public}d",
352             (uint32_t)displayId, defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
353         auto windowSize = GetSubWindowSize(parentContainerId_, displayId);
354         windowOption->SetWindowRect(
355             { 0, 0, static_cast<uint32_t>(windowSize.Width()), static_cast<uint32_t>(windowSize.Height()) });
356         windowOption->SetWindowRect({ 0, 0, static_cast<uint32_t>(defaultDisplay->GetWidth()),
357             static_cast<uint32_t>(defaultDisplay->GetHeight()) });
358         windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
359         SetUIExtensionSubwindowFlag(windowOption, isAppSubwindow, parentWindow);
360         windowOption->SetDisplayId(displayId);
361         OHOS::Rosen::WMError ret;
362         window_ = OHOS::Rosen::Window::Create(windowName, windowOption, parentWindow->GetContext(), ret);
363         if (!window_ || ret != OHOS::Rosen::WMError::WM_OK) {
364             SetIsRosenWindowCreate(false);
365             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window create failed, errCode is %{public}d", ret);
366         }
367         CHECK_NULL_VOID(window_);
368         window_->RegisterWindowAttachStateChangeListener(new MenuWindowSceneListener(WeakClaim(this)));
369         window_->SetFollowScreenChange(needFollowScreen);
370         defaultDisplayId_ = displayId;
371         window_->SetSubWindowSource(Rosen::SubWindowSource::SUB_WINDOW_SOURCE_ARKUI);
372     }
373     std::string url = "";
374     auto subSurface = window_->GetSurfaceNode();
375     CHECK_NULL_VOID(subSurface);
376     subSurface->SetShadowElevation(0.0f);
377     window_->NapiSetUIContent(url, (napi_env)nullptr, (napi_value)nullptr, Rosen::BackupAndRestoreType::NONE);
378     childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(window_->GetWindowId());
379     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Window child containerId : %{public}d", childContainerId_);
380     SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
381 
382     auto container = Platform::AceContainer::GetContainer(childContainerId_);
383     if (!container) {
384         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window get ace container failed");
385     }
386     CHECK_NULL_VOID(container);
387 
388     auto parentToken = parentContainer->GetToken();
389     container->SetToken(parentToken);
390     container->SetWindowId(window_->GetWindowId());
391     container->SetParentId(parentContainerId_);
392     container->GetSettings().SetUsingSharedRuntime(true);
393     container->SetSharedRuntime(parentContainer->GetSharedRuntime());
394     container->Initialize();
395     container->SetAssetManager(parentContainer->GetAssetManager());
396     container->SetResourceConfiguration(parentContainer->GetResourceConfiguration());
397     container->SetPackagePathStr(parentContainer->GetPackagePathStr());
398     container->SetHapPath(parentContainer->GetHapPath());
399     container->SetIsSubContainer(true);
400     container->InitializeSubContainer(parentContainerId_);
401     container->SetColorMode(parentContainer->GetColorMode());
402     SetIsRosenWindowCreate(true);
403     ViewportConfig config;
404     // create ace_view
405     auto aceView =
406         Platform::AceViewOhos::CreateView(childContainerId_, false, container->GetSettings().usePlatformAsUIThread);
407     Platform::AceViewOhos::SurfaceCreated(aceView, window_);
408 
409     int32_t width = static_cast<int32_t>(window_->GetRequestRect().width_);
410     int32_t height = static_cast<int32_t>(window_->GetRequestRect().height_);
411     auto density = parentPipeline->GetDensity();
412     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
413         "UIContent Initialize: width: %{public}d, height: %{public}d, density: %{public}lf", width, height, density);
414 
415     Ace::Platform::UIEnvCallback callback = nullptr;
416     // set view
417     Platform::AceContainer::SetView(aceView, density, width, height, window_, callback);
418     Platform::AceViewOhos::SurfaceChanged(aceView, width, height, config.Orientation());
419 
420     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(window_->GetUIContent());
421     CHECK_NULL_VOID(uiContentImpl);
422     uiContentImpl->SetFontScaleAndWeightScale(container, childContainerId_);
423     freeMultiWindowListener_ = new SwitchFreeMultiWindowListener(childContainerId_);
424     window_->RegisterSwitchFreeMultiWindowListener(freeMultiWindowListener_);
425     window_->SetAvoidAreaOption(ENABLE_SYSTEM_WINDOW_AVOID_AREA | ENABLE_APP_SUB_WINDOW_AVOID_AREA);
426 
427 #ifndef NG_BUILD
428 #ifdef ENABLE_ROSEN_BACKEND
429     if (SystemProperties::GetRosenBackendEnabled()) {
430         InitWindowRSUIDirector(container);
431     }
432 #endif
433 #endif
434 #ifdef NG_BUILD
435     auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(
436         Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
437     CHECK_NULL_VOID(subPipelineContextNG);
438     subPipelineContextNG->SetParentPipeline(parentContainer->GetPipelineContext());
439     subPipelineContextNG->SetupSubRootElement();
440     subPipelineContextNG->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
441     subPipelineContextNG->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
442     subPipelineContextNG->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
443     subPipelineContextNG->SetFollowSystem(parentPipeline->IsFollowSystem());
444     subPipelineContextNG->SetFontScale(parentPipeline->GetFontScale());
445     subPipelineContextNG->SetApiTargetVersion(parentPipeline->GetApiTargetVersion());
446 #else
447     if (container->IsCurrentUseNewPipeline()) {
448         auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(
449             Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
450         CHECK_NULL_VOID(subPipelineContextNG);
451         subPipelineContextNG->SetParentPipeline(parentContainer->GetPipelineContext());
452         subPipelineContextNG->SetupSubRootElement();
453         subPipelineContextNG->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
454         subPipelineContextNG->SetKeyboardAnimationConfig(parentPipeline->GetKeyboardAnimationConfig());
455         subPipelineContextNG->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
456         subPipelineContextNG->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
457         subPipelineContextNG->SetFollowSystem(parentPipeline->IsFollowSystem());
458         subPipelineContextNG->SetFontScale(parentPipeline->GetFontScale());
459         subPipelineContextNG->SetApiTargetVersion(parentPipeline->GetApiTargetVersion());
460         return;
461     }
462     auto subPipelineContext =
463         DynamicCast<PipelineContext>(Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
464     CHECK_NULL_VOID(subPipelineContext);
465     subPipelineContext->SetParentPipeline(parentContainer->GetPipelineContext());
466     subPipelineContext->SetupSubRootElement();
467     subPipelineContext->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
468     subPipelineContext->SetKeyboardAnimationConfig(parentPipeline->GetKeyboardAnimationConfig());
469     subPipelineContext->SetDragNodeGrayscale(parentPipeline->GetDragNodeGrayscale());
470     subPipelineContext->SetMaxAppFontScale(parentPipeline->GetMaxAppFontScale());
471     subPipelineContext->SetFollowSystem(parentPipeline->IsFollowSystem());
472     subPipelineContext->SetFontScale(parentPipeline->GetFontScale());
473     subPipelineContext->SetApiTargetVersion(parentPipeline->GetApiTargetVersion());
474 #endif
475 }
476 
GetChildPipelineContext() const477 RefPtr<PipelineBase> SubwindowOhos::GetChildPipelineContext() const
478 {
479     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
480     CHECK_NULL_RETURN(aceContainer, nullptr);
481     return aceContainer->GetPipelineContext();
482 }
483 
GetInitToastDelayTask(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)484 std::function<void()> SubwindowOhos::GetInitToastDelayTask(const NG::ToastInfo& toastInfo,
485     std::function<void(int32_t)>&& callback)
486 {
487     return [toastInfo, callbackParam = std::move(callback)]() {
488         int32_t posX = 0;
489         int32_t posY = 0;
490         int32_t width = 0;
491         int32_t height = 0;
492         float density = 1.0f;
493         auto subwindowOhos =
494             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
495         CHECK_NULL_VOID(subwindowOhos);
496         subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
497         auto childContainerId = subwindowOhos->GetChildContainerId();
498         auto window = Platform::DialogContainer::GetUIWindow(childContainerId);
499         auto dialogWindow = subwindowOhos->GetDialogWindow();
500         if (!dialogWindow || !window || !subwindowOhos->IsToastWindow()) {
501             bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY, true);
502             if (!ret) {
503                 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
504                 return;
505             }
506             ret = subwindowOhos->InitToastDialogView(width, height, density);
507             if (!ret) {
508                 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
509                 return;
510             }
511             subwindowOhos->SetIsToastWindow(true);
512         }
513         childContainerId = subwindowOhos->GetChildContainerId();
514         ContainerScope scope(childContainerId);
515         subwindowOhos->UpdateAceView(width, height, density, childContainerId);
516         TAG_LOGD(AceLogTag::ACE_SUB_WINDOW,
517             "update ace view width : %{public}d,  height : %{public}d, density : %{public}f,childContainerId : "
518             "%{public}d",
519             width, height, density, childContainerId);
520         auto container = Platform::AceContainer::GetContainer(childContainerId);
521         CHECK_NULL_VOID(container);
522         container->SetFontScaleAndWeightScale(childContainerId);
523         auto ret = subwindowOhos->InitToastServiceConfig();
524         if (!ret) {
525             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast service conf failed");
526         }
527         Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height, true);
528         Platform::DialogContainer::ShowToast(childContainerId, toastInfo,
529             std::move(const_cast<std::function<void(int32_t)>&&>(callbackParam)));
530     };
531 }
532 
ResizeWindow()533 void SubwindowOhos::ResizeWindow()
534 {
535     CHECK_NULL_VOID(window_);
536     auto windowSize = GetSubWindowSize(parentContainerId_, window_->GetDisplayId());
537     auto ret = window_->Resize(windowSize.Width(), windowSize.Height());
538     if (ret != Rosen::WMError::WM_OK) {
539         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
540             static_cast<int32_t>(ret));
541         return;
542     }
543     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
544         "SubwindowOhos window rect is resized to x: %{public}d, y: %{public}d, width: %{public}u, height: %{public}u",
545         window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
546 }
547 
ResizeWindowForMenu()548 void SubwindowOhos::ResizeWindowForMenu()
549 {
550     CHECK_NULL_VOID(window_);
551     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
552     CHECK_NULL_VOID(parentContainer);
553     auto pipeline = DynamicCast<NG::PipelineContext>(parentContainer->GetPipelineContext());
554     CHECK_NULL_VOID(pipeline);
555     auto theme = pipeline->GetTheme<SelectTheme>();
556     CHECK_NULL_VOID(theme);
557 
558     Rosen::WMError ret;
559     if (!(theme->GetExpandDisplay() || parentContainer->IsFreeMultiWindow()) &&
560         SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE) {
561         if (parentContainer->IsUIExtensionWindow()) {
562             auto subwindow =
563                 SubwindowManager::GetInstance()->GetSubwindowByType(childContainerId_, SubwindowType::TYPE_MENU);
564             CHECK_NULL_VOID(subwindow);
565             auto rect = subwindow->GetUIExtensionHostWindowRect();
566             ret = window_->Resize(rect.Width(), rect.Height());
567         } else {
568             auto rect = pipeline->GetDisplayWindowRectInfo();
569             ret = window_->Resize(rect.Width(), rect.Height());
570         }
571     } else {
572         auto windowSize = GetSubWindowSize(parentContainerId_, window_->GetDisplayId());
573         ret = window_->Resize(windowSize.Width(), windowSize.Height());
574     }
575     if (ret != Rosen::WMError::WM_OK) {
576         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
577             static_cast<int32_t>(ret));
578         return;
579     }
580     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
581         "SubwindowOhos window rect is resized for menu to x: %{public}d, y: %{public}d, width: %{public}u, height: "
582         "%{public}u",
583         window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
584 }
585 
SetRect(const NG::RectF & rect)586 void SubwindowOhos::SetRect(const NG::RectF& rect)
587 {
588     windowRect_ = rect;
589 }
590 
GetRect()591 NG::RectF SubwindowOhos::GetRect()
592 {
593     return windowRect_;
594 }
595 
ResizeDialogSubwindow()596 void SubwindowOhos::ResizeDialogSubwindow()
597 {
598     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
599     CHECK_NULL_VOID(defaultDisplay);
600     if (!(NearEqual(defaultDisplay->GetWidth(), window_->GetRect().width_) &&
601         NearEqual(defaultDisplay->GetHeight(), window_->GetRect().height_))) {
602         auto container = Container::Current();
603         CHECK_NULL_VOID(container);
604         auto taskExecutor = container->GetTaskExecutor();
605         CHECK_NULL_VOID(taskExecutor);
606         taskExecutor->PostTask(
607             [this]() {
608                 ResizeWindow();
609             },
610             TaskExecutor::TaskType::UI, "ArkUIResizeDialogSubwindow");
611     }
612 }
613 
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)614 void SubwindowOhos::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
615 {
616     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup enter");
617 #ifndef NG_BUILD
618     ShowWindow();
619     auto stack = GetStack();
620     CHECK_NULL_VOID(stack);
621     auto popup = AceType::DynamicCast<TweenComponent>(newComponent);
622     CHECK_NULL_VOID(popup);
623     stack->PopPopup(popup->GetId());
624     stack->PushComponent(newComponent, disableTouchEvent);
625     auto bubble = AceType::DynamicCast<BubbleComponent>(popup->GetChild());
626     if (bubble) {
627         bubble->SetWeakStack(WeakClaim(RawPtr(stack)));
628     }
629 #endif
630 }
631 
CancelPopup(const std::string & id)632 bool SubwindowOhos::CancelPopup(const std::string& id)
633 {
634     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "cancel popup enter");
635 #ifndef NG_BUILD
636     auto stack = GetStack();
637     CHECK_NULL_RETURN(stack, false);
638     stack->PopPopup(id);
639     auto context = stack->GetContext().Upgrade();
640     CHECK_NULL_RETURN(context, false);
641     context->FlushPipelineImmediately();
642     HideWindow();
643 #endif
644     return true;
645 }
646 
ShowPopupNG(int32_t targetId,const NG::PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)647 void SubwindowOhos::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo,
648     const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
649 {
650     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show popup ng enter, subwindowId: %{public}d", window_->GetWindowId());
651     popupTargetId_ = targetId;
652     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
653     CHECK_NULL_VOID(aceContainer);
654     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
655     CHECK_NULL_VOID(context);
656     auto overlayManager = context->GetOverlayManager();
657     CHECK_NULL_VOID(overlayManager);
658     ResizeWindow();
659     ShowWindow(popupInfo.focusable);
660     CHECK_NULL_VOID(window_);
661     window_->SetTouchable(true);
662     ContainerScope scope(childContainerId_);
663     needAvoidKeyboard_ = popupInfo.isAvoidKeyboard;
664     overlayManager->ShowPopup(targetId, popupInfo, std::move(onWillDismiss), interactiveDismiss);
665     window_->SetFocusable(true);
666 }
667 
HidePopupNG(int32_t targetId)668 void SubwindowOhos::HidePopupNG(int32_t targetId)
669 {
670     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
671         "hide popup ng enter, subwindowId: %{public}d, subwindowName: %{public}s",
672         window_->GetWindowId(), window_->GetWindowName().c_str());
673     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
674     CHECK_NULL_VOID(aceContainer);
675     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
676     CHECK_NULL_VOID(context);
677     auto overlayManager = context->GetOverlayManager();
678     CHECK_NULL_VOID(overlayManager);
679     auto popupInfo = overlayManager->GetPopupInfo(targetId == -1 ? popupTargetId_ : targetId);
680     popupInfo.markNeedUpdate = true;
681     ContainerScope scope(childContainerId_);
682     overlayManager->HidePopup(targetId == -1 ? popupTargetId_ : targetId, popupInfo);
683     context->FlushPipelineImmediately();
684     HideEventColumn();
685     HidePixelMap();
686 }
687 
ShowTipsNG(int32_t targetId,const NG::PopupInfo & popupInfo,int32_t appearingTime,int32_t appearingTimeWithContinuousOperation,bool isSubwindow)688 void SubwindowOhos::ShowTipsNG(int32_t targetId, const NG::PopupInfo& popupInfo, int32_t appearingTime,
689     int32_t appearingTimeWithContinuousOperation, bool isSubwindow)
690 {
691     popupTargetId_ = targetId;
692     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
693     CHECK_NULL_VOID(aceContainer);
694     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
695     CHECK_NULL_VOID(context);
696     auto overlayManager = context->GetOverlayManager();
697     CHECK_NULL_VOID(overlayManager);
698     ResizeWindow();
699     ShowWindow(popupInfo.focusable);
700     CHECK_NULL_VOID(window_);
701     window_->SetTouchable(true);
702     ContainerScope scope(childContainerId_);
703     overlayManager->ShowTips(targetId, popupInfo, appearingTime, appearingTimeWithContinuousOperation, isSubwindow);
704     window_->SetFocusable(true);
705 }
706 
HideTipsNG(int32_t targetId,int32_t disappearingTime)707 void SubwindowOhos::HideTipsNG(int32_t targetId, int32_t disappearingTime)
708 {
709     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
710     CHECK_NULL_VOID(aceContainer);
711     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
712     CHECK_NULL_VOID(context);
713     auto overlayManager = context->GetOverlayManager();
714     CHECK_NULL_VOID(overlayManager);
715     auto popupInfo = overlayManager->GetPopupInfo(targetId == -1 ? popupTargetId_ : targetId);
716     popupInfo.markNeedUpdate = true;
717     ContainerScope scope(childContainerId_);
718     overlayManager->HideTips(targetId == -1 ? popupTargetId_ : targetId, popupInfo, disappearingTime);
719     context->FlushPipelineImmediately();
720     HideEventColumn();
721     HidePixelMap();
722 }
723 
GetPopupInfoNG(int32_t targetId,NG::PopupInfo & popupInfo)724 void SubwindowOhos::GetPopupInfoNG(int32_t targetId, NG::PopupInfo& popupInfo)
725 {
726     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get popup info ng enter");
727     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
728     CHECK_NULL_VOID(aceContainer);
729     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
730     CHECK_NULL_VOID(context);
731     auto overlayManager = context->GetOverlayManager();
732     CHECK_NULL_VOID(overlayManager);
733     popupInfo = overlayManager->GetPopupInfo(targetId);
734 }
735 
GetOverlayManager()736 const RefPtr<NG::OverlayManager> SubwindowOhos::GetOverlayManager()
737 {
738     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
739     CHECK_NULL_RETURN(aceContainer, nullptr);
740     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
741     CHECK_NULL_RETURN(context, nullptr);
742     return context->GetOverlayManager();
743 }
744 
ShowWindow(bool needFocus)745 void SubwindowOhos::ShowWindow(bool needFocus)
746 {
747     CHECK_NULL_VOID(window_);
748     if (isShowed_) {
749         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u is on display", window_->GetWindowId());
750         if (needFocus) {
751             window_->SetFocusable(needFocus);
752             RequestFocus();
753         }
754         return;
755     }
756     // Set min window hot area so that sub window can transparent event.
757     std::vector<Rosen::Rect> hotAreas;
758     Rosen::Rect rosenRect {};
759     RectConverter(MIN_WINDOW_HOT_AREA, rosenRect);
760     hotAreas.emplace_back(rosenRect);
761     window_->SetTouchHotAreas(hotAreas);
762 
763     window_->SetNeedDefaultAnimation(false);
764     auto ret = window_->SetFocusable(needFocus);
765     if (ret != OHOS::Rosen::WMError::WM_OK) {
766         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW,
767             "subwindow id:%{public}u set focusable %{public}d failed with WMError: %{public}d", window_->GetWindowId(),
768             needFocus, static_cast<int32_t>(ret));
769     }
770     ret = window_->Show(0, false, needFocus);
771     attachState_ = MenuWindowState::ATTACHING;
772     if (ret != OHOS::Rosen::WMError::WM_OK) {
773         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Show subwindow id:%{public}u failed with WMError: %{public}d",
774             window_->GetWindowId(), static_cast<int32_t>(ret));
775         return;
776     }
777     if (needFocus) {
778         RequestFocus();
779     }
780 
781     InitializeSafeArea();
782     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
783     CHECK_NULL_VOID(aceContainer);
784     auto context = aceContainer->GetPipelineContext();
785     CHECK_NULL_VOID(context);
786     AccessibilityEvent event;
787     event.type = AccessibilityEventType::PAGE_CHANGE;
788     event.windowId = context->GetWindowId();
789     event.windowChangeTypes = WINDOW_UPDATE_ADDED;
790     context->SendEventToAccessibility(event);
791     isShowed_ = true;
792     if (ifNeedSetCurrentWindow_) {
793         SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
794     }
795 }
796 
HideWindow()797 void SubwindowOhos::HideWindow()
798 {
799     CHECK_NULL_VOID(window_);
800     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Hide the subwindow %{public}s", window_->GetWindowName().c_str());
801 
802     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
803     if (!aceContainer) {
804         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get container failed, child containerId: %{public}d", childContainerId_);
805         return;
806     }
807 
808 #ifdef NG_BUILD
809     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
810     CHECK_NULL_VOID(context);
811     auto rootNode = context->GetRootElement();
812     CHECK_NULL_VOID(rootNode);
813     if (!rootNode->GetChildren().empty() &&
814         !(rootNode->GetChildren().size() == 1 && rootNode->GetLastChild()->GetTag() == V2::KEYBOARD_ETS_TAG)) {
815         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Subwindow has other node, the last child is %{public}s",
816             rootNode->GetLastChild()->GetTag().c_str());
817         auto lastChildId = rootNode->GetLastChild()->GetId();
818         auto iter = hotAreasMap_.find(lastChildId);
819         if (iter != hotAreasMap_.end()) {
820             auto hotAreaRect = iter->second;
821             OHOS::Rosen::WMError ret = window_->SetTouchHotAreas(hotAreaRect);
822             if (ret != OHOS::Rosen::WMError::WM_OK) {
823                 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Set hot areas failed with errCode: %{public}d",
824                     static_cast<int32_t>(ret));
825             }
826         }
827         return;
828     }
829     auto focusHub = rootNode->GetFocusHub();
830     CHECK_NULL_VOID(focusHub);
831     focusHub->SetIsDefaultHasFocused(false);
832     context->SetIsFocusActive(false);
833 #else
834     if (Container::IsCurrentUseNewPipeline()) {
835         auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
836         CHECK_NULL_VOID(context);
837         auto rootNode = context->GetRootElement();
838         CHECK_NULL_VOID(rootNode);
839         if (!rootNode->GetChildren().empty() &&
840             !(rootNode->GetChildren().size() == 1 && rootNode->GetLastChild()->GetTag() == V2::KEYBOARD_ETS_TAG)) {
841             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Subwindow has other node, the last child is %{public}s",
842                 rootNode->GetLastChild()->GetTag().c_str());
843             return;
844         }
845         auto focusHub = rootNode->GetFocusHub();
846         CHECK_NULL_VOID(focusHub);
847         focusHub->SetIsDefaultHasFocused(false);
848         context->SetIsFocusActive(false);
849     } else {
850         auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
851         CHECK_NULL_VOID(context);
852         auto rootNode = context->GetRootElement();
853         CHECK_NULL_VOID(rootNode);
854         rootNode->SetIsDefaultHasFocused(false);
855     }
856 #endif
857     if (!window_->IsFocused()) {
858         ContainerModalUnFocus();
859     }
860     OHOS::Rosen::WMError ret = window_->Hide();
861     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
862     if (!parentContainer) {
863         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get container failed, parent containerId: %{public}d", parentContainerId_);
864         return;
865     }
866     if (parentContainer->IsSceneBoardWindow()) {
867         window_->SetTouchable(true);
868     }
869 
870     if (ret != OHOS::Rosen::WMError::WM_OK) {
871         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Hide window failed with errCode: %{public}d", static_cast<int32_t>(ret));
872         return;
873     }
874     if (isShowed_) {
875         detachState_ = MenuWindowState::DETACHING;
876     }
877     isShowed_ = false;
878     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Hide the subwindow successfully.");
879 #ifndef NG_BUILD
880     auto context = aceContainer->GetPipelineContext();
881     CHECK_NULL_VOID(context);
882 #endif
883     AccessibilityEvent event;
884     event.type = AccessibilityEventType::PAGE_CHANGE;
885     event.windowId = context->GetWindowId();
886     event.windowChangeTypes = WINDOW_UPDATE_REMOVED;
887     context->SendEventToAccessibility(event);
888 }
889 
ContainerModalUnFocus()890 void SubwindowOhos::ContainerModalUnFocus()
891 {
892     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
893     CHECK_NULL_VOID(parentContainer);
894     auto parentWindowName = parentContainer->GetWindowName();
895     sptr<OHOS::Rosen::Window> parentWindow = OHOS::Rosen::Window::Find(parentWindowName);
896     CHECK_NULL_VOID(parentWindow);
897     if (parentWindow->GetFocusable() && !parentWindow->IsFocused()) {
898         auto pipelineContext = parentContainer->GetPipelineContext();
899         CHECK_NULL_VOID(pipelineContext);
900         pipelineContext->ContainerModalUnFocus();
901     }
902 }
903 
AddMenu(const RefPtr<Component> & newComponent)904 void SubwindowOhos::AddMenu(const RefPtr<Component>& newComponent)
905 {
906     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "add menu enter");
907 #ifndef NG_BUILD
908     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow push new component start.");
909     auto stack = GetStack();
910     CHECK_NULL_VOID(stack);
911     // Push the component
912     stack->PopMenu();
913     stack->PushComponent(newComponent);
914     popup_ = AceType::DynamicCast<SelectPopupComponent>(newComponent);
915 #endif
916 }
917 
ClearMenu()918 void SubwindowOhos::ClearMenu()
919 {
920     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu enter");
921     if (haveDialog_) {
922         return;
923     }
924 #ifndef NG_BUILD
925     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow Clear menu start.");
926     auto stack = GetStack();
927     CHECK_NULL_VOID(stack);
928     // Pop the component
929     stack->PopMenu();
930     auto context = stack->GetContext().Upgrade();
931     CHECK_NULL_VOID(context);
932     context->FlushPipelineImmediately();
933     HideWindow();
934 #endif
935 }
936 
ShowPreviewNG(bool isStartDraggingFromSubWindow)937 bool SubwindowOhos::ShowPreviewNG(bool isStartDraggingFromSubWindow)
938 {
939     CHECK_NULL_RETURN(window_, false);
940     ResizeWindow();
941     ShowWindow(false);
942     if (!isStartDraggingFromSubWindow) {
943         window_->SetTouchable(false);
944     }
945     return true;
946 }
947 
HidePreviewNG()948 void SubwindowOhos::HidePreviewNG()
949 {
950     auto overlayManager = GetOverlayManager();
951     CHECK_NULL_VOID(overlayManager);
952     overlayManager->RemovePixelMap();
953     overlayManager->RemovePreviewBadgeNode();
954     overlayManager->RemoveGatherNode();
955     overlayManager->RemoveEventColumn();
956     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
957     CHECK_NULL_VOID(aceContainer);
958     auto pipeline = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
959     CHECK_NULL_VOID(pipeline);
960     pipeline->FlushPipelineImmediately();
961     HideSubWindowNG();
962 }
963 
ShowMenuNG(const RefPtr<NG::FrameNode> customNode,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)964 void SubwindowOhos::ShowMenuNG(const RefPtr<NG::FrameNode> customNode, const NG::MenuParam& menuParam,
965     const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
966 {
967     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
968     CHECK_NULL_VOID(customNode);
969     if (!targetNode) {
970         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "targetNode is nullptr");
971         return;
972     }
973     ContainerScope scope(childContainerId_);
974     auto overlay = GetOverlayManager();
975     CHECK_NULL_VOID(overlay);
976     auto menuNode = customNode;
977     if (customNode->GetTag() != V2::MENU_WRAPPER_ETS_TAG) {
978         menuNode = NG::MenuView::Create(customNode, targetNode->GetId(), targetNode->GetTag(), menuParam, true);
979         auto menuWrapperPattern = menuNode->GetPattern<NG::MenuWrapperPattern>();
980         CHECK_NULL_VOID(menuWrapperPattern);
981         menuWrapperPattern->RegisterMenuCallback(menuNode, menuParam);
982         menuWrapperPattern->SetMenuTransitionEffect(menuNode, menuParam);
983     }
984     ResizeWindowForMenu();
985     ShowWindow();
986     CHECK_NULL_VOID(window_);
987     window_->SetTouchable(true);
988     overlay->ShowMenuInSubWindow(targetNode->GetId(), offset, menuNode);
989 }
990 
ShowMenuNG(std::function<void ()> && buildFunc,std::function<void ()> && previewBuildFunc,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)991 void SubwindowOhos::ShowMenuNG(std::function<void()>&& buildFunc, std::function<void()>&& previewBuildFunc,
992     const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
993 {
994     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
995     if (!targetNode) {
996         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "targetNode is nullptr");
997         return;
998     }
999     ContainerScope scope(childContainerId_);
1000     auto overlay = GetOverlayManager();
1001     CHECK_NULL_VOID(overlay);
1002     ResizeWindowForMenu();
1003     ShowWindow();
1004     CHECK_NULL_VOID(window_);
1005     window_->SetTouchable(true);
1006     NG::ScopedViewStackProcessor builderViewStackProcessor;
1007     buildFunc();
1008     auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
1009     RefPtr<NG::UINode> previewCustomNode;
1010     if (previewBuildFunc && menuParam.previewMode == MenuPreviewMode::CUSTOM) {
1011         previewBuildFunc();
1012         previewCustomNode = NG::ViewStackProcessor::GetInstance()->Finish();
1013     }
1014     auto menuNode =
1015         NG::MenuView::Create(customNode, targetNode->GetId(), targetNode->GetTag(), menuParam, true, previewCustomNode);
1016     auto menuWrapperPattern = menuNode->GetPattern<NG::MenuWrapperPattern>();
1017     CHECK_NULL_VOID(menuWrapperPattern);
1018     menuWrapperPattern->RegisterMenuCallback(menuNode, menuParam);
1019     menuWrapperPattern->SetMenuTransitionEffect(menuNode, menuParam);
1020     overlay->ShowMenuInSubWindow(targetNode->GetId(), offset, menuNode);
1021 }
1022 
HideMenuNG(bool showPreviewAnimation,bool startDrag)1023 void SubwindowOhos::HideMenuNG(bool showPreviewAnimation, bool startDrag)
1024 {
1025     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
1026     if (!isShowed_) {
1027         return;
1028     }
1029     ContainerScope scope(childContainerId_);
1030     auto overlay = GetOverlayManager();
1031     CHECK_NULL_VOID(overlay);
1032     overlay->HideMenuInSubWindow(showPreviewAnimation, startDrag);
1033     HideEventColumn();
1034     HidePixelMap(startDrag, 0, 0, false);
1035 }
1036 
HideMenuNG(const RefPtr<NG::FrameNode> & menu,int32_t targetId)1037 void SubwindowOhos::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)
1038 {
1039     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
1040     if (!isShowed_) {
1041         return;
1042     }
1043     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Subwindow hide menu for target id %{public}d", targetId);
1044     auto overlay = GetOverlayManager();
1045     CHECK_NULL_VOID(overlay);
1046     overlay->HideMenuInSubWindow(menu, targetId);
1047     HideEventColumn();
1048     HidePixelMap(false, 0, 0, false);
1049 }
1050 
UpdatePreviewPosition()1051 void SubwindowOhos::UpdatePreviewPosition()
1052 {
1053     ContainerScope scope(childContainerId_);
1054     auto overlay = GetOverlayManager();
1055     CHECK_NULL_VOID(overlay);
1056     if (overlay->GetHasPixelMap()) {
1057         return;
1058     }
1059     overlay->UpdatePixelMapPosition(true);
1060 }
1061 
GetMenuPreviewCenter(NG::OffsetF & offset)1062 bool SubwindowOhos::GetMenuPreviewCenter(NG::OffsetF& offset)
1063 {
1064     ContainerScope scope(childContainerId_);
1065     auto overlay = GetOverlayManager();
1066     CHECK_NULL_RETURN(overlay, false);
1067     return overlay->GetMenuPreviewCenter(offset);
1068 }
1069 
UpdateHideMenuOffsetNG(const NG::OffsetF & offset,float menuScale,bool isRedragStart,int32_t menuWrapperId)1070 void SubwindowOhos::UpdateHideMenuOffsetNG(
1071     const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
1072 {
1073     ContainerScope scope(childContainerId_);
1074     auto overlay = GetOverlayManager();
1075     CHECK_NULL_VOID(overlay);
1076     if (overlay->IsContextMenuDragHideFinished()) {
1077         return;
1078     }
1079     overlay->UpdateContextMenuDisappearPosition(offset, menuScale, isRedragStart, menuWrapperId);
1080 }
1081 
ContextMenuSwitchDragPreviewAnimationtNG(const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)1082 void SubwindowOhos::ContextMenuSwitchDragPreviewAnimationtNG(const RefPtr<NG::FrameNode>& dragPreviewNode,
1083     const NG::OffsetF& offset)
1084 {
1085     CHECK_NULL_VOID(dragPreviewNode);
1086     ContainerScope scope(childContainerId_);
1087     auto overlay = GetOverlayManager();
1088     CHECK_NULL_VOID(overlay);
1089     overlay->ContextMenuSwitchDragPreviewAnimation(dragPreviewNode, offset);
1090 }
1091 
ClearMenuNG(int32_t targetId,bool inWindow,bool showAnimation)1092 void SubwindowOhos::ClearMenuNG(int32_t targetId, bool inWindow, bool showAnimation)
1093 {
1094     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "clear menu ng enter");
1095     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1096     CHECK_NULL_VOID(aceContainer);
1097     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1098     CHECK_NULL_VOID(context);
1099     auto overlay = context->GetOverlayManager();
1100     CHECK_NULL_VOID(overlay);
1101     if (showAnimation) {
1102         overlay->CleanMenuInSubWindowWithAnimation();
1103     } else {
1104         overlay->CleanMenuInSubWindow(targetId);
1105     }
1106     HideWindow();
1107     if (overlay->GetMenuNode(targetId)) {
1108         context->FlushPipelineImmediately();
1109     }
1110     overlay->EraseMenuInfo(targetId);
1111     if (inWindow) {
1112         HideEventColumn();
1113     }
1114     HidePixelMap(false, 0, 0, false);
1115 }
1116 
ClearPopupNG()1117 void SubwindowOhos::ClearPopupNG()
1118 {
1119     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear popup ng enter");
1120     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1121     CHECK_NULL_VOID(aceContainer);
1122     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1123     CHECK_NULL_VOID(context);
1124     auto overlay = context->GetOverlayManager();
1125     CHECK_NULL_VOID(overlay);
1126     overlay->CleanPopupInSubWindow();
1127     HideWindow();
1128     context->FlushPipelineImmediately();
1129 }
1130 
ClearPopupNG(bool isForceClear)1131 void SubwindowOhos::ClearPopupNG(bool isForceClear)
1132 {
1133     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear popup ng enter");
1134     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1135     CHECK_NULL_VOID(aceContainer);
1136     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1137     CHECK_NULL_VOID(context);
1138     auto overlay = context->GetOverlayManager();
1139     CHECK_NULL_VOID(overlay);
1140     overlay->CleanPopupInSubWindow(isForceClear);
1141     HideWindow();
1142     context->FlushPipelineImmediately();
1143 }
1144 
ShowMenu(const RefPtr<Component> & newComponent)1145 void SubwindowOhos::ShowMenu(const RefPtr<Component>& newComponent)
1146 {
1147     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show menu enter");
1148     ShowWindow();
1149     AddMenu(newComponent);
1150 }
1151 
CloseMenu()1152 void SubwindowOhos::CloseMenu()
1153 {
1154     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close menu enter");
1155 #ifndef NG_BUILD
1156     if (!isShowed_) {
1157         return;
1158     }
1159     if (popup_) {
1160         popup_->CloseContextMenu();
1161     }
1162 #endif
1163 }
1164 
GetStack()1165 RefPtr<StackElement> SubwindowOhos::GetStack()
1166 {
1167 #ifndef NG_BUILD
1168     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1169     CHECK_NULL_RETURN(aceContainer, nullptr);
1170 
1171     auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
1172     CHECK_NULL_RETURN(context, nullptr);
1173     return context->GetLastStack();
1174 #else
1175     return nullptr;
1176 #endif
1177 }
1178 
DeleteHotAreas(int32_t nodeId)1179 void SubwindowOhos::DeleteHotAreas(int32_t nodeId)
1180 {
1181     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "delete hot area %{public}d", nodeId);
1182     CHECK_NULL_VOID(window_);
1183     hotAreasMap_.erase(nodeId);
1184     if (hotAreasMap_.size() == 0) {
1185         // Set min window hot area so that sub window can transparent event.
1186         std::vector<Rosen::Rect> hotAreas;
1187         Rosen::Rect rosenRect {};
1188         RectConverter(MIN_WINDOW_HOT_AREA, rosenRect);
1189         hotAreas.emplace_back(rosenRect);
1190         window_->SetTouchHotAreas(hotAreas);
1191         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hotAreasMap_ has no item");
1192         return;
1193     }
1194     std::vector<Rosen::Rect> hotAreas;
1195     for (auto it = hotAreasMap_.begin(); it != hotAreasMap_.end(); it++) {
1196         hotAreas.insert(hotAreas.end(), it->second.begin(), it->second.end());
1197     }
1198     CHECK_NULL_VOID(window_);
1199     window_->SetTouchHotAreas(hotAreas);
1200 }
1201 
SetHotAreas(const std::vector<Rect> & rects,int32_t nodeId)1202 void SubwindowOhos::SetHotAreas(const std::vector<Rect>& rects, int32_t nodeId)
1203 {
1204     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot areas enter");
1205     CHECK_NULL_VOID(window_);
1206 
1207     std::vector<Rosen::Rect> hotAreas;
1208     Rosen::Rect rosenRect {};
1209     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "set hot area %{public}d", nodeId);
1210     for (const auto& rect : rects) {
1211         TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot area rect %{public}s", rect.ToString().c_str());
1212         RectConverter(rect, rosenRect);
1213         hotAreas.emplace_back(rosenRect);
1214     }
1215     if (nodeId >= 0) {
1216         hotAreasMap_[nodeId] = hotAreas;
1217     }
1218 
1219     std::vector<Rosen::Rect> hotAreasNow;
1220     for (auto it = hotAreasMap_.begin(); it != hotAreasMap_.end(); it++) {
1221         hotAreasNow.insert(hotAreasNow.end(), it->second.begin(), it->second.end());
1222     }
1223     window_->SetTouchHotAreas(hotAreasNow);
1224 }
1225 
RectConverter(const Rect & rect,Rosen::Rect & rosenRect)1226 void SubwindowOhos::RectConverter(const Rect& rect, Rosen::Rect& rosenRect)
1227 {
1228     rosenRect.posX_ = static_cast<int>(rect.GetOffset().GetX());
1229     rosenRect.posY_ = static_cast<int>(rect.GetOffset().GetY());
1230     rosenRect.width_ = static_cast<uint32_t>(rect.GetSize().Width());
1231     rosenRect.height_ = static_cast<uint32_t>(rect.GetSize().Height());
1232     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
1233         "Convert rect to rosenRect, x is %{public}d, y is %{public}d, width is %{public}d, height is %{public}d",
1234         rosenRect.posX_, rosenRect.posY_, rosenRect.width_, rosenRect.height_);
1235 }
1236 
ShowBindSheetNG(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<NG::UINode> ()> && buildNodeFunc,std::function<RefPtr<NG::UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<NG::FrameNode> & targetNode)1237 void SubwindowOhos::ShowBindSheetNG(bool isShow, std::function<void(const std::string&)>&& callback,
1238     std::function<RefPtr<NG::UINode>()>&& buildNodeFunc, std::function<RefPtr<NG::UINode>()>&& buildtitleNodeFunc,
1239     NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
1240     std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
1241     std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
1242     std::function<void(const float)>&& onHeightDidChange,
1243     std::function<void(const float)>&& onDetentsDidChange,
1244     std::function<void(const float)>&& onWidthDidChange,
1245     std::function<void(const float)>&& onTypeDidChange,
1246     std::function<void()>&& sheetSpringBack, const RefPtr<NG::FrameNode>& targetNode)
1247 {
1248     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1249     CHECK_NULL_VOID(aceContainer);
1250     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1251     CHECK_NULL_VOID(context);
1252     auto overlay = context->GetOverlayManager();
1253     CHECK_NULL_VOID(overlay);
1254     ResizeWindow();
1255     ShowWindow();
1256     CHECK_NULL_VOID(window_);
1257     window_->SetFullScreen(true);
1258     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1259     CHECK_NULL_VOID(parentAceContainer);
1260     if (parentAceContainer->IsUIExtensionWindow()) {
1261         window_->SetFollowParentWindowLayoutEnabled(true);
1262     }
1263     window_->SetTouchable(true);
1264     ContainerScope scope(childContainerId_);
1265     overlay->OnBindSheet(isShow, std::move(callback), std::move(buildNodeFunc),
1266         std::move(buildtitleNodeFunc), sheetStyle, std::move(onAppear), std::move(onDisappear),
1267         std::move(shouldDismiss), std::move(onWillDismiss),
1268         std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
1269         std::move(onDetentsDidChange), std::move(onWidthDidChange), std::move(onTypeDidChange),
1270         std::move(sheetSpringBack), targetNode);
1271 }
1272 
ShowDialogNG(const DialogProperties & dialogProps,std::function<void ()> && buildFunc)1273 RefPtr<NG::FrameNode> SubwindowOhos::ShowDialogNG(
1274     const DialogProperties& dialogProps, std::function<void()>&& buildFunc)
1275 {
1276     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
1277     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1278     CHECK_NULL_RETURN(aceContainer, nullptr);
1279     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1280     CHECK_NULL_RETURN(context, nullptr);
1281     auto overlay = context->GetOverlayManager();
1282     CHECK_NULL_RETURN(overlay, nullptr);
1283     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1284     CHECK_NULL_RETURN(parentAceContainer, nullptr);
1285     std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
1286     int dialogMapSize = static_cast<int>(DialogMap.size());
1287     if (dialogMapSize == 0) {
1288         auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1289         CHECK_NULL_RETURN(parentcontext, nullptr);
1290         auto parentOverlay = parentcontext->GetOverlayManager();
1291         CHECK_NULL_RETURN(parentOverlay, nullptr);
1292         parentOverlay->SetSubWindowId(childContainerId_);
1293     }
1294     auto dialogTheme = context->GetTheme<DialogTheme>();
1295     CHECK_NULL_RETURN(dialogTheme, nullptr);
1296     ResizeWindow();
1297     if (dialogTheme->GetExpandDisplay() || parentAceContainer->IsFreeMultiWindow()) {
1298         SetFollowParentWindowLayoutEnabled(false);
1299     } else {
1300         SetFollowParentWindowLayoutEnabled(true);
1301     }
1302     ShowWindow(dialogProps.focusable);
1303     CHECK_NULL_RETURN(window_, nullptr);
1304     window_->SetFullScreen(true);
1305     window_->SetTouchable(true);
1306     ContainerScope scope(childContainerId_);
1307     auto dialog = overlay->ShowDialog(dialogProps, std::move(buildFunc));
1308     CHECK_NULL_RETURN(dialog, nullptr);
1309     if (parentAceContainer->IsUIExtensionWindow() && dialogProps.isModal) {
1310         window_->SetFollowParentWindowLayoutEnabled(true);
1311         SetNodeId(dialog->GetId());
1312         SubwindowManager::GetInstance()->AddSubwindow(
1313             parentContainerId_, SubwindowType::TYPE_DIALOG, AceType::Claim(this), dialog->GetId());
1314     }
1315     haveDialog_ = true;
1316     return dialog;
1317 }
1318 
ShowDialogNGWithNode(const DialogProperties & dialogProps,const RefPtr<NG::UINode> & customNode)1319 RefPtr<NG::FrameNode> SubwindowOhos::ShowDialogNGWithNode(
1320     const DialogProperties& dialogProps, const RefPtr<NG::UINode>& customNode)
1321 {
1322     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
1323     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1324     CHECK_NULL_RETURN(aceContainer, nullptr);
1325     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1326     CHECK_NULL_RETURN(context, nullptr);
1327     auto overlay = context->GetOverlayManager();
1328     CHECK_NULL_RETURN(overlay, nullptr);
1329     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1330     CHECK_NULL_RETURN(parentAceContainer, nullptr);
1331     std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
1332     int dialogMapSize = static_cast<int>(DialogMap.size());
1333     if (dialogMapSize == 0) {
1334         auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1335         CHECK_NULL_RETURN(parentcontext, nullptr);
1336         auto parentOverlay = parentcontext->GetOverlayManager();
1337         CHECK_NULL_RETURN(parentOverlay, nullptr);
1338         parentOverlay->SetSubWindowId(childContainerId_);
1339     }
1340     auto dialogTheme = context->GetTheme<DialogTheme>();
1341     CHECK_NULL_RETURN(dialogTheme, nullptr);
1342     ResizeWindow();
1343     if (dialogTheme->GetExpandDisplay() || parentAceContainer->IsFreeMultiWindow()) {
1344         SetFollowParentWindowLayoutEnabled(false);
1345     } else {
1346         SetFollowParentWindowLayoutEnabled(true);
1347     }
1348     ShowWindow(dialogProps.focusable);
1349     CHECK_NULL_RETURN(window_, nullptr);
1350     window_->SetFullScreen(true);
1351     window_->SetTouchable(true);
1352     ContainerScope scope(childContainerId_);
1353     auto dialog = overlay->ShowDialogWithNode(dialogProps, customNode);
1354     CHECK_NULL_RETURN(dialog, nullptr);
1355     if (parentAceContainer->IsUIExtensionWindow() && dialogProps.isModal) {
1356         window_->SetFollowParentWindowLayoutEnabled(true);
1357         SetNodeId(dialog->GetId());
1358         SubwindowManager::GetInstance()->AddSubwindow(
1359             parentContainerId_, SubwindowType::TYPE_DIALOG, AceType::Claim(this), dialog->GetId());
1360     }
1361     haveDialog_ = true;
1362     return dialog;
1363 }
1364 
CloseDialogNG(const RefPtr<NG::FrameNode> & dialogNode)1365 void SubwindowOhos::CloseDialogNG(const RefPtr<NG::FrameNode>& dialogNode)
1366 {
1367     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog ng enter");
1368     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1369     CHECK_NULL_VOID(aceContainer);
1370     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1371     CHECK_NULL_VOID(context);
1372     auto overlay = context->GetOverlayManager();
1373     CHECK_NULL_VOID(overlay);
1374     ContainerScope scope(childContainerId_);
1375     return overlay->CloseDialog(dialogNode);
1376 }
1377 
OpenCustomDialogNG(const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)1378 void SubwindowOhos::OpenCustomDialogNG(const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
1379 {
1380     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "open customDialog ng subwindow enter");
1381     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1382     CHECK_NULL_VOID(aceContainer);
1383     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1384     CHECK_NULL_VOID(context);
1385     auto overlay = context->GetOverlayManager();
1386     CHECK_NULL_VOID(overlay);
1387     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1388     CHECK_NULL_VOID(parentAceContainer);
1389     std::map<int32_t, RefPtr<NG::FrameNode>> DialogMap(overlay->GetDialogMap().begin(), overlay->GetDialogMap().end());
1390     int dialogMapSize = static_cast<int>(DialogMap.size());
1391     if (dialogMapSize == 0) {
1392         auto parentcontext = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
1393         CHECK_NULL_VOID(parentcontext);
1394         auto parentOverlay = parentcontext->GetOverlayManager();
1395         CHECK_NULL_VOID(parentOverlay);
1396         parentOverlay->SetSubWindowId(childContainerId_);
1397         TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "overlay in parent container %{public}d, SetSubWindowId %{public}d",
1398             parentContainerId_, childContainerId_);
1399     }
1400     auto dialogTheme = context->GetTheme<DialogTheme>();
1401     CHECK_NULL_VOID(dialogTheme);
1402     ResizeWindow();
1403     if (dialogTheme->GetExpandDisplay() || parentAceContainer->IsFreeMultiWindow()) {
1404         SetFollowParentWindowLayoutEnabled(false);
1405     } else {
1406         SetFollowParentWindowLayoutEnabled(true);
1407     }
1408     ShowWindow(dialogProps.focusable);
1409     CHECK_NULL_VOID(window_);
1410     window_->SetFullScreen(true);
1411     window_->SetTouchable(true);
1412     ContainerScope scope(childContainerId_);
1413     auto dialog = overlay->OpenCustomDialog(dialogProps, std::move(callback));
1414     CHECK_NULL_VOID(dialog);
1415     if (parentAceContainer->IsUIExtensionWindow() && dialogProps.isModal) {
1416         window_->SetFollowParentWindowLayoutEnabled(true);
1417         SetNodeId(dialog->GetId());
1418         SubwindowManager::GetInstance()->AddSubwindow(
1419             parentContainerId_, SubwindowType::TYPE_DIALOG, AceType::Claim(this), dialog->GetId());
1420     }
1421     haveDialog_ = true;
1422 }
1423 
CloseCustomDialogNG(int32_t dialogId)1424 void SubwindowOhos::CloseCustomDialogNG(int32_t dialogId)
1425 {
1426     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng subwindow enter, child container id %{public}d",
1427         childContainerId_);
1428     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1429     CHECK_NULL_VOID(aceContainer);
1430     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1431     CHECK_NULL_VOID(context);
1432     auto overlay = context->GetOverlayManager();
1433     CHECK_NULL_VOID(overlay);
1434     ContainerScope scope(childContainerId_);
1435     return overlay->CloseCustomDialog(dialogId);
1436 }
1437 
CloseCustomDialogNG(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)1438 void SubwindowOhos::CloseCustomDialogNG(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
1439 {
1440     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng subwindow enter, child container id %{public}d",
1441         childContainerId_);
1442     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1443     CHECK_NULL_VOID(aceContainer);
1444     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1445     CHECK_NULL_VOID(context);
1446     auto overlay = context->GetOverlayManager();
1447     CHECK_NULL_VOID(overlay);
1448     ContainerScope scope(childContainerId_);
1449     return overlay->CloseCustomDialog(node, std::move(callback));
1450 }
1451 
UpdateCustomDialogNG(const WeakPtr<NG::UINode> & node,const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)1452 void SubwindowOhos::UpdateCustomDialogNG(
1453     const WeakPtr<NG::UINode>& node, const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
1454 {
1455     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "update customDialog ng subwindow enter");
1456     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1457     CHECK_NULL_VOID(aceContainer);
1458     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1459     CHECK_NULL_VOID(context);
1460     auto overlay = context->GetOverlayManager();
1461     CHECK_NULL_VOID(overlay);
1462     ContainerScope scope(childContainerId_);
1463     return overlay->UpdateCustomDialog(node, dialogProps, std::move(callback));
1464 }
1465 
HideSubWindowNG()1466 void SubwindowOhos::HideSubWindowNG()
1467 {
1468     ContainerScope scope(childContainerId_);
1469     auto container = Container::Current();
1470     CHECK_NULL_VOID(container);
1471     if (container->IsDialogContainer()) {
1472         if (IsToastWindow()) {
1473             Platform::AceContainer::HideWindow(Container::CurrentId());
1474         } else {
1475             Platform::AceContainer::CloseWindow(Container::CurrentId());
1476             Platform::AceContainer::DestroyContainer(Container::CurrentId());
1477         }
1478     } else {
1479         auto context = container->GetPipelineContext();
1480         if (context) {
1481             context->FlushPipelineImmediately();
1482         }
1483         HideWindow();
1484     }
1485 }
1486 
GetToastDialogWindowProperty(int32_t & width,int32_t & height,int32_t & posX,int32_t & posY,float & density) const1487 void SubwindowOhos::GetToastDialogWindowProperty(
1488     int32_t& width, int32_t& height, int32_t& posX, int32_t& posY, float& density) const
1489 {
1490     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get toast dialog window property enter");
1491     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
1492     auto subwindowOhos = AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1493     if (subwindowOhos) {
1494         auto dialogWindow = subwindowOhos->GetDialogWindow();
1495         if (dialogWindow) {
1496             auto currentDisplay = Rosen::DisplayManager::GetInstance().GetDisplayById(dialogWindow->GetDisplayId());
1497             defaultDisplay = currentDisplay ? currentDisplay : defaultDisplay;
1498         }
1499     }
1500 
1501     if (defaultDisplay) {
1502         posX = 0;
1503         posY = 0;
1504         width = defaultDisplay->GetWidth();
1505         height = defaultDisplay->GetHeight();
1506         density = defaultDisplay->GetVirtualPixelRatio();
1507     }
1508     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
1509         "Toast posX: %{public}d, posY: %{public}d, width: %{public}d, height: %{public}d, density: %{public}f", posX,
1510         posY, width, height, density);
1511 }
1512 
InitDialogWindowRSUIDirector(const RefPtr<Platform::AceContainer> & container)1513 void SubwindowOhos::InitDialogWindowRSUIDirector(const RefPtr<Platform::AceContainer>& container)
1514 {
1515 #ifdef ENABLE_ROSEN_BACKEND
1516     if (!SystemProperties::GetMultiInstanceEnabled()) {
1517         rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
1518         if (rsUiDirector != nullptr) {
1519             rsUiDirector->SetRSSurfaceNode(dialogWindow_->GetSurfaceNode());
1520             auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
1521             if (context != nullptr) {
1522                 context->SetRSUIDirector(rsUiDirector);
1523             }
1524             rsUiDirector->Init();
1525         }
1526     } else {
1527         rsUiDirector = dialogWindow_->GetRSUIDirector();
1528         if (!rsUiDirector) {
1529             rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
1530         }
1531         rsUiDirector->SetRSSurfaceNode(dialogWindow_->GetSurfaceNode());
1532         auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
1533         if (context != nullptr) {
1534             context->SetRSUIDirector(rsUiDirector);
1535         }
1536         rsUiDirector->Init(true, true);
1537     }
1538 #endif
1539 }
1540 
InitToastDialogWindow(int32_t & width,int32_t & height,int32_t posX,int32_t posY,bool isToast)1541 bool SubwindowOhos::InitToastDialogWindow(int32_t& width, int32_t& height, int32_t posX, int32_t posY, bool isToast)
1542 {
1543     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window enter");
1544     OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
1545     if (isToast) {
1546         auto windowType =
1547             IsSystemTopMost() ? Rosen::WindowType::WINDOW_TYPE_SYSTEM_TOAST : Rosen::WindowType::WINDOW_TYPE_TOAST;
1548         windowOption->SetWindowType(windowType);
1549     } else {
1550         windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1551     }
1552     windowOption->SetWindowRect({ posX, posY, static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
1553     windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
1554     windowOption->SetFocusable(!isToast);
1555     int32_t dialogId = gToastDialogId.fetch_add(1, std::memory_order_relaxed);
1556     std::string windowName = "ARK_APP_SUBWINDOW_TOAST_DIALOG_" + std::to_string(dialogId);
1557     if (isToast) {
1558         auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
1559         dialogWindow_ = OHOS::Rosen::Window::Create(windowName, windowOption, context);
1560     } else {
1561         dialogWindow_ = OHOS::Rosen::Window::Create(windowName, windowOption);
1562     }
1563     CHECK_NULL_RETURN(dialogWindow_, false);
1564     dialogWindow_->SetLayoutFullScreen(true);
1565     dialogWindow_->SetSubWindowSource(Rosen::SubWindowSource::SUB_WINDOW_SOURCE_ARKUI);
1566     auto focusWindowId = dialogWindow_->GetDisplayId();
1567     auto focusDisplayInfo = Rosen::DisplayManager::GetInstance().GetDisplayById(focusWindowId);
1568     CHECK_NULL_RETURN(focusDisplayInfo, false);
1569     width = focusDisplayInfo->GetWidth();
1570     height = focusDisplayInfo->GetHeight();
1571     return true;
1572 }
1573 
InitToastDialogView(int32_t width,int32_t height,float density)1574 bool SubwindowOhos::InitToastDialogView(int32_t width, int32_t height, float density)
1575 {
1576     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view enter");
1577 #ifndef NG_BUILD
1578     dialogWindow_->NapiSetUIContent("", (napi_env)nullptr, (napi_value)nullptr, Rosen::BackupAndRestoreType::NONE);
1579     childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(dialogWindow_->GetWindowId());
1580     SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
1581     ContainerScope scope(childContainerId_);
1582 
1583     auto container = Platform::DialogContainer::GetContainer(childContainerId_);
1584     CHECK_NULL_RETURN(container, false);
1585     // create ace_view
1586     auto aceView = Platform::AceViewOhos::CreateView(childContainerId_, true, true);
1587     Platform::AceViewOhos::SurfaceCreated(aceView, dialogWindow_);
1588     // set view
1589     Platform::DialogContainer::SetView(aceView, density, width, height, dialogWindow_);
1590     container->CheckAndSetFontFamily();
1591     Ace::Platform::DialogContainer::SetUIWindow(childContainerId_, dialogWindow_);
1592     ViewportConfig config(width, height, density);
1593     Platform::AceViewOhos::SetViewportMetrics(aceView, config);
1594     Platform::AceViewOhos::SurfaceChanged(aceView, width, height, 0);
1595 
1596 #ifdef ENABLE_ROSEN_BACKEND
1597     if (SystemProperties::GetRosenBackendEnabled()) {
1598         InitDialogWindowRSUIDirector(container);
1599     }
1600 #endif
1601 
1602     auto pipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1603     CHECK_NULL_RETURN(pipelineContext, false);
1604     pipelineContext->SetupSubRootElement();
1605     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1606     if (parentContainer) {
1607         auto parentPipeline = parentContainer->GetPipelineContext();
1608         CHECK_NULL_RETURN(parentPipeline, false);
1609         pipelineContext->SetMinPlatformVersion(parentPipeline->GetMinPlatformVersion());
1610         pipelineContext->SetApiTargetVersion(parentPipeline->GetApiTargetVersion());
1611     } else {
1612         pipelineContext->SetMinPlatformVersion(PLATFORM_VERSION_TEN);
1613         pipelineContext->SetApiTargetVersion(container->GetApiTargetVersion());
1614     }
1615     return true;
1616 #else
1617     return true;
1618 #endif
1619 }
1620 
InitToastServiceConfig()1621 bool SubwindowOhos::InitToastServiceConfig()
1622 {
1623     auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
1624     CHECK_NULL_RETURN(context, false);
1625     auto config = context->GetConfiguration();
1626     CHECK_NULL_RETURN(config, false);
1627     auto maxAppFontScale = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_MAX_SCALE);
1628     auto followSystem = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_SIZE_SCALE);
1629     auto container = Platform::DialogContainer::GetContainer(childContainerId_);
1630     CHECK_NULL_RETURN(container, false);
1631     auto pipelineContext = container->GetPipelineContext();
1632     CHECK_NULL_RETURN(pipelineContext, false);
1633     auto isFollowSystem = followSystem == "followSystem";
1634     if (!followSystem.empty()) {
1635         pipelineContext->SetFollowSystem(isFollowSystem);
1636     }
1637     if (!maxAppFontScale.empty()) {
1638         pipelineContext->SetMaxAppFontScale(StringUtils::StringToFloat(maxAppFontScale));
1639     }
1640     if (!isFollowSystem) {
1641         pipelineContext->SetFontScale(1.0f);
1642     }
1643     auto fontScale = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE);
1644     if (!fontScale.empty()) {
1645         pipelineContext->SetFontScale(StringUtils::StringToFloat(fontScale));
1646     }
1647 
1648     return true;
1649 }
1650 
CreateEventRunner()1651 bool SubwindowOhos::CreateEventRunner()
1652 {
1653     std::lock_guard<std::mutex> lock(eventRunnerMutex_);
1654     if (!eventLoop_) {
1655         eventLoop_ = AppExecFwk::EventRunner::Create("Subwindow_Toast_Dialog");
1656         CHECK_NULL_RETURN(eventLoop_, false);
1657         handler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
1658         CHECK_NULL_RETURN(handler_, false);
1659     }
1660     return true;
1661 }
1662 
ClearToast()1663 void SubwindowOhos::ClearToast()
1664 {
1665     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast enter");
1666     if (!IsToastWindow()) {
1667         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "default toast needs not to be clear");
1668         return;
1669     }
1670     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1671     CHECK_NULL_VOID(aceContainer);
1672     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1673     CHECK_NULL_VOID(context);
1674     auto overlayManager = context->GetOverlayManager();
1675     CHECK_NULL_VOID(overlayManager);
1676     ContainerScope scope(childContainerId_);
1677     overlayManager->ClearToast();
1678     context->FlushPipelineImmediately();
1679     HideWindow();
1680 }
1681 
ShowToastForAbility(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)1682 void SubwindowOhos::ShowToastForAbility(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
1683 {
1684     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast for ability enter, containerId : %{public}d", childContainerId_);
1685     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
1686     CHECK_NULL_VOID(parentContainer);
1687     SetIsToastWindow(
1688         toastInfo.showMode == NG::ToastShowMode::TOP_MOST || toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
1689     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1690     if (!aceContainer) {
1691         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get container failed, child containerId : %{public}d", childContainerId_);
1692         return;
1693     }
1694 
1695     auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1696     RefPtr<Framework::FrontendDelegate> delegate;
1697     if (!engine) {
1698         auto frontend = AceType::DynamicCast<DeclarativeFrontend>(aceContainer->GetFrontend());
1699         CHECK_NULL_VOID(frontend);
1700         delegate = frontend->GetDelegate();
1701         if (!delegate) {
1702             TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get engine failed, containerId : %{public}d",
1703                 aceContainer->GetInstanceId());
1704             return;
1705         }
1706     } else {
1707         delegate = engine->GetFrontend();
1708         if (!delegate) {
1709             TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "get frontend failed, child containerId : %{public}d",
1710                 childContainerId_);
1711             return;
1712         }
1713     }
1714     ContainerScope scope(childContainerId_);
1715     if (parentContainer->IsSceneBoardWindow() || toastInfo.showMode == NG::ToastShowMode::TOP_MOST ||
1716         toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST) {
1717         ResizeWindow();
1718         ifNeedSetCurrentWindow_ = false;
1719         ShowWindow(false);
1720         CHECK_NULL_VOID(window_);
1721         window_->SetTouchable(false);
1722     }
1723     delegate->ShowToast(toastInfo, std::move(callback));
1724 }
1725 
ShowToastForService(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)1726 void SubwindowOhos::ShowToastForService(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
1727 {
1728     bool ret = CreateEventRunner();
1729     if (!ret) {
1730         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1731         return;
1732     }
1733 
1734     SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1735     if (!handler_->PostTask(GetInitToastDelayTask(toastInfo, std::move(callback)))) {
1736         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1737         return;
1738     }
1739 }
1740 
ShowToast(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)1741 void SubwindowOhos::ShowToast(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
1742 {
1743     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show toast, window parent id is %{public}d", parentContainerId_);
1744     auto isTopMost = toastInfo.showMode == NG::ToastShowMode::TOP_MOST;
1745     // for pa service
1746     if ((isTopMost && parentContainerId_ >= MIN_PA_SERVICE_ID && parentContainerId_ < MIN_SUBCONTAINER_ID) ||
1747         (!isTopMost && parentContainerId_ >= MIN_PA_SERVICE_ID) || parentContainerId_ < 0) {
1748         ShowToastForService(toastInfo, std::move(callback));
1749     } else {
1750         ShowToastForAbility(toastInfo, std::move(callback));
1751     }
1752 }
1753 
CloseToast(const int32_t toastId,std::function<void (int32_t)> && callback)1754 void SubwindowOhos::CloseToast(const int32_t toastId, std::function<void(int32_t)>&& callback)
1755 {
1756     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close toast enter");
1757     if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1758         auto subwindowOhos =
1759             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1760         CHECK_NULL_VOID(subwindowOhos);
1761         auto childContainerId = subwindowOhos->GetChildContainerId();
1762         CHECK_NULL_VOID(childContainerId);
1763         ContainerScope scope(childContainerId);
1764         Platform::DialogContainer::CloseToast(childContainerId, toastId, std::move(callback));
1765     } else {
1766         auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1767         CHECK_NULL_VOID(aceContainer);
1768         auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1769         auto delegate = engine->GetFrontend();
1770         CHECK_NULL_VOID(delegate);
1771         ContainerScope scope(childContainerId_);
1772         delegate->CloseToast(toastId, std::move(callback));
1773     }
1774 }
1775 
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)1776 void SubwindowOhos::ShowDialogForAbility(const std::string& title, const std::string& message,
1777     const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1778     const std::set<std::string>& callbacks)
1779 {
1780     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog for ability enter");
1781     SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1782 
1783     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1784     if (!aceContainer) {
1785         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get container failed, child containerId : %{public}d", childContainerId_);
1786         return;
1787     }
1788 
1789     auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1790     auto delegate = engine->GetFrontend();
1791     if (!delegate) {
1792         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed, child containerId : %{public}d", childContainerId_);
1793         return;
1794     }
1795     delegate->ShowDialog(title, message, buttons, autoCancel, std::move(callback), callbacks);
1796 }
1797 
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)1798 void SubwindowOhos::ShowDialogForService(const std::string& title, const std::string& message,
1799     const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1800     const std::set<std::string>& callbacks)
1801 {
1802     bool ret = CreateEventRunner();
1803     if (!ret) {
1804         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1805         return;
1806     }
1807 
1808     SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1809     auto showDialogCallback = [title, message, &buttons, autoCancel, callbackParam = std::move(callback),
1810                                   &callbacks]() {
1811         int32_t posX = 0;
1812         int32_t posY = 0;
1813         int32_t width = 0;
1814         int32_t height = 0;
1815         float density = 1.0f;
1816         auto subwindowOhos =
1817             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1818         CHECK_NULL_VOID(subwindowOhos);
1819         subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
1820         bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
1821         if (!ret) {
1822             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
1823             return;
1824         }
1825         ret = subwindowOhos->InitToastDialogView(width, height, density);
1826         if (!ret) {
1827             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
1828             return;
1829         }
1830         auto childContainerId = subwindowOhos->GetChildContainerId();
1831         ContainerScope scope(childContainerId);
1832         auto container = Platform::AceContainer::GetContainer(childContainerId);
1833         CHECK_NULL_VOID(container);
1834         container->SetFontScaleAndWeightScale(childContainerId);
1835         Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
1836         Platform::DialogContainer::ShowDialog(childContainerId, title, message, buttons, autoCancel,
1837             std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)), callbacks);
1838     };
1839     isToastWindow_ = false;
1840     if (!handler_->PostTask(showDialogCallback)) {
1841         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1842         return;
1843     }
1844 }
1845 
ShowDialogForAbility(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1846 void SubwindowOhos::ShowDialogForAbility(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1847     std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1848 {
1849     SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1850 
1851     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1852     if (!aceContainer) {
1853         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get ace container failed");
1854         return;
1855     }
1856 
1857     auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1858     auto delegate = engine->GetFrontend();
1859     if (!delegate) {
1860         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed");
1861         return;
1862     }
1863     delegate->ShowDialog(dialogAttr, buttons, std::move(callback), callbacks);
1864 }
1865 
ShowDialogForService(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1866 void SubwindowOhos::ShowDialogForService(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1867     std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1868 {
1869     bool ret = CreateEventRunner();
1870     if (!ret) {
1871         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
1872         return;
1873     }
1874 
1875     SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
1876     auto showDialogCallback = [dialogAttr, &buttons, callbackParam = std::move(callback), &callbacks]() {
1877         int32_t posX = 0;
1878         int32_t posY = 0;
1879         int32_t width = 0;
1880         int32_t height = 0;
1881         float density = 1.0f;
1882         auto subwindowOhos =
1883             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
1884         CHECK_NULL_VOID(subwindowOhos);
1885         subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
1886         bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
1887         if (!ret) {
1888             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog window failed");
1889             return;
1890         }
1891         ret = subwindowOhos->InitToastDialogView(width, height, density);
1892         if (!ret) {
1893             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
1894             return;
1895         }
1896         auto childContainerId = subwindowOhos->GetChildContainerId();
1897         ContainerScope scope(childContainerId);
1898         Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
1899         Platform::DialogContainer::ShowDialog(childContainerId, dialogAttr, buttons,
1900             std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)), callbacks);
1901     };
1902     isToastWindow_ = false;
1903     if (!handler_->PostTask(showDialogCallback)) {
1904         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
1905         return;
1906     }
1907 }
1908 
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)1909 void SubwindowOhos::ShowDialog(const std::string& title, const std::string& message,
1910     const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
1911     const std::set<std::string>& callbacks)
1912 {
1913     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show dialog, window parent id is %{public}d", parentContainerId_);
1914     if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1915         ShowDialogForService(title, message, buttons, autoCancel, std::move(callback), callbacks);
1916     } else {
1917         ShowDialogForAbility(title, message, buttons, autoCancel, std::move(callback), callbacks);
1918     }
1919 }
1920 
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)1921 void SubwindowOhos::ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1922     std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
1923 {
1924     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show dialog with attr, window parent id is %{public}d", parentContainerId_);
1925     if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1926         ShowDialogForService(dialogAttr, buttons, std::move(callback), callbacks);
1927     } else {
1928         ShowDialogForAbility(dialogAttr, buttons, std::move(callback), callbacks);
1929     }
1930 }
1931 
OpenCustomDialogForAbility(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1932 void SubwindowOhos::OpenCustomDialogForAbility(
1933     const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1934 {
1935     SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
1936 
1937     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1938     if (!aceContainer) {
1939         TAG_LOGW(
1940             AceLogTag::ACE_SUB_WINDOW, "open dialog fail, the container %{public}d can not find", childContainerId_);
1941         return;
1942     }
1943 
1944     auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
1945     auto delegate = engine->GetFrontend();
1946     if (!delegate) {
1947         return;
1948     }
1949     delegate->OpenCustomDialog(dialogAttr, std::move(callback));
1950 }
1951 
OpenCustomDialogForService(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1952 void SubwindowOhos::OpenCustomDialogForService(
1953     const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1954 {
1955     // temporary not support
1956     TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "temporary not support for service by promptAction with CustomBuilder");
1957 }
1958 
OpenCustomDialog(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1959 void SubwindowOhos::OpenCustomDialog(const PromptDialogAttr& dialogAttr, std::function<void(int32_t)>&& callback)
1960 {
1961     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "open custom dialog, window parent id is %{public}d", parentContainerId_);
1962     if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
1963         OpenCustomDialogForService(dialogAttr, std::move(callback));
1964     } else {
1965         OpenCustomDialogForAbility(dialogAttr, std::move(callback));
1966     }
1967 }
1968 
CloseCustomDialog(const int32_t dialogId)1969 void SubwindowOhos::CloseCustomDialog(const int32_t dialogId)
1970 {
1971     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close custom dialog with id, childContainerId_ is %{public}d",
1972         childContainerId_);
1973     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1974     CHECK_NULL_VOID(aceContainer);
1975     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1976     CHECK_NULL_VOID(context);
1977     auto overlay = context->GetOverlayManager();
1978     CHECK_NULL_VOID(overlay);
1979     ContainerScope scope(childContainerId_);
1980     return overlay->CloseCustomDialog(dialogId);
1981 }
1982 
CloseCustomDialog(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)1983 void SubwindowOhos::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
1984 {
1985     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "close custom dialog with node, childContainerId_ is %{public}d",
1986         childContainerId_);
1987     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
1988     CHECK_NULL_VOID(aceContainer);
1989     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
1990     CHECK_NULL_VOID(context);
1991     auto overlay = context->GetOverlayManager();
1992     CHECK_NULL_VOID(overlay);
1993     ContainerScope scope(childContainerId_);
1994     return overlay->CloseCustomDialog(node, std::move(callback));
1995 }
1996 
ShowActionMenuForAbility(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)1997 void SubwindowOhos::ShowActionMenuForAbility(
1998     const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
1999 {
2000     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu for ability enter");
2001     SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
2002 
2003     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
2004     if (!aceContainer) {
2005         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get container failed");
2006         return;
2007     }
2008 
2009     auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
2010     auto delegate = engine->GetFrontend();
2011     if (!delegate) {
2012         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get frontend failed");
2013         return;
2014     }
2015     delegate->ShowActionMenu(title, button, std::move(callback));
2016 }
2017 
ShowActionMenuForService(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)2018 void SubwindowOhos::ShowActionMenuForService(
2019     const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
2020 {
2021     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu for service enter");
2022     bool ret = CreateEventRunner();
2023     if (!ret) {
2024         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create event runner failed");
2025         return;
2026     }
2027 
2028     SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
2029     auto showDialogCallback = [title, &button, callbackParam = std::move(callback)]() {
2030         int32_t posX = 0;
2031         int32_t posY = 0;
2032         int32_t width = 0;
2033         int32_t height = 0;
2034         float density = 1.0f;
2035         auto subwindowOhos =
2036             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
2037         CHECK_NULL_VOID(subwindowOhos);
2038         subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
2039         bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
2040         if (!ret) {
2041             return;
2042         }
2043         ret = subwindowOhos->InitToastDialogView(width, height, density);
2044         if (!ret) {
2045             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "init toast dialog view failed");
2046             return;
2047         }
2048         auto childContainerId = subwindowOhos->GetChildContainerId();
2049         ContainerScope scope(childContainerId);
2050         auto container = Platform::AceContainer::GetContainer(childContainerId);
2051         CHECK_NULL_VOID(container);
2052         container->SetFontScaleAndWeightScale(childContainerId);
2053         Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
2054         Platform::DialogContainer::ShowActionMenu(childContainerId, title, button,
2055             std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)));
2056     };
2057     isToastWindow_ = false;
2058     if (!handler_->PostTask(showDialogCallback)) {
2059         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "create show dialog callback failed");
2060         return;
2061     }
2062 }
2063 
CloseDialog(int32_t instanceId)2064 void SubwindowOhos::CloseDialog(int32_t instanceId)
2065 {
2066     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog enter");
2067     Platform::DialogContainer::CloseWindow(instanceId);
2068 }
2069 
UpdateAceView(int32_t width,int32_t height,float density,int32_t containerId)2070 void SubwindowOhos::UpdateAceView(int32_t width, int32_t height, float density, int32_t containerId)
2071 {
2072     auto container = Platform::DialogContainer::GetContainer(containerId);
2073     CHECK_NULL_VOID(container);
2074     auto aceView = AceType::DynamicCast<Platform::AceViewOhos>(container->GetAceView());
2075     CHECK_NULL_VOID(aceView);
2076     if (aceView->GetWidth() != width || aceView->GetHeight() != height) {
2077         ViewportConfig config(width, height, density);
2078         Platform::AceViewOhos::SetViewportMetrics(aceView, config);
2079         Platform::AceViewOhos::SurfaceChanged(aceView, width, height, 0);
2080     }
2081 }
2082 
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)2083 void SubwindowOhos::ShowActionMenu(
2084     const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
2085 {
2086     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "show custom dialog, window parent id is %{public}d", parentContainerId_);
2087     if (parentContainerId_ >= MIN_PA_SERVICE_ID || parentContainerId_ < 0) {
2088         ShowActionMenuForService(title, button, std::move(callback));
2089     } else {
2090         ShowActionMenuForAbility(title, button, std::move(callback));
2091     }
2092 }
2093 
GetParentWindowRect() const2094 Rect SubwindowOhos::GetParentWindowRect() const
2095 {
2096     Rect rect;
2097     CHECK_NULL_RETURN(parentWindow_, rect);
2098     auto parentWindowRect = parentWindow_->GetRect();
2099     return Rect(parentWindowRect.posX_, parentWindowRect.posY_, parentWindowRect.width_, parentWindowRect.height_);
2100 }
2101 
GetUIExtensionHostWindowRect() const2102 Rect SubwindowOhos::GetUIExtensionHostWindowRect() const
2103 {
2104     Rect rect;
2105     CHECK_NULL_RETURN(parentWindow_, rect);
2106     auto id = GetUIExtensionHostWindowId();
2107     auto hostWindowRect = parentWindow_->GetHostWindowRect(id);
2108     return Rect(hostWindowRect.posX_, hostWindowRect.posY_, hostWindowRect.width_, hostWindowRect.height_);
2109 }
2110 
GetFoldExpandAvailableRect() const2111 Rect SubwindowOhos::GetFoldExpandAvailableRect() const
2112 {
2113     CHECK_NULL_RETURN(window_, Rect());
2114     Rosen::DMRect rect;
2115     Rosen::DMError ret = Rosen::DisplayManager::GetInstance().GetExpandAvailableArea(DEFAULT_DISPLAY_ID, rect);
2116     if (ret != Rosen::DMError::DM_OK) {
2117         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "failed to get expandAvailableArea");
2118         return Rect();
2119     }
2120 
2121     return Rect(rect.posX_, rect.posY_, rect.width_, rect.height_);
2122 }
2123 
GetWindowRect() const2124 NG::RectF SubwindowOhos::GetWindowRect() const
2125 {
2126     NG::RectF rect;
2127     CHECK_NULL_RETURN(window_, rect);
2128     rect.SetRect(window_->GetRect().posX_, window_->GetRect().posY_,
2129         window_->GetRect().width_, window_->GetRect().height_);
2130     return rect;
2131 }
2132 
RequestFocus()2133 void SubwindowOhos::RequestFocus()
2134 {
2135     CHECK_NULL_VOID(window_);
2136     if (window_->IsFocused()) {
2137         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u already focused", window_->GetWindowId());
2138         // already focused, no need to focus
2139         return;
2140     }
2141     OHOS::Rosen::WMError ret = window_->RequestFocus();
2142     if (ret != OHOS::Rosen::WMError::WM_OK) {
2143         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subindow id:%{public}u request focus failed with WMError: %{public}d",
2144             window_->GetWindowId(), static_cast<int32_t>(ret));
2145         return;
2146     }
2147     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow id:%{public}u request focus successfully.", window_->GetWindowId());
2148 }
2149 
IsFocused()2150 bool SubwindowOhos::IsFocused()
2151 {
2152     CHECK_NULL_RETURN(window_, false);
2153     return window_->IsFocused();
2154 }
2155 
HidePixelMap(bool startDrag,double x,double y,bool showAnimation)2156 void SubwindowOhos::HidePixelMap(bool startDrag, double x, double y, bool showAnimation)
2157 {
2158     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
2159     CHECK_NULL_VOID(parentAceContainer);
2160     auto parentPipeline = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
2161     CHECK_NULL_VOID(parentPipeline);
2162     auto manager = parentPipeline->GetOverlayManager();
2163     CHECK_NULL_VOID(manager);
2164     ContainerScope scope(parentContainerId_);
2165     if (!startDrag) {
2166         manager->RemovePreviewBadgeNode();
2167         manager->RemoveGatherNodeWithAnimation();
2168     }
2169     if (showAnimation) {
2170         manager->RemovePixelMapAnimation(startDrag, x, y, true);
2171     } else {
2172         manager->RemovePixelMap();
2173     }
2174 }
2175 
HideEventColumn()2176 void SubwindowOhos::HideEventColumn()
2177 {
2178     auto parentAceContainer = Platform::AceContainer::GetContainer(parentContainerId_);
2179     CHECK_NULL_VOID(parentAceContainer);
2180     auto parentPipeline = DynamicCast<NG::PipelineContext>(parentAceContainer->GetPipelineContext());
2181     CHECK_NULL_VOID(parentPipeline);
2182     auto manager = parentPipeline->GetOverlayManager();
2183     CHECK_NULL_VOID(manager);
2184     ContainerScope scope(parentContainerId_);
2185     manager->RemoveEventColumn();
2186 }
2187 
ResizeWindowForFoldStatus(int32_t parentContainerId)2188 void SubwindowOhos::ResizeWindowForFoldStatus(int32_t parentContainerId)
2189 {
2190     auto callback = []() {
2191         auto subwindowOhos =
2192             AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
2193         CHECK_NULL_VOID(subwindowOhos);
2194         auto childContainerId = subwindowOhos->GetChildContainerId();
2195         ContainerScope scope(childContainerId);
2196         auto window = Platform::DialogContainer::GetUIWindow(childContainerId);
2197         CHECK_NULL_VOID(window);
2198         auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
2199         CHECK_NULL_VOID(defaultDisplay);
2200         auto ret = window->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
2201         if (ret != Rosen::WMError::WM_OK) {
2202             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
2203                 static_cast<int32_t>(ret));
2204             return;
2205         }
2206         auto container = Platform::DialogContainer::GetContainer(childContainerId);
2207         CHECK_NULL_VOID(container);
2208         // get ace_view
2209         auto aceView = AceType::DynamicCast<Platform::AceViewOhos>(container->GetAceView());
2210         CHECK_NULL_VOID(aceView);
2211         Platform::AceViewOhos::SurfaceChanged(aceView, defaultDisplay->GetWidth(), defaultDisplay->GetHeight(), 0);
2212     };
2213     if (parentContainerId > 0 && parentContainerId < MIN_PA_SERVICE_ID) {
2214         ResizeWindowForFoldStatus();
2215         return;
2216     }
2217     if (!handler_->PostTask(callback)) {
2218         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize Toast Window failed");
2219     }
2220 }
2221 
ResizeWindowForFoldStatus()2222 void SubwindowOhos::ResizeWindowForFoldStatus()
2223 {
2224     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
2225     CHECK_NULL_VOID(defaultDisplay);
2226     CHECK_NULL_VOID(window_);
2227     auto ret = window_->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
2228     if (ret != Rosen::WMError::WM_OK) {
2229         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Resize window by default display failed with errCode: %{public}d",
2230             static_cast<int32_t>(ret));
2231         return;
2232     }
2233     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
2234         "foldStatus is changed, subwindowOhos is resized to [%{public}d, %{public}d, %{public}u, %{public}u]",
2235         window_->GetRect().posX_, window_->GetRect().posY_, window_->GetRect().width_, window_->GetRect().height_);
2236 }
2237 
MarkDirtyDialogSafeArea()2238 void SubwindowOhos::MarkDirtyDialogSafeArea()
2239 {
2240     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
2241     CHECK_NULL_VOID(aceContainer);
2242     auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
2243     CHECK_NULL_VOID(context);
2244     auto rootNode = context->GetRootElement();
2245     CHECK_NULL_VOID(rootNode);
2246     auto lastChild = rootNode->GetLastChild();
2247     CHECK_NULL_VOID(lastChild);
2248     lastChild->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2249 }
2250 
CheckHostWindowStatus() const2251 bool SubwindowOhos::CheckHostWindowStatus() const
2252 {
2253     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
2254     CHECK_NULL_RETURN(parentContainer, false);
2255     sptr<OHOS::Rosen::Window> parentWindow = parentContainer->GetUIWindow(parentContainerId_);
2256     CHECK_NULL_RETURN(parentWindow, false);
2257     if (parentWindow->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION) {
2258         auto parentPipeline = parentContainer->GetPipelineContext();
2259         CHECK_NULL_RETURN(parentPipeline, false);
2260         auto hostWindowId = parentPipeline->GetFocusWindowId();
2261         auto hostWindowRect = parentWindow->GetHostWindowRect(hostWindowId);
2262         auto isValid = GreatNotEqual(hostWindowRect.width_, 0) && GreatNotEqual(hostWindowRect.height_, 0);
2263         if (!isValid) {
2264             TAG_LOGW(AceLogTag::ACE_SUB_WINDOW,
2265                 "UIExtension Window failed to obtain host window information. Please check if permissions are enabled");
2266             return false;
2267         }
2268     }
2269     return true;
2270 }
2271 
Close()2272 bool SubwindowOhos::Close()
2273 {
2274     // prevent repeated closure when subWindow's container is destroying
2275     if (isClosing_) {
2276         TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "current window is closing.");
2277         return false;
2278     }
2279 
2280     CHECK_NULL_RETURN(window_, false);
2281     window_->UnregisterSwitchFreeMultiWindowListener(freeMultiWindowListener_);
2282     isClosing_ = true;
2283     OHOS::Rosen::WMError ret = window_->Destroy();
2284     isClosing_ = false;
2285     if (ret != OHOS::Rosen::WMError::WM_OK) {
2286         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "SubwindowOhos failed to close the dialog subwindow.");
2287         return false;
2288     }
2289     sptr<OHOS::Rosen::Window> uiWindow = nullptr;
2290     Ace::Platform::DialogContainer::SetUIWindow(childContainerId_, uiWindow);
2291     return true;
2292 }
2293 
IsFreeMultiWindow() const2294 bool SubwindowOhos::IsFreeMultiWindow() const
2295 {
2296     if (!parentWindow_) {
2297         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Window is null, failed to get freeMultiWindow status");
2298         return false;
2299     }
2300 
2301     return parentWindow_->GetFreeMultiWindowModeEnabledState();
2302 }
2303 
OnFreeMultiWindowSwitch(bool enable)2304 void SubwindowOhos::OnFreeMultiWindowSwitch(bool enable)
2305 {
2306     for (auto&& [id, callback] : freeMultiWindowSwitchCallbackMap_) {
2307         if (callback) {
2308             callback(enable);
2309         }
2310     }
2311 }
2312 
RegisterFreeMultiWindowSwitchCallback(std::function<void (bool)> && callback)2313 int32_t SubwindowOhos::RegisterFreeMultiWindowSwitchCallback(std::function<void(bool)>&& callback)
2314 {
2315     if (callback) {
2316         freeMultiWindowSwitchCallbackMap_.emplace(++callbackId_, std::move(callback));
2317         return callbackId_;
2318     }
2319     return 0;
2320 }
2321 
UnRegisterFreeMultiWindowSwitchCallback(int32_t callbackId)2322 void SubwindowOhos::UnRegisterFreeMultiWindowSwitchCallback(int32_t callbackId)
2323 {
2324     freeMultiWindowSwitchCallbackMap_.erase(callbackId);
2325 }
2326 
IsToastSubWindow()2327 bool SubwindowOhos::IsToastSubWindow()
2328 {
2329     CHECK_NULL_RETURN(window_, false);
2330     auto windowType = window_->GetType();
2331     return windowType == Rosen::WindowType::WINDOW_TYPE_SYSTEM_TOAST ||
2332            windowType == Rosen::WindowType::WINDOW_TYPE_TOAST;
2333 }
2334 
DestroyWindow()2335 void SubwindowOhos::DestroyWindow()
2336 {
2337     CHECK_NULL_VOID(window_);
2338     OHOS::Rosen::WMError ret = window_->Destroy();
2339     if (ret != OHOS::Rosen::WMError::WM_OK) {
2340         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "SubwindowOhos failed to destroy the dialog subwindow.");
2341         return;
2342     }
2343 }
2344 
GetDisplayId()2345 uint64_t SubwindowOhos::GetDisplayId()
2346 {
2347     if (window_) {
2348         return window_->GetDisplayId();
2349     }
2350     return 0;
2351 }
2352 
IsSameDisplayWithParentWindow(bool useInitializedId)2353 bool SubwindowOhos::IsSameDisplayWithParentWindow(bool useInitializedId)
2354 {
2355     CHECK_NULL_RETURN(window_, false);
2356     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
2357     CHECK_NULL_RETURN(parentContainer, false);
2358     auto parentWindow = parentContainer->GetUIWindow(parentContainerId_);
2359     CHECK_NULL_RETURN(parentWindow, false);
2360     auto displayId = useInitializedId ? defaultDisplayId_ : window_->GetDisplayId();
2361     return displayId == parentWindow->GetDisplayId();
2362 }
2363 
InitializeSafeArea()2364 void SubwindowOhos::InitializeSafeArea()
2365 {
2366     CHECK_NULL_VOID(window_);
2367 
2368     auto container = Platform::AceContainer::GetContainer(childContainerId_);
2369     CHECK_NULL_VOID(container);
2370     auto pipeline = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2371     CHECK_NULL_VOID(pipeline);
2372     auto theme = pipeline->GetTheme<SelectTheme>();
2373     CHECK_NULL_VOID(theme);
2374 
2375     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
2376     CHECK_NULL_VOID(parentContainer);
2377 
2378     std::optional<NG::RectF> windowRect;
2379     if (theme->GetExpandDisplay() || parentContainer->IsFreeMultiWindow()) {
2380         auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDisplayById(window_->GetDisplayId());
2381         CHECK_NULL_VOID(defaultDisplay);
2382         windowRect = { 0.0, 0.0, static_cast<float>(defaultDisplay->GetWidth()),
2383             static_cast<float>(defaultDisplay->GetHeight()) };
2384     }
2385 
2386     auto systemSafeArea = container->GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_SYSTEM, windowRect);
2387     auto navSafeArea = container->GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR, windowRect);
2388     pipeline->UpdateSystemSafeArea(systemSafeArea);
2389     pipeline->UpdateNavSafeArea(navSafeArea);
2390     auto cutoutSafeArea = container->GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_CUTOUT, windowRect);
2391     pipeline->UpdateCutoutSafeArea(cutoutSafeArea);
2392 
2393     auto safeAreaInsets = pipeline->GetSafeAreaWithoutProcess();
2394     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "initializeSafeArea by windowRect: %{public}s, safeAreaInsets: %{public}s",
2395         windowRect.value_or(NG::RectF()).ToString().c_str(), safeAreaInsets.ToString().c_str());
2396 }
2397 
ShowSelectOverlay(const RefPtr<NG::FrameNode> & overlayNode)2398 bool SubwindowOhos::ShowSelectOverlay(const RefPtr<NG::FrameNode>& overlayNode)
2399 {
2400     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Show selectOverlay enter");
2401     ContainerScope scope(childContainerId_);
2402     CHECK_NULL_RETURN(window_, false);
2403     ResizeWindow();
2404     ShowWindow(false);
2405     if (!isShowed_) {
2406         TAG_LOGW(AceLogTag::ACE_SUB_WINDOW,
2407             "Show selectOverlay subwindow failed, subwindow not show after showWindow called.");
2408         return false;
2409     }
2410     auto context = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
2411     CHECK_NULL_RETURN(context, false);
2412     auto rootNode = context->GetRootElement();
2413     CHECK_NULL_RETURN(rootNode, false);
2414     CHECK_NULL_RETURN(overlayNode, false);
2415     overlayNode->MountToParent(rootNode);
2416     rootNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
2417     window_->SetTouchable(true);
2418     window_->KeepKeyboardOnFocus(true);
2419     window_->SetFocusable(false);
2420     return true;
2421 }
2422 
SwitchFollowParentWindowLayout(bool freeMultiWindowEnable)2423 void SubwindowOhos::SwitchFollowParentWindowLayout(bool freeMultiWindowEnable)
2424 {
2425     TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "subwindow switch followParentWindowLayout, enable: %{public}d",
2426         freeMultiWindowEnable);
2427     if (nodeId_ != DEFAULT_NODE_ID) {
2428         LOGI("modal dialog subwindows created by UEC always follow parent.");
2429         return;
2430     }
2431     auto expandDisplay = SubwindowManager::GetInstance()->GetIsExpandDisplay();
2432     if (NeedFollowParentWindowLayout() && !expandDisplay && !freeMultiWindowEnable) {
2433         SetFollowParentWindowLayoutEnabled(true);
2434     } else if (SetFollowParentWindowLayoutEnabled(false)) {
2435         ResizeWindow();
2436     }
2437 }
2438 
AddFollowParentWindowLayoutNode(int32_t nodeId)2439 void SubwindowOhos::AddFollowParentWindowLayoutNode(int32_t nodeId)
2440 {
2441     followParentWindowLayoutNodeIds_.emplace_back(nodeId);
2442     if (followParentWindowLayoutNodeIds_.size() == 1) {
2443         bool freeMultiWindowEnable = IsFreeMultiWindow();
2444         SwitchFollowParentWindowLayout(freeMultiWindowEnable);
2445     }
2446 }
2447 
RemoveFollowParentWindowLayoutNode(int32_t nodeId)2448 void SubwindowOhos::RemoveFollowParentWindowLayoutNode(int32_t nodeId)
2449 {
2450     followParentWindowLayoutNodeIds_.remove(nodeId);
2451     if (followParentWindowLayoutNodeIds_.empty()) {
2452         bool freeMultiWindowEnable = IsFreeMultiWindow();
2453         SwitchFollowParentWindowLayout(freeMultiWindowEnable);
2454     }
2455 }
2456 } // namespace OHOS::Ace
2457