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