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