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