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 40namespace OHOS::Ace::Platform { 41DialogContainer::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 51void 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 70void 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 88void 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 106void 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 120void 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 134void 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 151void 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 164void 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 178void 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 190void 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 204void 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 219RefPtr<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 227void 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 253void 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 DestroyToastSubwindow(instanceId_); 281 resRegister_.Reset(); 282 assetManager_.Reset(); 283} 284 285void DialogContainer::DestroyView() 286{ 287 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer DestroyView begin"); 288 ContainerScope scope(instanceId_); 289 std::lock_guard<std::mutex> lock(viewMutex_); 290 aceView_ = nullptr; 291} 292 293void DialogContainer::SetView( 294 const RefPtr<AceView>& view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window>& rsWindow) 295{ 296 CHECK_NULL_VOID(view); 297 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(view->GetInstanceId())); 298 CHECK_NULL_VOID(container); 299#ifdef ENABLE_ROSEN_BACKEND 300 auto taskExecutor = container->GetTaskExecutor(); 301 CHECK_NULL_VOID(taskExecutor); 302 303 auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId()); 304#else 305 auto platformWindow = PlatformWindow::Create(view); 306 CHECK_NULL_VOID(platformWindow); 307 auto window = std::make_shared<Window>(std::move(platformWindow)); 308#endif 309 container->AttachView(std::move(window), view, density, width, height, rsWindow->GetWindowId()); 310} 311 312void DialogContainer::SetViewNew( 313 const RefPtr<AceView>& view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window>& rsWindow) 314{ 315#ifdef ENABLE_ROSEN_BACKEND 316 CHECK_NULL_VOID(view); 317 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(view->GetInstanceId())); 318 CHECK_NULL_VOID(container); 319 auto taskExecutor = container->GetTaskExecutor(); 320 CHECK_NULL_VOID(taskExecutor); 321 322 auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId()); 323 container->AttachView(std::move(window), view, density, width, height, rsWindow->GetWindowId()); 324#endif 325} 326 327void DialogContainer::AttachView(std::shared_ptr<Window> window, const RefPtr<AceView>& view, double density, 328 int32_t width, int32_t height, uint32_t windowId) 329{ 330 aceView_ = view; 331 auto instanceId = aceView_->GetInstanceId(); 332 auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_); 333 auto aceView = AceType::DynamicCast<AceViewOhos>(aceView_); 334 ACE_DCHECK(aceView != nullptr); 335 taskExecutorImpl->InitOtherThreads(aceView->GetThreadModelImpl()); 336 ContainerScope scope(instanceId); 337 // For DECLARATIVE_JS frontend display UI in JS thread temporarily. 338 taskExecutorImpl->InitJsThread(false); 339 InitializeFrontend(); 340 SetUseNewPipeline(); 341 342 InitPipelineContext(std::move(window), instanceId, density, width, height, windowId); 343 InitializeCallback(); 344 CheckAndSetFontFamily(); 345 346 taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); }, 347 TaskExecutor::TaskType::UI, "ArkUIDialogFrameReportInit"); 348 ThemeConstants::InitDeviceType(); 349 // Load custom style at UI thread before frontend attach, to make sure style can be loaded before building dom tree. 350 RefPtr<ThemeManagerImpl> themeManager = nullptr; 351 if (SystemProperties::GetResourceDecoupling()) { 352 auto resAdapter = ResourceAdapter::CreateV2(); 353 themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resAdapter); 354 } else { 355 themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(); 356 } 357 if (themeManager) { 358 pipelineContext_->SetThemeManager(themeManager); 359 // Init resource 360 themeManager->InitResource(resourceInfo_); 361 taskExecutor_->PostTask( 362 [themeManager, assetManager = assetManager_, colorScheme = colorScheme_] { 363 ACE_SCOPED_TRACE("OHOS::LoadThemes()"); 364 TAG_LOGI(AceLogTag::ACE_DIALOG, "UIContent load theme"); 365 themeManager->SetColorScheme(colorScheme); 366 themeManager->LoadCustomTheme(assetManager); 367 themeManager->LoadResourceThemes(); 368 }, 369 TaskExecutor::TaskType::UI, "ArkUIDialogLoadTheme"); 370 } 371 aceView_->Launch(); 372 // Only MainWindow instance will be registered to watch dog. 373 frontend_->AttachPipelineContext(pipelineContext_); 374#if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED) 375 pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) { 376 auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task)); 377 Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask); 378 }); 379#endif 380} 381 382void DialogContainer::InitPipelineContext(std::shared_ptr<Window> window, int32_t instanceId, double density, 383 int32_t width, int32_t height, uint32_t windowId) 384{ 385#ifdef NG_BUILD 386 TAG_LOGI(AceLogTag::ACE_DIALOG, "New pipeline version creating..."); 387 pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>( 388 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId); 389#else 390 if (useNewPipeline_) { 391 TAG_LOGI(AceLogTag::ACE_DIALOG, "New pipeline version creating..."); 392 pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>( 393 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId); 394 } else { 395 pipelineContext_ = AceType::MakeRefPtr<PipelineContext>( 396 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId); 397 } 398#endif 399 pipelineContext_->SetRootSize(density, width, height); 400 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>()); 401 pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft()); 402 pipelineContext_->SetWindowId(windowId); 403 pipelineContext_->SetWindowModal(windowModal_); 404 pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate()); 405 pipelineContext_->SetIsSubPipeline(true); 406} 407 408void DialogContainer::InitializeFrontend() 409{ 410 frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>(); 411 CHECK_NULL_VOID(frontend_); 412 frontend_->Initialize(type_, taskExecutor_); 413 auto front = GetFrontend(); 414 CHECK_NULL_VOID(front); 415 front->UpdateState(Frontend::State::ON_CREATE); 416 front->SetJsMessageDispatcher(AceType::Claim(this)); 417 front->SetAssetManager(assetManager_); 418} 419 420void DialogContainer::DumpHeapSnapshot(bool isPrivate) 421{ 422 taskExecutor_->PostTask( 423 [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] { 424 auto sp = frontend.Upgrade(); 425 CHECK_NULL_VOID(sp); 426 sp->DumpHeapSnapshot(isPrivate); 427 }, 428 TaskExecutor::TaskType::JS, "ArkUIDialogDumpHeapSnapshot"); 429} 430void DialogContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window>& uiWindow) 431{ 432 CHECK_NULL_VOID(uiWindow); 433 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 434 CHECK_NULL_VOID(container); 435 container->SetUIWindowInner(uiWindow); 436} 437 438sptr<OHOS::Rosen::Window> DialogContainer::GetUIWindow(int32_t instanceId) 439{ 440 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 441 CHECK_NULL_RETURN(container, nullptr); 442 return container->GetUIWindowInner(); 443} 444 445void DialogContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow) 446{ 447 uiWindow_ = std::move(uiWindow); 448} 449 450sptr<OHOS::Rosen::Window> DialogContainer::GetUIWindowInner() const 451{ 452 return uiWindow_; 453} 454 455void DialogContainer::ShowToast(int32_t instanceId, const std::string& message, int32_t duration, 456 const std::string& bottom, std::function<void(int32_t)>&& callback) 457{ 458 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 459 CHECK_NULL_VOID(container); 460 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend()); 461 CHECK_NULL_VOID(frontend); 462 auto delegate = frontend->GetDelegate(); 463 CHECK_NULL_VOID(delegate); 464 delegate->SetToastStopListenerCallback([instanceId = instanceId]() { 465 if (ContainerScope::CurrentId() >= 0) { 466 DialogContainer::HideWindow(instanceId); 467 } 468 }); 469 auto toastInfo = NG::ToastInfo { .message = message, 470 .duration = duration, 471 .bottom = bottom, 472 .showMode = NG::ToastShowMode::DEFAULT, 473 .alignment = -1, 474 .offset = std::nullopt }; 475 delegate->ShowToast(toastInfo, std::move(callback)); 476} 477 478void DialogContainer::CloseToast(int32_t instanceId, int32_t toastId, std::function<void(int32_t)>&& callback) 479{ 480 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 481 CHECK_NULL_VOID(container); 482 483 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend()); 484 CHECK_NULL_VOID(frontend); 485 486 auto delegate = frontend->GetDelegate(); 487 CHECK_NULL_VOID(delegate); 488 delegate->SetToastStopListenerCallback([instanceId = instanceId]() { 489 if (ContainerScope::CurrentId() >= 0) { 490 DialogContainer::HideWindow(instanceId); 491 } 492 }); 493 494 delegate->CloseToast(toastId, std::move(callback)); 495} 496 497void DialogContainer::ShowDialog(int32_t instanceId, const std::string& title, const std::string& message, 498 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback, 499 const std::set<std::string>& callbacks) 500{ 501 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog 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( 509 title, message, buttons, autoCancel, std::move(callback), callbacks, [instanceId = instanceId](bool isShow) { 510 TAG_LOGI( 511 AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog HideWindow instanceId = %{public}d", instanceId); 512 if (!isShow) { 513 DialogContainer::HideWindow(instanceId); 514 } 515 }); 516} 517 518void DialogContainer::ShowDialog(int32_t instanceId, const PromptDialogAttr& dialogAttr, 519 const std::vector<ButtonInfo>& buttons, std::function<void(int32_t, int32_t)>&& callback, 520 const std::set<std::string>& callbacks) 521{ 522 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog with attr begin"); 523 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 524 CHECK_NULL_VOID(container); 525 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend()); 526 CHECK_NULL_VOID(frontend); 527 auto delegate = frontend->GetDelegate(); 528 CHECK_NULL_VOID(delegate); 529 delegate->ShowDialog(dialogAttr, buttons, std::move(callback), callbacks, [instanceId = instanceId](bool isShow) { 530 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowDialog HideWindow instanceId = %{public}d", instanceId); 531 if (!isShow) { 532 DialogContainer::HideWindow(instanceId); 533 } 534 }); 535} 536 537void DialogContainer::ShowActionMenu(int32_t instanceId, const std::string& title, 538 const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback) 539{ 540 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 541 CHECK_NULL_VOID(container); 542 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(container->GetFrontend()); 543 CHECK_NULL_VOID(frontend); 544 auto delegate = frontend->GetDelegate(); 545 CHECK_NULL_VOID(delegate); 546 delegate->ShowActionMenu(title, button, std::move(callback), [instanceId = instanceId](bool isShow) { 547 if (!isShow) { 548 DialogContainer::HideWindow(instanceId); 549 } 550 }); 551} 552 553bool DialogContainer::ShowToastDialogWindow( 554 int32_t instanceId, int32_t posX, int32_t posY, int32_t width, int32_t height, bool isToast) 555{ 556 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow begin"); 557 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 558 CHECK_NULL_RETURN(container, false); 559 auto window = container->GetUIWindowInner(); 560 CHECK_NULL_RETURN(window, false); 561 window->SetTransparent(true); 562 if (isToast) { 563 window->SetTouchable(false); 564 } 565 window->SetNeedDefaultAnimation(false); 566 OHOS::Rosen::WMError ret = window->MoveTo(posX, posY); 567 if (ret != OHOS::Rosen::WMError::WM_OK) { 568 TAG_LOGW(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow MoveTo window failed code: %{public}d", 569 static_cast<int32_t>(ret)); 570 return false; 571 } 572 ret = window->Resize(width, height); 573 if (ret != OHOS::Rosen::WMError::WM_OK) { 574 TAG_LOGW(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow Resize window failed code: %{public}d", 575 static_cast<int32_t>(ret)); 576 return false; 577 } 578 ret = window->Show(); 579 if (ret != OHOS::Rosen::WMError::WM_OK) { 580 TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer ShowToastDialogWindow Show window failed code: %{public}d", 581 static_cast<int32_t>(ret)); 582 return false; 583 } 584 return true; 585} 586 587bool DialogContainer::HideWindow(int32_t instanceId) 588{ 589 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer HideWindow begin"); 590 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 591 CHECK_NULL_RETURN(container, false); 592 auto window = container->GetUIWindowInner(); 593 CHECK_NULL_RETURN(window, false); 594 OHOS::Rosen::WMError ret = window->Hide(); 595 if (ret != OHOS::Rosen::WMError::WM_OK) { 596 TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer HideWindow Failed to hide the window."); 597 return false; 598 } 599 sptr<OHOS::Rosen::Window> uiWindow = nullptr; 600 DialogContainer::SetUIWindow(instanceId, uiWindow); 601 return true; 602} 603 604bool DialogContainer::CloseWindow(int32_t instanceId) 605{ 606 TAG_LOGI(AceLogTag::ACE_DIALOG, "DialogContainer CloseWindow begin"); 607 auto container = AceType::DynamicCast<DialogContainer>(AceEngine::Get().GetContainer(instanceId)); 608 CHECK_NULL_RETURN(container, false); 609 auto window = container->GetUIWindowInner(); 610 CHECK_NULL_RETURN(window, false); 611 OHOS::Rosen::WMError ret = window->Close(); 612 if (ret != OHOS::Rosen::WMError::WM_OK) { 613 TAG_LOGE(AceLogTag::ACE_DIALOG, "DialogContainer CloseWindow Failed to close the window."); 614 return false; 615 } 616 sptr<OHOS::Rosen::Window> uiWindow = nullptr; 617 DialogContainer::SetUIWindow(instanceId, uiWindow); 618 return true; 619} 620 621bool DialogContainer::OnBackPressed(int32_t instanceId) 622{ 623 return DialogContainer::CloseWindow(instanceId); 624} 625 626void DialogContainer::SetFontScaleAndWeightScale(int32_t instanceId) 627{ 628 float fontScale = SystemProperties::GetFontScale(); 629 float fontWeightScale = SystemProperties::GetFontWeightScale(); 630 Container::SetFontScale(instanceId, fontScale); 631 Container::SetFontWeightScale(instanceId, fontWeightScale); 632} 633 634void DialogContainer::UpdateConfiguration(const ParsedConfig& parsedConfig) 635{ 636 if (!parsedConfig.IsValid()) { 637 LOGW("DialogContainer::OnConfigurationUpdated param is empty"); 638 return; 639 } 640 641 CHECK_NULL_VOID(pipelineContext_); 642 auto themeManager = pipelineContext_->GetThemeManager(); 643 CHECK_NULL_VOID(themeManager); 644 auto resConfig = GetResourceConfiguration(); 645 if (!parsedConfig.colorMode.empty()) { 646 if (parsedConfig.colorMode == "dark") { 647 SystemProperties::SetColorMode(ColorMode::DARK); 648 resConfig.SetColorMode(ColorMode::DARK); 649 } else { 650 SystemProperties::SetColorMode(ColorMode::LIGHT); 651 resConfig.SetColorMode(ColorMode::LIGHT); 652 } 653 } 654 655 SetResourceConfiguration(resConfig); 656 themeManager->UpdateConfig(resConfig); 657 themeManager->LoadResourceThemes(); 658 // change color mode and theme to clear image cache 659 pipelineContext_->ClearImageCache(); 660} 661 662void DialogContainer::CheckAndSetFontFamily() 663{ 664 CHECK_NULL_VOID(pipelineContext_); 665 auto fontManager = pipelineContext_->GetFontManager(); 666 CHECK_NULL_VOID(fontManager); 667 if (fontManager->IsUseAppCustomFont()) { 668 return; 669 } 670 std::string familyName = ""; 671 std::string path = "/data/themes/a/app"; 672 if (!IsFontFileExistInPath(path)) { 673 path = "/data/themes/b/app"; 674 if (!IsFontFileExistInPath(path)) { 675 return; 676 } 677 } 678 path = path.append("/fonts/"); 679 familyName = GetFontFamilyName(path); 680 if (familyName.empty()) { 681 return; 682 } 683 path = path.append(familyName); 684 fontManager->SetFontFamily(familyName.c_str(), path.c_str()); 685} 686} // namespace OHOS::Ace::Platform 687