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