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 "window.h"
19
20 #include "adapter/ohos/entrance/ace_application_info.h"
21 #include "core/components/root/root_element.h"
22 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
23 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
24 #endif
25
26 #include "dm/display_manager.h"
27 #include "interfaces/inner_api/ace/viewport_config.h"
28
29 #include "adapter/ohos/entrance/ace_container.h"
30 #include "adapter/ohos/entrance/dialog_container.h"
31 #include "adapter/ohos/entrance/flutter_ace_view.h"
32 #include "adapter/ohos/entrance/utils.h"
33 #include "base/log/frame_report.h"
34 #include "base/utils/system_properties.h"
35 #include "base/utils/utils.h"
36 #include "core/common/connect_server_manager.h"
37 #include "core/common/container_scope.h"
38 #include "core/common/flutter/flutter_task_executor.h"
39 #include "core/common/frontend.h"
40 #include "core/common/hdc_register.h"
41 #include "core/common/text_field_manager.h"
42 #include "core/components/bubble/bubble_component.h"
43 #include "core/components/popup/popup_component.h"
44 #include "core/components_ng/render/adapter/rosen_window.h"
45 #include "frameworks/bridge/common/utils/engine_helper.h"
46 #include "frameworks/bridge/declarative_frontend/declarative_frontend.h"
47
48 namespace OHOS::Ace {
49
50 int32_t SubwindowOhos::id_ = 0;
51 static std::atomic<int32_t> gToastDialogId = 0;
CreateSubwindow(int32_t instanceId)52 RefPtr<Subwindow> Subwindow::CreateSubwindow(int32_t instanceId)
53 {
54 LOGI("Create Subwindow, parent container id is %{public}d", instanceId);
55 return AceType::MakeRefPtr<SubwindowOhos>(instanceId);
56 }
57
SubwindowOhos(int32_t instanceId)58 SubwindowOhos::SubwindowOhos(int32_t instanceId) : windowId_(id_), parentContainerId_(instanceId)
59 {
60 SetSubwindowId(windowId_);
61 id_++;
62 }
63
InitContainer()64 void SubwindowOhos::InitContainer()
65 {
66 LOGI("Subwindow start initialize container");
67 auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
68 CHECK_NULL_VOID(parentContainer);
69 if (!window_) {
70 LOGI("Window is null, need create a new window");
71 OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
72 auto parentWindowName = parentContainer->GetWindowName();
73 auto parentWindowId = parentContainer->GetWindowId();
74 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
75 sptr<OHOS::Rosen::Window> parentWindow = OHOS::Rosen::Window::Find(parentWindowName);
76 CHECK_NULL_VOID_NOLOG(parentWindow);
77 auto windowType = parentWindow->GetType();
78 if (windowType == Rosen::WindowType::WINDOW_TYPE_DESKTOP) {
79 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_FLOAT);
80 } else if (windowType >= Rosen::WindowType::SYSTEM_WINDOW_BASE) {
81 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW);
82 windowOption->SetParentId(parentWindowId);
83 } else {
84 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
85 windowOption->SetParentId(parentWindowId);
86 }
87 windowOption->SetWindowRect({ 0, 0, defaultDisplay->GetWidth(), defaultDisplay->GetHeight() });
88 windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
89 window_ = OHOS::Rosen::Window::Create(
90 "ARK_APP_SUBWINDOW_" + parentWindowName + std::to_string(windowId_), windowOption);
91 CHECK_NULL_VOID(window_);
92 }
93 std::string url = "";
94 auto subSurface = window_->GetSurfaceNode();
95 CHECK_NULL_VOID(subSurface);
96 subSurface->SetShadowElevation(0.0f);
97 window_->SetUIContent(url, nullptr, nullptr, false);
98 childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(window_->GetWindowId());
99 SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
100
101 auto container = Platform::AceContainer::GetContainer(childContainerId_);
102 CHECK_NULL_VOID(container);
103
104 container->SetParentId(parentContainerId_);
105 container->GetSettings().SetUsingSharedRuntime(true);
106 container->SetSharedRuntime(parentContainer->GetSharedRuntime());
107 container->Initialize();
108 container->SetAssetManager(parentContainer->GetAssetManager());
109 container->SetResourceConfiguration(parentContainer->GetResourceConfiguration());
110 container->SetPackagePathStr(parentContainer->GetPackagePathStr());
111 container->SetHapPath(parentContainer->GetHapPath());
112 container->SetIsSubContainer(true);
113 container->InitializeSubContainer(parentContainerId_);
114 ViewportConfig config;
115 // create ace_view
116 auto flutterAceView =
117 Platform::FlutterAceView::CreateView(childContainerId_, false, container->GetSettings().usePlatformAsUIThread);
118 Platform::FlutterAceView::SurfaceCreated(flutterAceView, window_);
119
120 int32_t width = static_cast<int32_t>(window_->GetRequestRect().width_);
121 int32_t height = static_cast<int32_t>(window_->GetRequestRect().height_);
122 auto parentPipeline = parentContainer->GetPipelineContext();
123 CHECK_NULL_VOID(parentPipeline);
124 auto density = parentPipeline->GetDensity();
125 LOGI("UIContent Initialize: width: %{public}d, height: %{public}d, density: %{public}lf", width, height, density);
126
127 Ace::Platform::UIEnvCallback callback = nullptr;
128 // set view
129 Platform::AceContainer::SetView(flutterAceView, density, width, height, window_, callback);
130 Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, config.Orientation());
131
132 #ifdef ENABLE_ROSEN_BACKEND
133 if (SystemProperties::GetRosenBackendEnabled()) {
134 rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
135 if (rsUiDirector != nullptr) {
136 rsUiDirector->SetRSSurfaceNode(window_->GetSurfaceNode());
137 auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
138 if (context != nullptr) {
139 LOGI("Init RSUIDirector");
140 context->SetRSUIDirector(rsUiDirector);
141 }
142 rsUiDirector->Init();
143 LOGI("UIContent Init Rosen Backend");
144 }
145 }
146 #endif
147 if (container->IsCurrentUseNewPipeline()) {
148 auto subPipelineContextNG = AceType::DynamicCast<NG::PipelineContext>(
149 Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
150 CHECK_NULL_VOID(subPipelineContextNG);
151 subPipelineContextNG->SetParentPipeline(parentContainer->GetPipelineContext());
152 subPipelineContextNG->SetupSubRootElement();
153 return;
154 }
155 auto subPipelineContext =
156 DynamicCast<PipelineContext>(Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext());
157 CHECK_NULL_VOID(subPipelineContext);
158 subPipelineContext->SetParentPipeline(parentContainer->GetPipelineContext());
159 subPipelineContext->SetupSubRootElement();
160 }
161
ResizeWindow()162 void SubwindowOhos::ResizeWindow()
163 {
164 LOGI("SubwindowOhos::ResizeWindow");
165 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
166 CHECK_NULL_VOID(defaultDisplay);
167 window_->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
168 }
169
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)170 void SubwindowOhos::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
171 {
172 ShowWindow();
173 auto stack = GetStack();
174 CHECK_NULL_VOID(stack);
175 auto popup = AceType::DynamicCast<TweenComponent>(newComponent);
176 CHECK_NULL_VOID(popup);
177 stack->PopPopup(popup->GetId());
178 stack->PushComponent(newComponent, disableTouchEvent);
179 auto bubble = AceType::DynamicCast<BubbleComponent>(popup->GetChild());
180 if (bubble) {
181 bubble->SetWeakStack(WeakClaim(RawPtr(stack)));
182 }
183 }
184
CancelPopup(const std::string & id)185 bool SubwindowOhos::CancelPopup(const std::string& id)
186 {
187 auto stack = GetStack();
188 CHECK_NULL_RETURN_NOLOG(stack, false);
189 stack->PopPopup(id);
190 auto context = stack->GetContext().Upgrade();
191 CHECK_NULL_RETURN_NOLOG(context, false);
192 context->FlushPipelineImmediately();
193 HideWindow();
194 return true;
195 }
196
ShowPopupNG(int32_t targetId,const NG::PopupInfo & popupInfo)197 void SubwindowOhos::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo)
198 {
199 popupTargetId_ = targetId;
200 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
201 CHECK_NULL_VOID(aceContainer);
202 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
203 CHECK_NULL_VOID(context);
204 auto overlayManager = context->GetOverlayManager();
205 CHECK_NULL_VOID(overlayManager);
206 ShowWindow();
207 overlayManager->UpdatePopupNode(targetId, popupInfo);
208 }
209
HidePopupNG(int32_t targetId)210 void SubwindowOhos::HidePopupNG(int32_t targetId)
211 {
212 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
213 CHECK_NULL_VOID(aceContainer);
214 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
215 CHECK_NULL_VOID(context);
216 auto overlayManager = context->GetOverlayManager();
217 CHECK_NULL_VOID(overlayManager);
218 auto popupInfo = overlayManager->GetPopupInfo(targetId);
219 popupInfo.popupId = -1;
220 popupInfo.markNeedUpdate = true;
221 overlayManager->HidePopup(targetId, popupInfo);
222 context->FlushPipelineImmediately();
223 HideWindow();
224 }
225
HidePopupNG()226 void SubwindowOhos::HidePopupNG()
227 {
228 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
229 CHECK_NULL_VOID(aceContainer);
230 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
231 CHECK_NULL_VOID(context);
232 auto overlayManager = context->GetOverlayManager();
233 CHECK_NULL_VOID(overlayManager);
234 auto popupInfo = overlayManager->GetPopupInfo(popupTargetId_);
235 popupInfo.popupId = -1;
236 popupInfo.markNeedUpdate = true;
237 overlayManager->HidePopup(popupTargetId_, popupInfo);
238 context->FlushPipelineImmediately();
239 HideWindow();
240 }
241
ShowWindow()242 void SubwindowOhos::ShowWindow()
243 {
244 LOGI("Show the subwindow");
245 CHECK_NULL_VOID(window_);
246
247 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
248 CHECK_NULL_VOID(defaultDisplay);
249 window_->Resize(defaultDisplay->GetWidth(), defaultDisplay->GetHeight());
250
251 OHOS::Rosen::WMError ret = window_->Show();
252
253 if (ret != OHOS::Rosen::WMError::WM_OK) {
254 LOGE("Show window failed with errCode: %{public}d", static_cast<int32_t>(ret));
255 return;
256 }
257 window_->RequestFocus();
258 LOGI("Show the subwindow successfully.");
259 isShowed_ = true;
260 SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
261 }
262
HideWindow()263 void SubwindowOhos::HideWindow()
264 {
265 LOGI("Hide the subwindow");
266 CHECK_NULL_VOID(window_);
267
268 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
269 CHECK_NULL_VOID(aceContainer);
270
271 if (Container::IsCurrentUseNewPipeline()) {
272 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
273 CHECK_NULL_VOID(context);
274 auto rootNode = context->GetRootElement();
275 CHECK_NULL_VOID(rootNode);
276 auto focusHub = rootNode->GetFocusHub();
277 CHECK_NULL_VOID(focusHub);
278 focusHub->SetIsDefaultHasFocused(false);
279 } else {
280 auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
281 CHECK_NULL_VOID(context);
282 auto rootNode = context->GetRootElement();
283 CHECK_NULL_VOID(rootNode);
284 rootNode->SetIsDefaultHasFocused(false);
285 }
286
287 if (window_->IsFocused()) {
288 auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
289 CHECK_NULL_VOID(parentContainer);
290 auto parentWindowName = parentContainer->GetWindowName();
291 sptr<OHOS::Rosen::Window> parentWindow = OHOS::Rosen::Window::Find(parentWindowName);
292 CHECK_NULL_VOID(parentWindow);
293 parentWindow->RequestFocus();
294 }
295
296 OHOS::Rosen::WMError ret = window_->Hide();
297
298 if (ret != OHOS::Rosen::WMError::WM_OK) {
299 LOGE("Hide window failed with errCode: %{public}d", static_cast<int32_t>(ret));
300 return;
301 }
302 isShowed_ = false;
303 LOGI("Hide the subwindow successfully.");
304 }
305
AddMenu(const RefPtr<Component> & newComponent)306 void SubwindowOhos::AddMenu(const RefPtr<Component>& newComponent)
307 {
308 LOGI("Subwindow push new component start.");
309 auto stack = GetStack();
310 CHECK_NULL_VOID(stack);
311 // Push the component
312 stack->PopMenu();
313 stack->PushComponent(newComponent);
314 popup_ = AceType::DynamicCast<SelectPopupComponent>(newComponent);
315 if (!popup_) {
316 LOGE("Add menu failed, this is not a popup component.");
317 }
318 LOGI("Subwindow push new component end.");
319 }
320
ClearMenu()321 void SubwindowOhos::ClearMenu()
322 {
323 LOGI("Subwindow Clear menu start.");
324 auto stack = GetStack();
325 CHECK_NULL_VOID(stack);
326 // Pop the component
327 stack->PopMenu();
328 auto context = stack->GetContext().Upgrade();
329 CHECK_NULL_VOID(context);
330 context->FlushPipelineImmediately();
331 HideWindow();
332 LOGI("Subwindow clear menu end.");
333 }
334
ShowMenuNG(const RefPtr<NG::FrameNode> menuNode,int32_t targetId,const NG::OffsetF & offset)335 void SubwindowOhos::ShowMenuNG(const RefPtr<NG::FrameNode> menuNode, int32_t targetId, const NG::OffsetF& offset)
336 {
337 LOGI("SubwindowOhos::ShowMenuNG");
338 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
339 CHECK_NULL_VOID(aceContainer);
340 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
341 CHECK_NULL_VOID(context);
342 auto overlay = context->GetOverlayManager();
343 CHECK_NULL_VOID(overlay);
344 ShowWindow();
345 overlay->ShowMenuInSubWindow(targetId, offset, menuNode);
346 }
347
HideMenuNG()348 void SubwindowOhos::HideMenuNG()
349 {
350 if (!isShowed_) {
351 return;
352 }
353 isShowed_ = false;
354 LOGI("SubwindowOhos::HideMenuNG");
355 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
356 CHECK_NULL_VOID(aceContainer);
357 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
358 CHECK_NULL_VOID(context);
359 auto overlay = context->GetOverlayManager();
360 CHECK_NULL_VOID(overlay);
361 overlay->HideMenuInSubWindow();
362 }
363
HideMenuNG(int32_t targetId)364 void SubwindowOhos::HideMenuNG(int32_t targetId)
365 {
366 if (!isShowed_) {
367 return;
368 }
369 isShowed_ = false;
370 LOGI("SubwindowOhos::HideMenuNG for target id %{public}d", targetId);
371 targetId_ = targetId;
372 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
373 CHECK_NULL_VOID(aceContainer);
374 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
375 CHECK_NULL_VOID(context);
376 auto overlay = context->GetOverlayManager();
377 CHECK_NULL_VOID(overlay);
378 overlay->HideMenuInSubWindow(targetId_);
379 }
380
ClearMenuNG()381 void SubwindowOhos::ClearMenuNG()
382 {
383 LOGI("SubwindowOhos::ClearMenuNG");
384 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
385 CHECK_NULL_VOID(aceContainer);
386 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
387 CHECK_NULL_VOID(context);
388 auto overlay = context->GetOverlayManager();
389 CHECK_NULL_VOID(overlay);
390 overlay->CleanMenuInSubWindow();
391 context->FlushPipelineImmediately();
392 HideWindow();
393 }
394
ShowMenu(const RefPtr<Component> & newComponent)395 void SubwindowOhos::ShowMenu(const RefPtr<Component>& newComponent)
396 {
397 LOGI("Show the menu");
398 ShowWindow();
399 AddMenu(newComponent);
400 }
401
CloseMenu()402 void SubwindowOhos::CloseMenu()
403 {
404 LOGI("Close the menu");
405 if (!isShowed_) {
406 LOGW("Subwindow is not showed.");
407 return;
408 }
409 if (popup_) {
410 popup_->CloseContextMenu();
411 }
412 }
413
GetStack()414 RefPtr<StackElement> SubwindowOhos::GetStack()
415 {
416 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
417 CHECK_NULL_RETURN(aceContainer, nullptr);
418
419 auto context = DynamicCast<PipelineContext>(aceContainer->GetPipelineContext());
420 CHECK_NULL_RETURN(context, nullptr);
421 return context->GetLastStack();
422 }
423
SetHotAreas(const std::vector<Rect> & rects)424 void SubwindowOhos::SetHotAreas(const std::vector<Rect>& rects)
425 {
426 LOGI("Set hot areas for window.");
427 CHECK_NULL_VOID(window_);
428
429 std::vector<Rosen::Rect> hotAreas;
430 Rosen::Rect rosenRect;
431 for (const auto& rect : rects) {
432 RectConverter(rect, rosenRect);
433 hotAreas.emplace_back(rosenRect);
434 }
435
436 OHOS::Rosen::WMError ret = window_->SetTouchHotAreas(hotAreas);
437 if (ret != OHOS::Rosen::WMError::WM_OK) {
438 LOGE("Set hot areas failed with errCode: %{public}d", static_cast<int32_t>(ret));
439 return;
440 }
441 LOGI("Set hot areas successfully.");
442 }
443
RectConverter(const Rect & rect,Rosen::Rect & rosenRect)444 void SubwindowOhos::RectConverter(const Rect& rect, Rosen::Rect& rosenRect)
445 {
446 rosenRect.posX_ = static_cast<int>(rect.GetOffset().GetX());
447 rosenRect.posY_ = static_cast<int>(rect.GetOffset().GetY());
448 rosenRect.width_ = static_cast<uint32_t>(rect.GetSize().Width());
449 rosenRect.height_ = static_cast<uint32_t>(rect.GetSize().Height());
450 LOGI("Convert rect to rosenRect, x is %{public}d, y is %{public}d, width is %{public}d, height is %{public}d",
451 rosenRect.posX_, rosenRect.posY_, rosenRect.width_, rosenRect.height_);
452 }
453
ShowDialogNG(const DialogProperties & dialogProps,const RefPtr<NG::UINode> & customNode)454 RefPtr<NG::FrameNode> SubwindowOhos::ShowDialogNG(
455 const DialogProperties& dialogProps, const RefPtr<NG::UINode>& customNode)
456 {
457 LOGI("SubwindowOhos::ShowDialogNG");
458 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
459 CHECK_NULL_RETURN(aceContainer, nullptr);
460 auto context = DynamicCast<NG::PipelineContext>(aceContainer->GetPipelineContext());
461 CHECK_NULL_RETURN(context, nullptr);
462 auto overlay = context->GetOverlayManager();
463 CHECK_NULL_RETURN(overlay, nullptr);
464 ShowWindow();
465 ContainerScope scope(childContainerId_);
466 return overlay->ShowDialog(dialogProps, customNode);
467 }
468
HideSubWindowNG()469 void SubwindowOhos::HideSubWindowNG()
470 {
471 LOGI("SubwindowOhos::HideDialogNG");
472 auto container = Container::Current();
473 CHECK_NULL_VOID(container);
474 if (container->IsDialogContainer()) {
475 if (IsToastWindow()) {
476 Platform::DialogContainer::HideWindow(Container::CurrentId());
477 } else {
478 Platform::DialogContainer::CloseWindow(Container::CurrentId());
479 Platform::DialogContainer::DestroyContainer(Container::CurrentId());
480 }
481 } else {
482 HideWindow();
483 }
484 }
485
GetToastDialogWindowProperty(int32_t & width,int32_t & height,int32_t & posX,int32_t & posY,float & density) const486 void SubwindowOhos::GetToastDialogWindowProperty(
487 int32_t& width, int32_t& height, int32_t& posX, int32_t& posY, float& density) const
488 {
489 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
490 if (defaultDisplay) {
491 posX = 0;
492 posY = 0;
493 width = defaultDisplay->GetWidth();
494 height = defaultDisplay->GetHeight();
495 density = defaultDisplay->GetVirtualPixelRatio();
496 }
497 LOGI("Toast posX: %{public}d, posY: %{public}d, width: %{public}d, height: %{public}d, density: %{public}f", posX,
498 posY, width, height, density);
499 }
500
InitToastDialogWindow(int32_t width,int32_t height,int32_t posX,int32_t posY,bool isToast)501 bool SubwindowOhos::InitToastDialogWindow(int32_t width, int32_t height, int32_t posX, int32_t posY, bool isToast)
502 {
503 OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
504 if (isToast) {
505 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_TOAST);
506 } else {
507 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
508 }
509 windowOption->SetWindowRect({ posX, posY, width, height });
510 windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
511 windowOption->SetFocusable(!isToast);
512 int32_t dialogId = gToastDialogId.fetch_add(1, std::memory_order_relaxed);
513 std::string windowName = "ARK_APP_SUBWINDOW_TOAST_DIALOG_" + std::to_string(dialogId);
514 dialogWindow_ = OHOS::Rosen::Window::Create(windowName, windowOption);
515 CHECK_NULL_RETURN(dialogWindow_, false);
516 dialogWindow_->SetLayoutFullScreen(true);
517 LOGI("SubwindowOhos::InitToastDialogWindow end");
518 return true;
519 }
520
InitToastDialogView(int32_t width,int32_t height,float density)521 bool SubwindowOhos::InitToastDialogView(int32_t width, int32_t height, float density)
522 {
523 LOGI("SubwindowOhos::InitToastDialogView begin");
524 dialogWindow_->SetUIContent("", nullptr, nullptr, false);
525 childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(dialogWindow_->GetWindowId());
526 SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
527 ContainerScope scope(childContainerId_);
528
529 auto container = Platform::DialogContainer::GetContainer(childContainerId_);
530 CHECK_NULL_RETURN(container, false);
531 // create ace_view
532 auto* flutterAceView = Platform::FlutterAceView::CreateView(childContainerId_, true, true);
533 Platform::FlutterAceView::SurfaceCreated(flutterAceView, dialogWindow_);
534 // set view
535 Platform::DialogContainer::SetView(flutterAceView, density, width, height, dialogWindow_);
536 Ace::Platform::DialogContainer::SetUIWindow(childContainerId_, dialogWindow_);
537 flutter::ViewportMetrics metrics;
538 metrics.physical_width = width;
539 metrics.physical_height = height;
540 metrics.device_pixel_ratio = density;
541 Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics);
542 Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, 0);
543
544 #ifdef ENABLE_ROSEN_BACKEND
545 if (SystemProperties::GetRosenBackendEnabled()) {
546 rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
547 if (rsUiDirector != nullptr) {
548 rsUiDirector->SetRSSurfaceNode(dialogWindow_->GetSurfaceNode());
549 auto context = DynamicCast<PipelineContext>(container->GetPipelineContext());
550 if (context != nullptr) {
551 LOGI("Init RSUIDirector");
552 context->SetRSUIDirector(rsUiDirector);
553 }
554 rsUiDirector->Init();
555 LOGI("UIContent Init Rosen Backend");
556 }
557 }
558 #endif
559
560 auto pipelineContext = container->GetPipelineContext();
561 CHECK_NULL_RETURN(pipelineContext, false);
562 pipelineContext->SetupRootElement();
563 LOGI("SubwindowOhos::InitToastDialogView end");
564 return true;
565 }
566
CreateEventRunner()567 bool SubwindowOhos::CreateEventRunner()
568 {
569 if (!eventLoop_) {
570 eventLoop_ = AppExecFwk::EventRunner::Create("Subwindow_Toast_Dialog");
571 CHECK_NULL_RETURN_NOLOG(eventLoop_, false);
572 handler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
573 CHECK_NULL_RETURN_NOLOG(handler_, false);
574 }
575 return true;
576 }
577
ShowToastForAbility(const std::string & message,int32_t duration,const std::string & bottom)578 void SubwindowOhos::ShowToastForAbility(const std::string& message, int32_t duration, const std::string& bottom)
579 {
580 LOGI("SubwindowOhos::ShowToastForAbility Show the toast");
581 SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
582
583 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
584 if (!aceContainer) {
585 LOGE("Get container failed, it is null");
586 return;
587 }
588
589 auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
590 auto delegate = engine->GetFrontend();
591 if (!delegate) {
592 LOGE("can not get delegate.");
593 return;
594 }
595 delegate->ShowToast(message, duration, bottom);
596 }
597
ShowToastForService(const std::string & message,int32_t duration,const std::string & bottom)598 void SubwindowOhos::ShowToastForService(const std::string& message, int32_t duration, const std::string& bottom)
599 {
600 LOGI("SubwindowOhos::ShowToastForService begin");
601 bool ret = CreateEventRunner();
602 if (!ret) {
603 return;
604 }
605
606 SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
607 auto showDialogCallback = [message, duration, bottom]() {
608 int32_t posX = 0;
609 int32_t posY = 0;
610 int32_t width = 0;
611 int32_t height = 0;
612 float density = 1.0f;
613 auto subwindowOhos =
614 AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
615 CHECK_NULL_VOID(subwindowOhos);
616 subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
617 auto childContainerId = subwindowOhos->GetChildContainerId();
618 auto window = Platform::DialogContainer::GetUIWindow(childContainerId);
619 auto dialogWindow = subwindowOhos->GetDialogWindow();
620 if (!dialogWindow || !window || !subwindowOhos->IsToastWindow()) {
621 bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY, true);
622 if (!ret) {
623 return;
624 }
625 ret = subwindowOhos->InitToastDialogView(width, height, density);
626 if (!ret) {
627 return;
628 }
629 subwindowOhos->SetIsToastWindow(true);
630 }
631 childContainerId = subwindowOhos->GetChildContainerId();
632 ContainerScope scope(childContainerId);
633 auto container = Platform::DialogContainer::GetContainer(childContainerId);
634 CHECK_NULL_VOID(container);
635 auto flutterAceView = static_cast<Platform::FlutterAceView*>(container->GetView());
636 CHECK_NULL_VOID(flutterAceView);
637 if (flutterAceView->GetWidth() != width || flutterAceView->GetHeight() != height) {
638 flutter::ViewportMetrics metrics;
639 metrics.physical_width = width;
640 metrics.physical_height = height;
641 metrics.device_pixel_ratio = density;
642 Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics);
643 Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, 0);
644 }
645
646 Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height, true);
647 Platform::DialogContainer::ShowToast(childContainerId, message, duration, bottom);
648 };
649 if (!handler_->PostTask(showDialogCallback)) {
650 LOGE("Post sync task error");
651 return;
652 }
653 }
654
ShowToast(const std::string & message,int32_t duration,const std::string & bottom)655 void SubwindowOhos::ShowToast(const std::string& message, int32_t duration, const std::string& bottom)
656 {
657 if (parentContainerId_ >= MIN_PA_SERVICE_ID) {
658 ShowToastForService(message, duration, bottom);
659 } else {
660 ShowToastForAbility(message, duration, bottom);
661 }
662 }
663
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)664 void SubwindowOhos::ShowDialogForAbility(const std::string& title, const std::string& message,
665 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
666 const std::set<std::string>& callbacks)
667 {
668 LOGI("Show the dialog");
669 SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
670
671 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
672 if (!aceContainer) {
673 LOGE("Get container failed, it is null");
674 return;
675 }
676
677 auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
678 auto delegate = engine->GetFrontend();
679 if (!delegate) {
680 LOGE("can not get delegate.");
681 return;
682 }
683 delegate->ShowDialog(title, message, buttons, autoCancel, std::move(callback), callbacks);
684 }
685
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)686 void SubwindowOhos::ShowDialogForService(const std::string& title, const std::string& message,
687 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
688 const std::set<std::string>& callbacks)
689 {
690 LOGI("SubwindowOhos::ShowDialogForService begin");
691 bool ret = CreateEventRunner();
692 if (!ret) {
693 return;
694 }
695
696 SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
697 auto showDialogCallback = [title, message, &buttons, autoCancel, callbackParam = std::move(callback),
698 &callbacks]() {
699 int32_t posX = 0;
700 int32_t posY = 0;
701 int32_t width = 0;
702 int32_t height = 0;
703 float density = 1.0f;
704 auto subwindowOhos =
705 AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
706 CHECK_NULL_VOID(subwindowOhos);
707 subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
708 bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
709 if (!ret) {
710 return;
711 }
712 ret = subwindowOhos->InitToastDialogView(width, height, density);
713 if (!ret) {
714 return;
715 }
716 auto childContainerId = subwindowOhos->GetChildContainerId();
717 ContainerScope scope(childContainerId);
718 Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
719 Platform::DialogContainer::ShowDialog(childContainerId, title, message, buttons, autoCancel,
720 std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)), callbacks);
721 };
722 isToastWindow_ = false;
723 if (!handler_->PostTask(showDialogCallback)) {
724 LOGE("Post sync task error");
725 return;
726 }
727 LOGI("SubwindowOhos::ShowDialogForService end");
728 }
729
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)730 void SubwindowOhos::ShowDialog(const std::string& title, const std::string& message,
731 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
732 const std::set<std::string>& callbacks)
733 {
734 if (parentContainerId_ >= MIN_PA_SERVICE_ID) {
735 ShowDialogForService(title, message, buttons, autoCancel, std::move(callback), callbacks);
736 } else {
737 ShowDialogForAbility(title, message, buttons, autoCancel, std::move(callback), callbacks);
738 }
739 }
740
ShowActionMenuForAbility(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)741 void SubwindowOhos::ShowActionMenuForAbility(
742 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
743 {
744 LOGI("Show the action menu");
745 SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
746
747 auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
748 if (!aceContainer) {
749 LOGE("Get container failed, it is null");
750 return;
751 }
752
753 auto engine = EngineHelper::GetEngine(aceContainer->GetInstanceId());
754 auto delegate = engine->GetFrontend();
755 if (!delegate) {
756 LOGE("can not get delegate.");
757 return;
758 }
759 delegate->ShowActionMenu(title, button, std::move(callback));
760 }
761
ShowActionMenuForService(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)762 void SubwindowOhos::ShowActionMenuForService(
763 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
764 {
765 LOGI("SubwindowOhos::ShowActionMenu begin");
766 bool ret = CreateEventRunner();
767 if (!ret) {
768 return;
769 }
770
771 SubwindowManager::GetInstance()->SetCurrentDialogSubwindow(AceType::Claim(this));
772 auto showDialogCallback = [title, &button, callbackParam = std::move(callback)]() {
773 int32_t posX = 0;
774 int32_t posY = 0;
775 int32_t width = 0;
776 int32_t height = 0;
777 float density = 1.0f;
778 auto subwindowOhos =
779 AceType::DynamicCast<SubwindowOhos>(SubwindowManager::GetInstance()->GetCurrentDialogWindow());
780 CHECK_NULL_VOID(subwindowOhos);
781 subwindowOhos->GetToastDialogWindowProperty(width, height, posX, posY, density);
782 bool ret = subwindowOhos->InitToastDialogWindow(width, height, posX, posY);
783 if (!ret) {
784 return;
785 }
786 ret = subwindowOhos->InitToastDialogView(width, height, density);
787 if (!ret) {
788 return;
789 }
790 auto childContainerId = subwindowOhos->GetChildContainerId();
791 ContainerScope scope(childContainerId);
792 Platform::DialogContainer::ShowToastDialogWindow(childContainerId, posX, posY, width, height);
793 Platform::DialogContainer::ShowActionMenu(childContainerId, title, button,
794 std::move(const_cast<std::function<void(int32_t, int32_t)>&&>(callbackParam)));
795 };
796 isToastWindow_ = false;
797 if (!handler_->PostTask(showDialogCallback)) {
798 LOGE("Post sync task error");
799 return;
800 }
801 LOGI("SubwindowOhos::ShowActionMenu end");
802 }
803
CloseDialog(int32_t instanceId)804 void SubwindowOhos::CloseDialog(int32_t instanceId)
805 {
806 Platform::DialogContainer::CloseWindow(instanceId);
807 }
808
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)809 void SubwindowOhos::ShowActionMenu(
810 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
811 {
812 if (parentContainerId_ >= MIN_PA_SERVICE_ID) {
813 ShowActionMenuForService(title, button, std::move(callback));
814 } else {
815 ShowActionMenuForAbility(title, button, std::move(callback));
816 }
817 }
818 } // namespace OHOS::Ace
819