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