• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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