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