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