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/dialog_container.h"
17 
18 #include <mutex>
19 
20 #include "adapter/ohos/entrance/ace_application_info.h"
21 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
22 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
23 #endif
24 #include "adapter/ohos/entrance/ace_view_ohos.h"
25 #include "base/log/frame_report.h"
26 #include "base/log/log.h"
27 #include "base/utils/utils.h"
28 #include "core/common/ace_engine.h"
29 #include "core/common/container_scope.h"
30 #include "core/common/task_executor_impl.h"
31 #include "core/common/text_field_manager.h"
32 #include "core/components/theme/theme_constants.h"
33 #include "core/components/theme/theme_manager_impl.h"
34 #include "core/pipeline/pipeline_context.h"
35 #include "core/pipeline_ng/pipeline_context.h"
36 #include "frameworks/base/subwindow/subwindow_manager.h"
37 #include "frameworks/bridge/common/utils/engine_helper.h"
38 #include "frameworks/bridge/declarative_frontend/declarative_frontend.h"
39 
40 namespace OHOS::Ace::Platform {
DialogContainer(int32_t instanceId,FrontendType type)41 DialogContainer::DialogContainer(int32_t instanceId, FrontendType type) : instanceId_(instanceId), type_(type)
42 {
43     auto taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
44     taskExecutorImpl->InitPlatformThread(true);
45     taskExecutor_ = taskExecutorImpl;
46     GetSettings().useUIAsJSThread = true;
47     GetSettings().usePlatformAsUIThread = true;
48     GetSettings().usingSharedRuntime = true;
49 }
50 
InitializeTouchEventCallback()51 void DialogContainer::InitializeTouchEventCallback()
52 {
53     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
54     auto&& touchEventCallback = [context = pipelineContext_, id = instanceId_](
55                                     const TouchEvent& event, const std::function<void()>& markProcess,
56                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
57         ContainerScope scope(id);
58         context->GetTaskExecutor()->PostTask(
59             [context, event, markProcess]() {
60                 context->OnTouchEvent(event);
61                 context->NotifyDispatchTouchEventDismiss(event);
62                 CHECK_NULL_VOID(markProcess);
63                 markProcess();
64             },
65             TaskExecutor::TaskType::UI, "ArkUIDialogTouchEvent");
66     };
67     aceView_->RegisterTouchEventCallback(touchEventCallback);
68 }
69 
InitializeMouseEventCallback()70 void DialogContainer::InitializeMouseEventCallback()
71 {
72     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
73     auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](
74                                     const MouseEvent& event, const std::function<void()>& markProcess,
75                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
76         ContainerScope scope(id);
77         context->GetTaskExecutor()->PostTask(
78             [context, event, markProcess]() {
79                 context->OnMouseEvent(event);
80                 CHECK_NULL_VOID(markProcess);
81                 markProcess();
82             },
83             TaskExecutor::TaskType::UI, "ArkUIDialogMouseEvent");
84     };
85     aceView_->RegisterMouseEventCallback(mouseEventCallback);
86 }
87 
InitializeAxisEventCallback()88 void DialogContainer::InitializeAxisEventCallback()
89 {
90     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
91     auto&& axisEventCallback = [context = pipelineContext_, id = instanceId_](
92                                    const AxisEvent& event, const std::function<void()>& markProcess,
93                                    const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
94         ContainerScope scope(id);
95         context->GetTaskExecutor()->PostTask(
96             [context, event, markProcess]() {
97                 context->OnAxisEvent(event);
98                 CHECK_NULL_VOID(markProcess);
99                 markProcess();
100             },
101             TaskExecutor::TaskType::UI, "ArkUIDialogAxisEvent");
102     };
103     aceView_->RegisterAxisEventCallback(axisEventCallback);
104 }
105 
InitializeKeyEventCallback()106 void DialogContainer::InitializeKeyEventCallback()
107 {
108     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
109     auto&& keyEventCallback = [context = pipelineContext_, id = instanceId_](const KeyEvent& event) {
110         ContainerScope scope(id);
111         bool result = false;
112         context->GetTaskExecutor()->PostSyncTask(
113             [context, event, &result]() { result = context->OnKeyEvent(event); },
114             TaskExecutor::TaskType::UI, "ArkUIDialogKeyEvent");
115         return result;
116     };
117     aceView_->RegisterKeyEventCallback(keyEventCallback);
118 }
119 
InitializeRotationEventCallback()120 void DialogContainer::InitializeRotationEventCallback()
121 {
122     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
123     auto&& rotationEventCallback = [context = pipelineContext_, id = instanceId_](const RotationEvent& event) {
124         ContainerScope scope(id);
125         bool result = false;
126         context->GetTaskExecutor()->PostSyncTask(
127             [context, event, &result]() { result = context->OnRotationEvent(event); },
128             TaskExecutor::TaskType::UI, "ArkUIDialogRotationEvent");
129         return result;
130     };
131     aceView_->RegisterRotationEventCallback(rotationEventCallback);
132 }
133 
InitializeViewChangeCallback()134 void DialogContainer::InitializeViewChangeCallback()
135 {
136     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
137     auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t width, int32_t height,
138                                     WindowSizeChangeReason type,
139                                     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
140         ContainerScope scope(id);
141         ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
142         context->GetTaskExecutor()->PostTask(
143             [context, width, height, type, rsTransaction]() {
144                 context->OnSurfaceChanged(width, height, type, rsTransaction);
145             },
146             TaskExecutor::TaskType::UI, "ArkUIDialogSurfaceChanged");
147     };
148     aceView_->RegisterViewChangeCallback(viewChangeCallback);
149 }
150 
InitializeDensityChangeCallback()151 void DialogContainer::InitializeDensityChangeCallback()
152 {
153     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
154     auto&& densityChangeCallback = [context = pipelineContext_, id = instanceId_](double density) {
155         ContainerScope scope(id);
156         ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
157         context->GetTaskExecutor()->PostTask(
158             [context, density]() { context->OnSurfaceDensityChanged(density); },
159             TaskExecutor::TaskType::UI, "ArkUIDialogSurfaceDensityChanged");
160     };
161     aceView_->RegisterDensityChangeCallback(densityChangeCallback);
162 }
163 
InitializeSystemBarHeightChangeCallback()164 void DialogContainer::InitializeSystemBarHeightChangeCallback()
165 {
166     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
167     auto&& systemBarHeightChangeCallback = [context = pipelineContext_, id = instanceId_](
168                                                double statusBar, double navigationBar) {
169         ContainerScope scope(id);
170         ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
171         context->GetTaskExecutor()->PostTask(
172             [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
173             TaskExecutor::TaskType::UI, "ArkUIDialogSystemBarHeightChanged");
174     };
175     aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
176 }
177 
InitializeSurfaceDestroyCallback()178 void DialogContainer::InitializeSurfaceDestroyCallback()
179 {
180     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
181     auto&& surfaceDestroyCallback = [context = pipelineContext_, id = instanceId_]() {
182         ContainerScope scope(id);
183         context->GetTaskExecutor()->PostTask(
184             [context]() { context->OnSurfaceDestroyed(); },
185             TaskExecutor::TaskType::UI, "ArkUIDialogSurfaceDestroyed");
186     };
187     aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
188 }
189 
InitializeDragEventCallback()190 void DialogContainer::InitializeDragEventCallback()
191 {
192     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
193     auto&& dragEventCallback = [context = pipelineContext_, id = instanceId_](
194                                     const PointerEvent& pointerEvent, const DragEventAction& action,
195                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
196         ContainerScope scope(id);
197         context->GetTaskExecutor()->PostTask(
198             [context, pointerEvent, action, node]() { context->OnDragEvent(pointerEvent, action, node); },
199             TaskExecutor::TaskType::UI, "ArkUIDialogDragEvent");
200     };
201     aceView_->RegisterDragEventCallback(dragEventCallback);
202 }
203 
InitializeCallback()204 void DialogContainer::InitializeCallback()
205 {
206     ACE_FUNCTION_TRACE();
207     InitializeTouchEventCallback();
208     InitializeMouseEventCallback();
209     InitializeAxisEventCallback();
210     InitializeKeyEventCallback();
211     InitializeRotationEventCallback();
212     InitializeViewChangeCallback();
213     InitializeDensityChangeCallback();
214     InitializeSystemBarHeightChangeCallback();
215     InitializeSurfaceDestroyCallback();
216     InitializeDragEventCallback();
217 }
218 
GetContainer(int32_t instanceId)219 RefPtr<DialogContainer> DialogContainer::GetContainer(int32_t instanceId)
220 {
221     auto container = AceEngine::Get().GetContainer(instanceId);
222     CHECK_NULL_RETURN(container, nullptr);
223     auto dialogContainer = AceType::DynamicCast<DialogContainer>(container);
224     return dialogContainer;
225 }
226 
DestroyContainer(int32_t instanceId,const std::function<void ()> & destroyCallback)227 void DialogContainer::DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)
228 {
229     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer DestroyContainer begin %{public}d", instanceId);
230     auto container = AceEngine::Get().GetContainer(instanceId);
231     CHECK_NULL_VOID(container);
232     container->Destroy();
233     auto taskExecutor = container->GetTaskExecutor();
234     CHECK_NULL_VOID(taskExecutor);
235     taskExecutor->PostSyncTask(
236         [] { TAG_LOGI(AceLogTag::ACE_DIALOG,  "Wait UI thread..."); },
237         TaskExecutor::TaskType::UI, "ArkUIDialogWaitLog");
238     taskExecutor->PostSyncTask(
239         [] { TAG_LOGI(AceLogTag::ACE_DIALOG,  "Wait JS thread..."); },
240         TaskExecutor::TaskType::JS, "ArkUIDialogWaitLog");
241     container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
242     taskExecutor->PostTask(
243         [instanceId, destroyCallback] {
244             TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer DestroyContainer Remove on Platform thread...");
245             EngineHelper::RemoveEngine(instanceId);
246             AceEngine::Get().RemoveContainer(instanceId);
247             CHECK_NULL_VOID(destroyCallback);
248             destroyCallback();
249         },
250         TaskExecutor::TaskType::PLATFORM, "ArkUIDialogContainerDestroy");
251 }
252 
Destroy()253 void DialogContainer::Destroy()
254 {
255     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer Destroy begin");
256     ContainerScope scope(instanceId_);
257     if (pipelineContext_ && taskExecutor_) {
258         // 1. Destroy Pipeline on UI thread.
259         RefPtr<PipelineBase>& context = pipelineContext_;
260         if (GetSettings().usePlatformAsUIThread) {
261             context->Destroy();
262         } else {
263             taskExecutor_->PostTask([context]() { context->Destroy(); },
264                 TaskExecutor::TaskType::UI, "ArkUIDialogDestoryPipeline");
265         }
266         // 2. Destroy Frontend on JS thread.
267         RefPtr<Frontend>& frontend = frontend_;
268         if (GetSettings().usePlatformAsUIThread && GetSettings().useUIAsJSThread) {
269             frontend->UpdateState(Frontend::State::ON_DESTROY);
270             frontend->Destroy();
271         } else {
272             taskExecutor_->PostTask(
273                 [frontend]() {
274                     frontend->UpdateState(Frontend::State::ON_DESTROY);
275                     frontend->Destroy();
276                 },
277                 TaskExecutor::TaskType::JS, "ArkUIDialogFrontendDestroy");
278         }
279     }
280     resRegister_.Reset();
281     assetManager_.Reset();
282 }
283 
DestroyView()284 void DialogContainer::DestroyView()
285 {
286     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer DestroyView begin");
287     ContainerScope scope(instanceId_);
288     std::lock_guard<std::mutex> lock(viewMutex_);
289     aceView_ = nullptr;
290 }
291 
SetView(const RefPtr<AceView> & view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> & rsWindow)292 void DialogContainer::SetView(
293     const RefPtr<AceView>& view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window>& rsWindow)
294 {
295     CHECK_NULL_VOID(view);
296     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
297     CHECK_NULL_VOID(container);
298 #ifdef ENABLE_ROSEN_BACKEND
299     auto taskExecutor = container->GetTaskExecutor();
300     CHECK_NULL_VOID(taskExecutor);
301 
302     auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
303 #else
304     auto platformWindow = PlatformWindow::Create(view);
305     CHECK_NULL_VOID(platformWindow);
306     auto window = std::make_shared<Window>(std::move(platformWindow));
307 #endif
308     container->AttachView(std::move(window), view, density, width, height, rsWindow->GetWindowId());
309 }
310 
SetViewNew(const RefPtr<AceView> & view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> & rsWindow)311 void DialogContainer::SetViewNew(
312     const RefPtr<AceView>& view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window>& rsWindow)
313 {
314 #ifdef ENABLE_ROSEN_BACKEND
315     CHECK_NULL_VOID(view);
316     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
317     CHECK_NULL_VOID(container);
318     auto taskExecutor = container->GetTaskExecutor();
319     CHECK_NULL_VOID(taskExecutor);
320 
321     auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
322     container->AttachView(std::move(window), view, density, width, height, rsWindow->GetWindowId());
323 #endif
324 }
325 
AttachView(std::shared_ptr<Window> window,const RefPtr<AceView> & view,double density,int32_t width,int32_t height,uint32_t windowId)326 void DialogContainer::AttachView(std::shared_ptr<Window> window, const RefPtr<AceView>& view, double density,
327     int32_t width, int32_t height, uint32_t windowId)
328 {
329     aceView_ = view;
330     auto instanceId = aceView_->GetInstanceId();
331     auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_);
332     auto aceView = AceType::DynamicCast<AceViewOhos>(aceView_);
333     ACE_DCHECK(aceView != nullptr);
334     taskExecutorImpl->InitOtherThreads(aceView->GetThreadModelImpl());
335     ContainerScope scope(instanceId);
336     // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
337     taskExecutorImpl->InitJsThread(false);
338     InitializeFrontend();
339     SetUseNewPipeline();
340 
341     InitPipelineContext(std::move(window), instanceId, density, width, height, windowId);
342     InitializeCallback();
343 
344     taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); },
345         TaskExecutor::TaskType::UI, "ArkUIDialogFrameReportInit");
346     ThemeConstants::InitDeviceType();
347     // Load custom style at UI thread before frontend attach, to make sure style can be loaded before building dom tree.
348     RefPtr<ThemeManagerImpl> themeManager = nullptr;
349     if (SystemProperties::GetResourceDecoupling()) {
350         auto resAdapter = ResourceAdapter::CreateV2();
351         themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resAdapter);
352     } else {
353         themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
354     }
355     if (themeManager) {
356         pipelineContext_->SetThemeManager(themeManager);
357         // Init resource
358         themeManager->InitResource(resourceInfo_);
359         taskExecutor_->PostTask(
360             [themeManager, assetManager = assetManager_, colorScheme = colorScheme_] {
361                 ACE_SCOPED_TRACE("OHOS::LoadThemes()");
362                 TAG_LOGI(AceLogTag::ACE_DIALOG, "UIContent load theme");
363                 themeManager->SetColorScheme(colorScheme);
364                 themeManager->LoadCustomTheme(assetManager);
365                 themeManager->LoadResourceThemes();
366             },
367             TaskExecutor::TaskType::UI, "ArkUIDialogLoadTheme");
368     }
369     aceView_->Launch();
370     // Only MainWindow instance will be registered to watch dog.
371     frontend_->AttachPipelineContext(pipelineContext_);
372 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
373     pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) {
374         auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task));
375         Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask);
376     });
377 #endif
378 }
379 
InitPipelineContext(std::shared_ptr<Window> window,int32_t instanceId,double density,int32_t width,int32_t height,uint32_t windowId)380 void DialogContainer::InitPipelineContext(std::shared_ptr<Window> window, int32_t instanceId, double density,
381     int32_t width, int32_t height, uint32_t windowId)
382 {
383 #ifdef NG_BUILD
384     TAG_LOGI(AceLogTag::ACE_DIALOG, "New pipeline version creating...");
385     pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
386         std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
387 #else
388     if (useNewPipeline_) {
389         TAG_LOGI(AceLogTag::ACE_DIALOG, "New pipeline version creating...");
390         pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
391             std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
392     } else {
393         pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
394             std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
395     }
396 #endif
397     pipelineContext_->SetRootSize(density, width, height);
398     pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
399     pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
400     pipelineContext_->SetWindowId(windowId);
401     pipelineContext_->SetWindowModal(windowModal_);
402     pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
403     pipelineContext_->SetIsSubPipeline(true);
404 }
405 
InitializeFrontend()406 void DialogContainer::InitializeFrontend()
407 {
408     frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
409     CHECK_NULL_VOID(frontend_);
410     frontend_->Initialize(type_, taskExecutor_);
411     auto front = GetFrontend();
412     CHECK_NULL_VOID(front);
413     front->UpdateState(Frontend::State::ON_CREATE);
414     front->SetJsMessageDispatcher(AceType::Claim(this));
415     front->SetAssetManager(assetManager_);
416 }
417 
DumpHeapSnapshot(bool isPrivate)418 void DialogContainer::DumpHeapSnapshot(bool isPrivate)
419 {
420     taskExecutor_->PostTask(
421         [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] {
422             auto sp = frontend.Upgrade();
423             CHECK_NULL_VOID(sp);
424             sp->DumpHeapSnapshot(isPrivate);
425         },
426         TaskExecutor::TaskType::JS, "ArkUIDialogDumpHeapSnapshot");
427 }
SetUIWindow(int32_t instanceId,sptr<OHOS::Rosen::Window> & uiWindow)428 void DialogContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window>& uiWindow)
429 {
430     CHECK_NULL_VOID(uiWindow);
431     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
432     CHECK_NULL_VOID(container);
433     container->SetUIWindowInner(uiWindow);
434 }
435 
GetUIWindow(int32_t instanceId)436 sptr<OHOS::Rosen::Window> DialogContainer::GetUIWindow(int32_t instanceId)
437 {
438     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
439     CHECK_NULL_RETURN(container, nullptr);
440     return container->GetUIWindowInner();
441 }
442 
SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)443 void DialogContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)
444 {
445     uiWindow_ = std::move(uiWindow);
446 }
447 
GetUIWindowInner() const448 sptr<OHOS::Rosen::Window> DialogContainer::GetUIWindowInner() const
449 {
450     return uiWindow_;
451 }
452 
ShowToast(int32_t instanceId,const std::string & message,int32_t duration,const std::string & bottom)453 void DialogContainer::ShowToast(int32_t instanceId, const std::string& message, int32_t duration,
454     const std::string& bottom)
455 {
456     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
457     CHECK_NULL_VOID(container);
458     auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend());
459     CHECK_NULL_VOID(frontend);
460     auto delegate = frontend->GetDelegate();
461     CHECK_NULL_VOID(delegate);
462     delegate->SetToastStopListenerCallback([instanceId = instanceId]() {
463         if (ContainerScope::CurrentId() >= 0) {
464             DialogContainer::HideWindow(instanceId);
465         }
466     });
467     auto toastInfo = NG::ToastInfo { .message = message,
468         .duration = duration,
469         .bottom = bottom,
470         .showMode = NG::ToastShowMode::DEFAULT,
471         .alignment = -1,
472         .offset = std::nullopt };
473     delegate->ShowToast(toastInfo);
474 }
475 
ShowDialog(int32_t instanceId,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)476 void DialogContainer::ShowDialog(int32_t instanceId, const std::string& title, const std::string& message,
477     const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
478     const std::set<std::string>& callbacks)
479 {
480     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog begin");
481     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
482     CHECK_NULL_VOID(container);
483     auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend());
484     CHECK_NULL_VOID(frontend);
485     auto delegate = frontend->GetDelegate();
486     CHECK_NULL_VOID(delegate);
487     delegate->ShowDialog(
488         title, message, buttons, autoCancel, std::move(callback), callbacks, [instanceId = instanceId](bool isShow) {
489             TAG_LOGI(
490                 AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog HideWindow instanceId = %{public}d", instanceId);
491             if (!isShow) {
492                 DialogContainer::HideWindow(instanceId);
493             }
494         });
495 }
496 
ShowDialog(int32_t instanceId,const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)497 void DialogContainer::ShowDialog(int32_t instanceId, const PromptDialogAttr& dialogAttr,
498     const std::vector<ButtonInfo>& buttons, std::function<void(int32_t, int32_t)>&& callback,
499     const std::set<std::string>& callbacks)
500 {
501     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog with attr begin");
502     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
503     CHECK_NULL_VOID(container);
504     auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend());
505     CHECK_NULL_VOID(frontend);
506     auto delegate = frontend->GetDelegate();
507     CHECK_NULL_VOID(delegate);
508     delegate->ShowDialog(dialogAttr, buttons, std::move(callback), callbacks, [instanceId = instanceId](bool isShow) {
509         TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog HideWindow instanceId = %{public}d", instanceId);
510         if (!isShow) {
511             DialogContainer::HideWindow(instanceId);
512         }
513     });
514 }
515 
ShowActionMenu(int32_t instanceId,const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)516 void DialogContainer::ShowActionMenu(int32_t instanceId, const std::string& title,
517     const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
518 {
519     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
520     CHECK_NULL_VOID(container);
521     auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend());
522     CHECK_NULL_VOID(frontend);
523     auto delegate = frontend->GetDelegate();
524     CHECK_NULL_VOID(delegate);
525     delegate->ShowActionMenu(title, button, std::move(callback), [instanceId = instanceId](bool isShow) {
526         if (!isShow) {
527             DialogContainer::HideWindow(instanceId);
528         }
529     });
530 }
531 
ShowToastDialogWindow(int32_t instanceId,int32_t posX,int32_t posY,int32_t width,int32_t height,bool isToast)532 bool DialogContainer::ShowToastDialogWindow(
533     int32_t instanceId, int32_t posX, int32_t posY, int32_t width, int32_t height, bool isToast)
534 {
535     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow begin");
536     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
537     CHECK_NULL_RETURN(container, false);
538     auto window = container->GetUIWindowInner();
539     CHECK_NULL_RETURN(window, false);
540     window->SetTransparent(true);
541     if (isToast) {
542         window->SetTouchable(false);
543     }
544     window->SetNeedDefaultAnimation(false);
545     OHOS::Rosen::WMError ret = window->MoveTo(posX, posY);
546     if (ret != OHOS::Rosen::WMError::WM_OK) {
547         TAG_LOGW(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow MoveTo window failed code: %{public}d",
548             static_cast<int32_t>(ret));
549         return false;
550     }
551     ret = window->Resize(width, height);
552     if (ret != OHOS::Rosen::WMError::WM_OK) {
553         TAG_LOGW(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow Resize window failed code: %{public}d",
554             static_cast<int32_t>(ret));
555         return false;
556     }
557     ret = window->Show();
558     if (ret != OHOS::Rosen::WMError::WM_OK) {
559         TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow Show window failed code: %{public}d",
560             static_cast<int32_t>(ret));
561         return false;
562     }
563     return true;
564 }
565 
HideWindow(int32_t instanceId)566 bool DialogContainer::HideWindow(int32_t instanceId)
567 {
568     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer HideWindow begin");
569     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
570     CHECK_NULL_RETURN(container, false);
571     auto window = container->GetUIWindowInner();
572     CHECK_NULL_RETURN(window, false);
573     OHOS::Rosen::WMError ret = window->Hide();
574     if (ret != OHOS::Rosen::WMError::WM_OK) {
575         TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer HideWindow Failed to hide the window.");
576         return false;
577     }
578     sptr<OHOS::Rosen::Window> uiWindow = nullptr;
579     DialogContainer::SetUIWindow(instanceId, uiWindow);
580     return true;
581 }
582 
CloseWindow(int32_t instanceId)583 bool DialogContainer::CloseWindow(int32_t instanceId)
584 {
585     TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer CloseWindow begin");
586     auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId));
587     CHECK_NULL_RETURN(container, false);
588     auto window = container->GetUIWindowInner();
589     CHECK_NULL_RETURN(window, false);
590     OHOS::Rosen::WMError ret = window->Close();
591     if (ret != OHOS::Rosen::WMError::WM_OK) {
592         TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer CloseWindow Failed to close the window.");
593         return false;
594     }
595     sptr<OHOS::Rosen::Window> uiWindow = nullptr;
596     DialogContainer::SetUIWindow(instanceId, uiWindow);
597     return true;
598 }
599 
OnBackPressed(int32_t instanceId)600 bool DialogContainer::OnBackPressed(int32_t instanceId)
601 {
602     return DialogContainer::CloseWindow(instanceId);
603 }
604 
SetFontScaleAndWeightScale(int32_t instanceId)605 void DialogContainer::SetFontScaleAndWeightScale(int32_t instanceId)
606 {
607     float fontScale = SystemProperties::GetFontScale();
608     float fontWeightScale = SystemProperties::GetFontWeightScale();
609     Container::SetFontScale(instanceId, fontScale);
610     Container::SetFontWeightScale(instanceId, fontWeightScale);
611 }
612 
UpdateConfiguration(const ParsedConfig & parsedConfig)613 void DialogContainer::UpdateConfiguration(const ParsedConfig& parsedConfig)
614 {
615     if (!parsedConfig.IsValid()) {
616         LOGW("DialogContainer::OnConfigurationUpdated param is empty");
617         return;
618     }
619 
620     CHECK_NULL_VOID(pipelineContext_);
621     auto themeManager = pipelineContext_->GetThemeManager();
622     CHECK_NULL_VOID(themeManager);
623     auto resConfig = GetResourceConfiguration();
624     if (!parsedConfig.colorMode.empty()) {
625         if (parsedConfig.colorMode == "dark") {
626             SystemProperties::SetColorMode(ColorMode::DARK);
627             resConfig.SetColorMode(ColorMode::DARK);
628         } else {
629             SystemProperties::SetColorMode(ColorMode::LIGHT);
630             resConfig.SetColorMode(ColorMode::LIGHT);
631         }
632     }
633 
634     SetResourceConfiguration(resConfig);
635     themeManager->UpdateConfig(resConfig);
636     themeManager->LoadResourceThemes();
637     // change color mode and theme to clear image cache
638     pipelineContext_->ClearImageCache();
639 }
640 } // namespace OHOS::Ace::Platform
641