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