• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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/preview/entrance/ace_container.h"
17 
18 #include <functional>
19 
20 #ifndef ENABLE_ROSEN_BACKEND
21 #include "flutter/lib/ui/ui_dart_state.h"
22 
23 #include "adapter/preview/entrance/dir_asset_provider.h"
24 #include "core/common/flutter/flutter_asset_manager.h"
25 #include "core/common/flutter/flutter_task_executor.h"
26 #else // ENABLE_ROSEN_BACKEND == true
27 #include "adapter/preview/entrance/rs_dir_asset_provider.h"
28 #include "core/common/flutter/flutter_task_executor.h"
29 #include "core/common/rosen/rosen_asset_manager.h"
30 #endif
31 
32 #include "jsapp/rich/external/StageContext.h"
33 #include "native_engine/native_engine.h"
34 #include "previewer/include/window.h"
35 
36 #include "adapter/preview/entrance/ace_application_info.h"
37 #include "adapter/preview/osal/stage_card_parser.h"
38 #include "base/log/ace_trace.h"
39 #include "base/log/event_report.h"
40 #include "base/log/log.h"
41 #include "base/utils/system_properties.h"
42 #include "base/utils/utils.h"
43 #include "bridge/card_frontend/card_frontend.h"
44 #include "bridge/card_frontend/card_frontend_declarative.h"
45 #include "bridge/card_frontend/form_frontend_declarative.h"
46 #include "bridge/common/utils/engine_helper.h"
47 #include "bridge/declarative_frontend/declarative_frontend.h"
48 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
49 #include "bridge/js_frontend/engine/common/js_engine_loader.h"
50 #include "bridge/js_frontend/js_frontend.h"
51 #include "core/common/ace_engine.h"
52 #include "core/common/ace_view.h"
53 #include "core/common/container_scope.h"
54 #include "core/common/platform_bridge.h"
55 #include "core/common/platform_window.h"
56 #include "core/common/text_field_manager.h"
57 #include "core/common/window.h"
58 #include "core/components/theme/app_theme.h"
59 #include "core/components/theme/theme_constants.h"
60 #include "core/components/theme/theme_manager_impl.h"
61 #include "core/components_ng/pattern/text_field/text_field_manager.h"
62 #include "core/components_ng/render/adapter/rosen_window.h"
63 #include "core/pipeline/base/element.h"
64 #include "core/pipeline/pipeline_context.h"
65 #include "core/pipeline_ng/pipeline_context.h"
66 
67 namespace OHOS::Ace::Platform {
68 namespace {
69 const char LANGUAGE_TAG[] = "language";
70 const char COUNTRY_TAG[] = "countryOrRegion";
71 const char DIRECTION_TAG[] = "dir";
72 const char UNICODE_SETTING_TAG[] = "unicodeSetting";
73 const char LOCALE_DIR_LTR[] = "ltr";
74 const char LOCALE_DIR_RTL[] = "rtl";
75 const char LOCALE_KEY[] = "locale";
76 } // namespace
77 
78 std::once_flag AceContainer::onceFlag_;
79 bool AceContainer::isComponentMode_ = false;
AceContainer(int32_t instanceId,FrontendType type,bool useNewPipeline,bool useCurrentEventRunner)80 AceContainer::AceContainer(int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner)
81     : instanceId_(instanceId), messageBridge_(AceType::MakeRefPtr<PlatformBridge>()), type_(type)
82 {
83     LOGI("Using %{public}s pipeline context ...", (useNewPipeline ? "new" : "old"));
84     if (useNewPipeline) {
85         SetUseNewPipeline();
86     }
87     ThemeConstants::InitDeviceType();
88 #ifndef ENABLE_ROSEN_BACKEND
89     auto state = flutter::UIDartState::Current()->GetStateById(instanceId);
90     auto flutterTaskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>(state->GetTaskRunners());
91     if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::ETS_CARD) {
92         flutterTaskExecutor->InitJsThread();
93     }
94 #else
95     auto flutterTaskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
96     flutterTaskExecutor->InitPlatformThread(useCurrentEventRunner);
97     // No need to create JS Thread for DECLARATIVE_JS
98     if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::ETS_CARD) {
99         flutterTaskExecutor->InitJsThread();
100     } else {
101         GetSettings().useUIAsJSThread = true;
102     }
103 #endif
104     taskExecutor_ = flutterTaskExecutor;
105 }
106 
Initialize()107 void AceContainer::Initialize()
108 {
109     ContainerScope scope(instanceId_);
110     if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::ETS_CARD) {
111         InitializeFrontend();
112     }
113 }
114 
Destroy()115 void AceContainer::Destroy()
116 {
117     ContainerScope scope(instanceId_);
118     LOGI("AceContainer::Destroy begin");
119     if (!pipelineContext_) {
120         LOGE("no context find in %{private}d container", instanceId_);
121         return;
122     }
123     if (!taskExecutor_) {
124         LOGE("no taskExecutor find in %{private}d container", instanceId_);
125         return;
126     }
127     auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
128     taskExecutor_->PostTask(
129         [weak]() {
130             auto context = weak.Upgrade();
131             if (context == nullptr) {
132                 LOGE("context is nullptr");
133                 return;
134             }
135             context->Destroy();
136         },
137         TaskExecutor::TaskType::UI);
138 
139     RefPtr<Frontend> frontend;
140     frontend_.Swap(frontend);
141     if (frontend && taskExecutor_) {
142         taskExecutor_->PostTask(
143             [frontend]() {
144                 frontend->UpdateState(Frontend::State::ON_DESTROY);
145                 frontend->Destroy();
146             },
147             TaskExecutor::TaskType::JS);
148     }
149 
150     messageBridge_.Reset();
151     resRegister_.Reset();
152     assetManager_.Reset();
153     pipelineContext_.Reset();
154     aceView_ = nullptr;
155     LOGI("AceContainer::Destroy end");
156 }
157 
DestroyView()158 void AceContainer::DestroyView()
159 {
160     if (aceView_ != nullptr) {
161         delete aceView_;
162         aceView_ = nullptr;
163     }
164 }
165 
InitializeFrontend()166 void AceContainer::InitializeFrontend()
167 {
168     if (type_ == FrontendType::JS) {
169         frontend_ = Frontend::Create();
170         auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
171         auto jsEngine = Framework::JsEngineLoader::Get().CreateJsEngine(GetInstanceId());
172         EngineHelper::AddEngine(instanceId_, jsEngine);
173         jsFrontend->SetJsEngine(jsEngine);
174         jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
175         jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
176     } else if (type_ == FrontendType::DECLARATIVE_JS) {
177         frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
178         auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
179         auto& loader = Framework::JsEngineLoader::GetDeclarative();
180         RefPtr<Framework::JsEngine> jsEngine;
181         if (GetSettings().usingSharedRuntime) {
182             jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
183         } else {
184             jsEngine = loader.CreateJsEngine(instanceId_);
185         }
186         EngineHelper::AddEngine(instanceId_, jsEngine);
187         declarativeFrontend->SetJsEngine(jsEngine);
188         declarativeFrontend->SetPageProfile(pageProfile_);
189     } else if (type_ == FrontendType::JS_CARD) {
190         AceApplicationInfo::GetInstance().SetCardType();
191         frontend_ = AceType::MakeRefPtr<CardFrontend>();
192     } else if (type_ == FrontendType::ETS_CARD) {
193         frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
194         auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
195         auto jsEngine = Framework::JsEngineLoader::GetDeclarative().CreateJsEngine(instanceId_);
196         EngineHelper::AddEngine(instanceId_, jsEngine);
197         cardFrontend->SetJsEngine(jsEngine);
198         cardFrontend->SetPageProfile(pageProfile_);
199         cardFrontend->SetRunningCardId(0);
200         cardFrontend->SetIsFormRender(true);
201         cardFrontend->SetTaskExecutor(taskExecutor_);
202         SetIsFRSCardContainer(true);
203     } else {
204         LOGE("Frontend type not supported");
205         return;
206     }
207     ACE_DCHECK(frontend_);
208     frontend_->DisallowPopLastPage();
209     frontend_->Initialize(type_, taskExecutor_);
210     if (assetManager_) {
211         frontend_->SetAssetManager(assetManager_);
212     }
213 }
214 
RunNativeEngineLoop()215 void AceContainer::RunNativeEngineLoop()
216 {
217     taskExecutor_->PostTask([frontend = frontend_]() { frontend->RunNativeEngineLoop(); }, TaskExecutor::TaskType::JS);
218     // After the JS thread executes frontend ->RunNativeEngineLoop(),
219     // it is thrown back into the Platform thread queue to form a loop.
220     taskExecutor_->PostTask([this]() { RunNativeEngineLoop(); }, TaskExecutor::TaskType::PLATFORM);
221 }
222 
InitializeStageAppConfig(const std::string & assetPath,const std::string & bundleName,const std::string & moduleName,const std::string & compileMode)223 void AceContainer::InitializeStageAppConfig(const std::string& assetPath, const std::string& bundleName,
224     const std::string& moduleName, const std::string& compileMode)
225 {
226     bool isBundle = (compileMode != "esmodule");
227     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
228     CHECK_NULL_VOID(declarativeFrontend);
229     declarativeFrontend->InitializeModuleSearcher(bundleName, moduleName, assetPath, isBundle);
230 
231     auto formFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
232     CHECK_NULL_VOID(formFrontend);
233     formFrontend->SetBundleName(bundleName);
234     formFrontend->SetModuleName(moduleName);
235     formFrontend->SetIsBundle(isBundle);
236 }
237 
SetHspBufferTrackerCallback()238 void AceContainer::SetHspBufferTrackerCallback()
239 {
240     if (GetSettings().usingSharedRuntime) {
241         LOGI("The callback has been set by ability in the light simulator.");
242         return;
243     }
244     auto frontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
245     CHECK_NULL_VOID(frontend);
246     auto weak = WeakPtr(frontend->GetJsEngine());
247     taskExecutor_->PostTask(
248         [weak, instanceId = instanceId_]() {
249             ContainerScope scope(instanceId);
250             auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(weak.Upgrade());
251             CHECK_NULL_VOID(jsEngine);
252             jsEngine->SetHspBufferTrackerCallback(
253                 [](const std::string& inputPath, uint8_t** buff, size_t* buffSize) -> bool {
254                     if (!buff || !buffSize || inputPath.empty()) {
255                         LOGI("The pointer of buff or buffSize is null or inputPath is empty.");
256                         return false;
257                     }
258                     auto data = OHOS::Ide::StageContext::GetInstance().GetModuleBuffer(inputPath);
259                     CHECK_NULL_RETURN(data, false);
260                     *buff = data->data();
261                     *buffSize = data->size();
262                     return true;
263                 });
264         },
265         TaskExecutor::TaskType::JS);
266 }
267 
SetStageCardConfig(const std::string & pageProfile,const std::string & selectUrl)268 void AceContainer::SetStageCardConfig(const std::string& pageProfile, const std::string& selectUrl)
269 {
270     std::string fullPageProfile = pageProfile + ".json";
271     std::string formConfigs;
272     RefPtr<StageCardParser> stageCardParser = AceType::MakeRefPtr<StageCardParser>();
273     if (!Framework::GetAssetContentImpl(assetManager_, fullPageProfile, formConfigs)) {
274         LOGI("Can not load the form config.");
275         return;
276     }
277     const std::string prefix("./js/");
278     stageCardParser->Parse(formConfigs, prefix + selectUrl);
279     auto cardFront = static_cast<CardFrontend*>(RawPtr(frontend_));
280     if (cardFront) {
281         cardFront->SetFormSrc(selectUrl);
282         cardFront->SetCardWindowConfig(stageCardParser->GetWindowConfig());
283     }
284 }
285 
InitializeCallback()286 void AceContainer::InitializeCallback()
287 {
288     ACE_FUNCTION_TRACE();
289 
290     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
291 
292     auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
293     auto&& touchEventCallback = [weak, id = instanceId_](
294                                     const TouchEvent& event, const std::function<void()>& ignoreMark) {
295         ContainerScope scope(id);
296         auto context = weak.Upgrade();
297         if (context == nullptr) {
298             LOGE("context is nullptr");
299             return;
300         }
301         context->GetTaskExecutor()->PostTask(
302             [context, event]() { context->OnTouchEvent(event); }, TaskExecutor::TaskType::UI);
303     };
304     aceView_->RegisterTouchEventCallback(touchEventCallback);
305 
306     auto&& keyEventCallback = [weak, id = instanceId_](const KeyEvent& event) {
307         ContainerScope scope(id);
308         auto context = weak.Upgrade();
309         if (context == nullptr) {
310             LOGE("context is nullptr");
311             return false;
312         }
313         bool result = false;
314         context->GetTaskExecutor()->PostSyncTask(
315             [context, event, &result]() { result = context->OnKeyEvent(event); }, TaskExecutor::TaskType::UI);
316         return result;
317     };
318     aceView_->RegisterKeyEventCallback(keyEventCallback);
319 
320     auto&& mouseEventCallback = [weak, id = instanceId_](
321                                     const MouseEvent& event, const std::function<void()>& ignoreMark) {
322         ContainerScope scope(id);
323         auto context = weak.Upgrade();
324         if (context == nullptr) {
325             LOGE("context is nullptr");
326             return;
327         }
328         context->GetTaskExecutor()->PostTask(
329             [context, event]() { context->OnMouseEvent(event); }, TaskExecutor::TaskType::UI);
330     };
331     aceView_->RegisterMouseEventCallback(mouseEventCallback);
332 
333     auto&& axisEventCallback = [weak, id = instanceId_](
334                                    const AxisEvent& event, const std::function<void()>& ignoreMark) {
335         ContainerScope scope(id);
336         auto context = weak.Upgrade();
337         if (context == nullptr) {
338             LOGE("context is nullptr");
339             return;
340         }
341         context->GetTaskExecutor()->PostTask(
342             [context, event]() { context->OnAxisEvent(event); }, TaskExecutor::TaskType::UI);
343     };
344     aceView_->RegisterAxisEventCallback(axisEventCallback);
345 
346     auto&& rotationEventCallback = [weak, id = instanceId_](const RotationEvent& event) {
347         ContainerScope scope(id);
348         auto context = weak.Upgrade();
349         if (context == nullptr) {
350             LOGE("context is nullptr");
351             return false;
352         }
353         bool result = false;
354         context->GetTaskExecutor()->PostSyncTask(
355             [context, event, &result]() { result = context->OnRotationEvent(event); }, TaskExecutor::TaskType::UI);
356         return result;
357     };
358     aceView_->RegisterRotationEventCallback(rotationEventCallback);
359 
360     auto&& cardViewPositionCallback = [weak, instanceId = instanceId_](int id, float offsetX, float offsetY) {
361         ContainerScope scope(instanceId);
362         auto context = AceType::DynamicCast<PipelineContext>(weak.Upgrade());
363         if (context == nullptr) {
364             LOGE("context is nullptr");
365             return;
366         }
367         context->GetTaskExecutor()->PostSyncTask(
368             [context, id, offsetX, offsetY]() { context->SetCardViewPosition(id, offsetX, offsetY); },
369             TaskExecutor::TaskType::UI);
370     };
371     aceView_->RegisterCardViewPositionCallback(cardViewPositionCallback);
372 
373     auto&& cardViewParamsCallback = [weak, id = instanceId_](const std::string& key, bool focus) {
374         ContainerScope scope(id);
375         auto context = AceType::DynamicCast<PipelineContext>(weak.Upgrade());
376         if (context == nullptr) {
377             LOGE("context is nullptr");
378             return;
379         }
380         context->GetTaskExecutor()->PostSyncTask(
381             [context, key, focus]() { context->SetCardViewAccessibilityParams(key, focus); },
382             TaskExecutor::TaskType::UI);
383     };
384     aceView_->RegisterCardViewAccessibilityParamsCallback(cardViewParamsCallback);
385 
386     auto&& viewChangeCallback = [weak, id = instanceId_](int32_t width, int32_t height, WindowSizeChangeReason type,
387                                     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
388         ContainerScope scope(id);
389         auto context = weak.Upgrade();
390         if (context == nullptr) {
391             LOGE("context is nullptr");
392             return;
393         }
394         ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
395         context->GetTaskExecutor()->PostTask(
396             [context, width, height, type, rsTransaction]() {
397                 context->OnSurfaceChanged(width, height, type, rsTransaction);
398             },
399             TaskExecutor::TaskType::UI);
400     };
401     aceView_->RegisterViewChangeCallback(viewChangeCallback);
402 
403     auto&& densityChangeCallback = [weak, id = instanceId_](double density) {
404         ContainerScope scope(id);
405         auto context = weak.Upgrade();
406         if (context == nullptr) {
407             LOGE("context is nullptr");
408             return;
409         }
410         ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
411         context->GetTaskExecutor()->PostTask(
412             [context, density]() { context->OnSurfaceDensityChanged(density); }, TaskExecutor::TaskType::UI);
413     };
414     aceView_->RegisterDensityChangeCallback(densityChangeCallback);
415 
416     auto&& systemBarHeightChangeCallback = [weak, id = instanceId_](double statusBar, double navigationBar) {
417         ContainerScope scope(id);
418         auto context = weak.Upgrade();
419         if (context == nullptr) {
420             LOGE("context is nullptr");
421             return;
422         }
423         ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
424         context->GetTaskExecutor()->PostTask(
425             [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
426             TaskExecutor::TaskType::UI);
427     };
428     aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
429 
430     auto&& surfaceDestroyCallback = [weak, id = instanceId_]() {
431         ContainerScope scope(id);
432         auto context = weak.Upgrade();
433         if (context == nullptr) {
434             LOGE("context is nullptr");
435             return;
436         }
437         context->GetTaskExecutor()->PostTask(
438             [context]() { context->OnSurfaceDestroyed(); }, TaskExecutor::TaskType::UI);
439     };
440     aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
441 
442     auto&& idleCallback = [weak, id = instanceId_](int64_t deadline) {
443         ContainerScope scope(id);
444         auto context = weak.Upgrade();
445         if (context == nullptr) {
446             LOGE("context is nullptr");
447             return;
448         }
449         context->GetTaskExecutor()->PostTask(
450             [context, deadline]() { context->OnIdle(deadline); }, TaskExecutor::TaskType::UI);
451     };
452     aceView_->RegisterIdleCallback(idleCallback);
453 }
454 
CreateContainer(int32_t instanceId,FrontendType type,bool useNewPipeline,bool useCurrentEventRunner)455 void AceContainer::CreateContainer(
456     int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner)
457 {
458     auto aceContainer = AceType::MakeRefPtr<AceContainer>(instanceId, type, useNewPipeline, useCurrentEventRunner);
459     AceEngine::Get().AddContainer(aceContainer->GetInstanceId(), aceContainer);
460     aceContainer->Initialize();
461     ContainerScope scope(instanceId);
462     auto front = aceContainer->GetFrontend();
463     if (front) {
464         front->UpdateState(Frontend::State::ON_CREATE);
465         front->SetJsMessageDispatcher(aceContainer);
466     }
467     auto platMessageBridge = aceContainer->GetMessageBridge();
468     platMessageBridge->SetJsMessageDispatcher(aceContainer);
469 }
470 
DestroyContainer(int32_t instanceId)471 void AceContainer::DestroyContainer(int32_t instanceId)
472 {
473     auto container = AceEngine::Get().GetContainer(instanceId);
474     if (!container) {
475         LOGE("no AceContainer with id %{private}d in AceEngine", instanceId);
476         return;
477     }
478     container->Destroy();
479     // unregister watchdog before stop thread to avoid UI_BLOCK report
480     AceEngine::Get().UnRegisterFromWatchDog(instanceId);
481     auto taskExecutor = container->GetTaskExecutor();
482     if (taskExecutor) {
483         taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI);
484         taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS);
485     }
486     container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
487     EngineHelper::RemoveEngine(instanceId);
488     AceEngine::Get().RemoveContainer(instanceId);
489 }
490 
RunPage(int32_t instanceId,int32_t pageId,const std::string & url,const std::string & params)491 bool AceContainer::RunPage(int32_t instanceId, int32_t pageId, const std::string& url, const std::string& params)
492 {
493     ACE_FUNCTION_TRACE();
494     auto container = AceEngine::Get().GetContainer(instanceId);
495     if (!container) {
496         return false;
497     }
498 
499     ContainerScope scope(instanceId);
500     auto front = container->GetFrontend();
501     if (front) {
502         auto type = front->GetType();
503         if ((type == FrontendType::JS) || (type == FrontendType::DECLARATIVE_JS) || (type == FrontendType::JS_CARD) ||
504             (type == FrontendType::ETS_CARD)) {
505             front->RunPage(pageId, url, params);
506             return true;
507         } else {
508             LOGE("Frontend type not supported when runpage");
509             EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
510             return false;
511         }
512     }
513     return false;
514 }
515 
UpdateResourceConfiguration(const std::string & jsonStr)516 void AceContainer::UpdateResourceConfiguration(const std::string& jsonStr)
517 {
518     ContainerScope scope(instanceId_);
519     uint32_t updateFlags = 0;
520     auto resConfig = resourceInfo_.GetResourceConfiguration();
521     if (!resConfig.UpdateFromJsonString(jsonStr, updateFlags) || !updateFlags) {
522         return;
523     }
524     resourceInfo_.SetResourceConfiguration(resConfig);
525     if (ResourceConfiguration::TestFlag(updateFlags, ResourceConfiguration::COLOR_MODE_UPDATED_FLAG)) {
526         SystemProperties::SetColorMode(resConfig.GetColorMode());
527         if (frontend_) {
528             frontend_->SetColorMode(resConfig.GetColorMode());
529         }
530     }
531     if (!pipelineContext_) {
532         return;
533     }
534     auto themeManager = pipelineContext_->GetThemeManager();
535     if (!themeManager) {
536         return;
537     }
538     themeManager->UpdateConfig(resConfig);
539     taskExecutor_->PostTask(
540         [weakThemeManager = WeakPtr<ThemeManager>(themeManager), colorScheme = colorScheme_, config = resConfig,
541             weakContext = WeakPtr<PipelineBase>(pipelineContext_)]() {
542             auto themeManager = weakThemeManager.Upgrade();
543             auto context = weakContext.Upgrade();
544             if (!themeManager || !context) {
545                 return;
546             }
547             themeManager->LoadResourceThemes();
548             themeManager->ParseSystemTheme();
549             themeManager->SetColorScheme(colorScheme);
550             context->RefreshRootBgColor();
551             context->UpdateFontWeightScale();
552             context->SetFontScale(config.GetFontRatio());
553         },
554         TaskExecutor::TaskType::UI);
555     if (frontend_) {
556         frontend_->RebuildAllPages();
557     }
558 }
559 
NativeOnConfigurationUpdated(int32_t instanceId)560 void AceContainer::NativeOnConfigurationUpdated(int32_t instanceId)
561 {
562     auto container = GetContainerInstance(instanceId);
563     if (!container) {
564         return;
565     }
566     ContainerScope scope(instanceId);
567     auto front = container->GetFrontend();
568     if (!front) {
569         return;
570     }
571 
572     std::unique_ptr<JsonValue> value = JsonUtil::Create(true);
573     value->Put("fontScale", container->GetResourceConfiguration().GetFontRatio());
574     value->Put("colorMode", SystemProperties::GetColorMode() == ColorMode::LIGHT ? "light" : "dark");
575     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(front);
576     if (declarativeFrontend) {
577         container->UpdateResourceConfiguration(value->ToString());
578         declarativeFrontend->OnConfigurationUpdated(value->ToString());
579         return;
580     }
581 
582     std::unique_ptr<JsonValue> localeValue = JsonUtil::Create(false);
583     localeValue->Put(LANGUAGE_TAG, AceApplicationInfo::GetInstance().GetLanguage().c_str());
584     localeValue->Put(COUNTRY_TAG, AceApplicationInfo::GetInstance().GetCountryOrRegion().c_str());
585     localeValue->Put(
586         DIRECTION_TAG, AceApplicationInfo::GetInstance().IsRightToLeft() ? LOCALE_DIR_RTL : LOCALE_DIR_LTR);
587     localeValue->Put(UNICODE_SETTING_TAG, AceApplicationInfo::GetInstance().GetUnicodeSetting().c_str());
588     value->Put(LOCALE_KEY, localeValue);
589     front->OnConfigurationUpdated(value->ToString());
590 }
591 
Dispatch(const std::string & group,std::vector<uint8_t> && data,int32_t id,bool replyToComponent) const592 void AceContainer::Dispatch(
593     const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
594 {}
595 
FetchResponse(const ResponseData responseData,const int32_t callbackId) const596 void AceContainer::FetchResponse(const ResponseData responseData, const int32_t callbackId) const
597 {
598     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(0));
599     if (!container) {
600         LOGE("FetchResponse container is null!");
601         return;
602     }
603     ContainerScope scope(instanceId_);
604     auto front = container->GetFrontend();
605     auto type = container->GetType();
606     if (type == FrontendType::JS) {
607         auto jsFrontend = AceType::DynamicCast<JsFrontend>(front);
608         if (jsFrontend) {
609             jsFrontend->TransferJsResponseDataPreview(callbackId, ACTION_SUCCESS, responseData);
610         }
611     } else if (type == FrontendType::DECLARATIVE_JS) {
612         auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(front);
613         if (declarativeFrontend) {
614             declarativeFrontend->TransferJsResponseDataPreview(callbackId, ACTION_SUCCESS, responseData);
615         }
616     } else {
617         LOGE("Frontend type not supported");
618         return;
619     }
620 }
621 
CallCurlFunction(const RequestData requestData,const int32_t callbackId) const622 void AceContainer::CallCurlFunction(const RequestData requestData, const int32_t callbackId) const
623 {
624     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(ACE_INSTANCE_ID));
625     if (!container) {
626         LOGE("CallCurlFunction container is null!");
627         return;
628     }
629 
630     ContainerScope scope(instanceId_);
631     taskExecutor_->PostTask(
632         [container, requestData, callbackId]() mutable {
633             ResponseData responseData;
634             if (FetchManager::GetInstance().Fetch(requestData, callbackId, responseData)) {
635                 container->FetchResponse(responseData, callbackId);
636             }
637         },
638         TaskExecutor::TaskType::BACKGROUND);
639 }
640 
DispatchPluginError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const641 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
642 {
643     auto front = GetFrontend();
644     if (!front) {
645         LOGE("the front jni is nullptr");
646         return;
647     }
648 
649     ContainerScope scope(instanceId_);
650     taskExecutor_->PostTask(
651         [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
652             front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
653         },
654         TaskExecutor::TaskType::BACKGROUND);
655 }
656 
AddRouterChangeCallback(int32_t instanceId,const OnRouterChangeCallback & onRouterChangeCallback)657 void AceContainer::AddRouterChangeCallback(int32_t instanceId, const OnRouterChangeCallback& onRouterChangeCallback)
658 {
659     auto container = GetContainerInstance(instanceId);
660     if (!container) {
661         return;
662     }
663     ContainerScope scope(instanceId);
664     if (!container->pipelineContext_) {
665         LOGE("container pipelineContext not init");
666         return;
667     }
668     container->pipelineContext_->AddRouterChangeCallback(onRouterChangeCallback);
669 }
670 
671 #ifndef ENABLE_ROSEN_BACKEND
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::vector<std::string> & paths)672 void AceContainer::AddAssetPath(
673     int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths)
674 {
675     auto container = GetContainerInstance(instanceId);
676     CHECK_NULL_VOID(container);
677 
678     if (!container->assetManager_) {
679         RefPtr<FlutterAssetManager> flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
680         container->assetManager_ = flutterAssetManager;
681         if (container->frontend_) {
682             container->frontend_->SetAssetManager(flutterAssetManager);
683         }
684     }
685 
686     for (const auto& path : paths) {
687         LOGD("Current path is: %{private}s", path.c_str());
688         auto dirAssetProvider = AceType::MakeRefPtr<DirAssetProvider>(
689             path, std::make_unique<flutter::DirectoryAssetBundle>(
690                       fml::OpenDirectory(path.c_str(), false, fml::FilePermission::kRead)));
691         container->assetManager_->PushBack(std::move(dirAssetProvider));
692     }
693 }
694 #else
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::vector<std::string> & paths)695 void AceContainer::AddAssetPath(
696     int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths)
697 {
698     auto container = GetContainerInstance(instanceId);
699     CHECK_NULL_VOID(container);
700 
701     if (!container->assetManager_) {
702         RefPtr<RSAssetManager> rsAssetManager = Referenced::MakeRefPtr<RSAssetManager>();
703         container->assetManager_ = rsAssetManager;
704         if (container->frontend_) {
705             container->frontend_->SetAssetManager(rsAssetManager);
706         }
707     }
708 
709     for (const auto& path : paths) {
710         LOGD("Current path is: %{private}s", path.c_str());
711         auto dirAssetProvider = AceType::MakeRefPtr<RSDirAssetProvider>(path);
712         container->assetManager_->PushBack(std::move(dirAssetProvider));
713     }
714 }
715 #endif
716 
SetResourcesPathAndThemeStyle(int32_t instanceId,const std::string & systemResourcesPath,const std::string & appResourcesPath,const int32_t & themeId,const ColorMode & colorMode)717 void AceContainer::SetResourcesPathAndThemeStyle(int32_t instanceId, const std::string& systemResourcesPath,
718     const std::string& appResourcesPath, const int32_t& themeId, const ColorMode& colorMode)
719 {
720     auto container = GetContainerInstance(instanceId);
721     if (!container) {
722         return;
723     }
724     ContainerScope scope(instanceId);
725     auto resConfig = container->resourceInfo_.GetResourceConfiguration();
726     resConfig.SetColorMode(static_cast<OHOS::Ace::ColorMode>(colorMode));
727     container->resourceInfo_.SetResourceConfiguration(resConfig);
728     container->resourceInfo_.SetPackagePath(appResourcesPath);
729     container->resourceInfo_.SetSystemPackagePath(systemResourcesPath);
730     container->resourceInfo_.SetThemeId(themeId);
731 }
732 
UpdateDeviceConfig(const DeviceConfig & deviceConfig)733 void AceContainer::UpdateDeviceConfig(const DeviceConfig& deviceConfig)
734 {
735     ContainerScope scope(instanceId_);
736     SystemProperties::InitDeviceType(deviceConfig.deviceType);
737     SystemProperties::SetDeviceOrientation(deviceConfig.orientation == DeviceOrientation::PORTRAIT ? 0 : 1);
738     SystemProperties::SetResolution(deviceConfig.density);
739     SystemProperties::SetColorMode(deviceConfig.colorMode);
740     auto resConfig = resourceInfo_.GetResourceConfiguration();
741     if (resConfig.GetDeviceType() == deviceConfig.deviceType &&
742         resConfig.GetOrientation() == deviceConfig.orientation && resConfig.GetDensity() == deviceConfig.density &&
743         resConfig.GetColorMode() == deviceConfig.colorMode && resConfig.GetFontRatio() == deviceConfig.fontRatio) {
744         return;
745     } else {
746         resConfig.SetDeviceType(deviceConfig.deviceType);
747         resConfig.SetOrientation(deviceConfig.orientation);
748         resConfig.SetDensity(deviceConfig.density);
749         resConfig.SetColorMode(deviceConfig.colorMode);
750         resConfig.SetFontRatio(deviceConfig.fontRatio);
751         if (frontend_) {
752             frontend_->SetColorMode(deviceConfig.colorMode);
753         }
754     }
755     resourceInfo_.SetResourceConfiguration(resConfig);
756     if (!pipelineContext_) {
757         return;
758     }
759     auto themeManager = pipelineContext_->GetThemeManager();
760     if (!themeManager) {
761         return;
762     }
763     themeManager->UpdateConfig(resConfig);
764     taskExecutor_->PostTask(
765         [weakThemeManager = WeakPtr<ThemeManager>(themeManager), colorScheme = colorScheme_,
766             weakContext = WeakPtr<PipelineBase>(pipelineContext_)]() {
767             auto themeManager = weakThemeManager.Upgrade();
768             auto context = weakContext.Upgrade();
769             if (!themeManager || !context) {
770                 return;
771             }
772             themeManager->LoadResourceThemes();
773             themeManager->ParseSystemTheme();
774             themeManager->SetColorScheme(colorScheme);
775             context->RefreshRootBgColor();
776         },
777         TaskExecutor::TaskType::UI);
778 }
779 
780 #ifndef ENABLE_ROSEN_BACKEND
SetView(AceViewPreview * view,double density,int32_t width,int32_t height)781 void AceContainer::SetView(AceViewPreview* view, double density, int32_t width, int32_t height)
782 {
783     if (view == nullptr) {
784         return;
785     }
786 
787     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
788     if (!container) {
789         return;
790     }
791     auto platformWindow = PlatformWindow::Create(view);
792     if (!platformWindow) {
793         LOGE("Create PlatformWindow failed!");
794         return;
795     }
796 
797     std::unique_ptr<Window> window = std::make_unique<Window>(std::move(platformWindow));
798     container->AttachView(std::move(window), view, density, width, height);
799 }
800 #else
SetView(AceViewPreview * view,sptr<Rosen::Window> rsWindow,double density,int32_t width,int32_t height,UIEnvCallback callback)801 void AceContainer::SetView(AceViewPreview* view, sptr<Rosen::Window> rsWindow, double density, int32_t width,
802     int32_t height, UIEnvCallback callback)
803 {
804     CHECK_NULL_VOID(view);
805     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
806     CHECK_NULL_VOID(container);
807     auto taskExecutor = container->GetTaskExecutor();
808     CHECK_NULL_VOID(taskExecutor);
809     auto window = std::make_unique<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
810     container->AttachView(std::move(window), view, density, width, height, callback);
811 }
812 #endif
813 
814 #ifndef ENABLE_ROSEN_BACKEND
AttachView(std::unique_ptr<Window> window,AceViewPreview * view,double density,int32_t width,int32_t height)815 void AceContainer::AttachView(
816     std::unique_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height)
817 {
818     ContainerScope scope(instanceId_);
819     aceView_ = view;
820     auto instanceId = aceView_->GetInstanceId();
821 
822     auto state = flutter::UIDartState::Current()->GetStateById(instanceId);
823     ACE_DCHECK(state != nullptr);
824     auto flutterTaskExecutor = AceType::DynamicCast<FlutterTaskExecutor>(taskExecutor_);
825     flutterTaskExecutor->InitOtherThreads(state->GetTaskRunners());
826     if (type_ == FrontendType::DECLARATIVE_JS) {
827         // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
828         flutterTaskExecutor->InitJsThread(false);
829         InitializeFrontend();
830         auto front = GetFrontend();
831         if (front) {
832             front->UpdateState(Frontend::State::ON_CREATE);
833             front->SetJsMessageDispatcher(AceType::Claim(this));
834         }
835     }
836     resRegister_ = aceView_->GetPlatformResRegister();
837     auto pipelineContext = AceType::MakeRefPtr<PipelineContext>(
838         std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
839     pipelineContext->SetRootSize(density, width, height);
840     pipelineContext->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
841     pipelineContext->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
842     pipelineContext->SetMessageBridge(messageBridge_);
843     pipelineContext->SetWindowModal(windowModal_);
844     pipelineContext->SetDrawDelegate(aceView_->GetDrawDelegate());
845     pipelineContext->SetIsJsCard(type_ == FrontendType::JS_CARD);
846     pipelineContext_ = pipelineContext;
847     InitializeCallback();
848 
849     ThemeConstants::InitDeviceType();
850     // Only init global resource here, construct theme in UI thread
851     auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
852     if (themeManager) {
853         pipelineContext_->SetThemeManager(themeManager);
854         // Init resource, load theme map.
855         themeManager->InitResource(resourceInfo_);
856         themeManager->LoadSystemTheme(resourceInfo_.GetThemeId());
857         taskExecutor_->PostTask(
858             [themeManager, assetManager = assetManager_, colorScheme = colorScheme_, aceView = aceView_]() {
859                 themeManager->ParseSystemTheme();
860                 themeManager->SetColorScheme(colorScheme);
861                 themeManager->LoadCustomTheme(assetManager);
862                 // get background color from theme
863                 aceView->SetBackgroundColor(themeManager->GetBackgroundColor());
864             },
865             TaskExecutor::TaskType::UI);
866     }
867 
868     auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
869     taskExecutor_->PostTask(
870         [weak]() {
871             auto context = weak.Upgrade();
872             if (context == nullptr) {
873                 LOGE("context is nullptr");
874                 return;
875             }
876             context->SetupRootElement();
877         },
878         TaskExecutor::TaskType::UI);
879     aceView_->Launch();
880 
881     frontend_->AttachPipelineContext(pipelineContext_);
882     auto cardFronted = AceType::DynamicCast<CardFrontend>(frontend_);
883     if (cardFronted) {
884         cardFronted->SetDensity(static_cast<double>(density));
885         taskExecutor_->PostTask(
886             [weak, width, height]() {
887                 auto context = weak.Upgrade();
888                 if (context == nullptr) {
889                     LOGE("context is nullptr");
890                     return;
891                 }
892                 context->OnSurfaceChanged(width, height);
893             },
894             TaskExecutor::TaskType::UI);
895     }
896 
897     AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
898 }
899 #else
AttachView(std::unique_ptr<Window> window,AceViewPreview * view,double density,int32_t width,int32_t height,UIEnvCallback callback)900 void AceContainer::AttachView(std::unique_ptr<Window> window, AceViewPreview* view, double density, int32_t width,
901     int32_t height, UIEnvCallback callback)
902 {
903     ContainerScope scope(instanceId_);
904     aceView_ = view;
905     auto instanceId = aceView_->GetInstanceId();
906 
907     auto flutterTaskExecutor = AceType::DynamicCast<FlutterTaskExecutor>(taskExecutor_);
908     CHECK_NULL_VOID(flutterTaskExecutor);
909     flutterTaskExecutor->InitOtherThreads(aceView_->GetThreadModel());
910     if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::ETS_CARD) {
911         // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
912         flutterTaskExecutor->InitJsThread(false);
913         InitializeFrontend();
914         SetHspBufferTrackerCallback();
915         auto front = AceType::DynamicCast<DeclarativeFrontend>(GetFrontend());
916         if (front) {
917             front->UpdateState(Frontend::State::ON_CREATE);
918             front->SetJsMessageDispatcher(AceType::Claim(this));
919             auto weak = WeakPtr(front->GetJsEngine());
920             taskExecutor_->PostTask(
921                 [weak, containerSdkPath = containerSdkPath_]() {
922                     auto jsEngine = weak.Upgrade();
923                     CHECK_NULL_VOID(jsEngine);
924                     auto* nativeEngine = jsEngine->GetNativeEngine();
925                     CHECK_NULL_VOID(nativeEngine);
926                     auto* moduleManager = nativeEngine->GetModuleManager();
927                     CHECK_NULL_VOID(moduleManager);
928                     moduleManager->SetPreviewSearchPath(containerSdkPath);
929                 },
930                 TaskExecutor::TaskType::JS);
931         }
932     }
933     resRegister_ = aceView_->GetPlatformResRegister();
934     if (useNewPipeline_) {
935         LOGI("New pipeline version creating...");
936         pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
937             std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
938         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
939     } else {
940         pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
941             std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
942         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
943     }
944     pipelineContext_->SetRootSize(density, width, height);
945     pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
946     pipelineContext_->SetMessageBridge(messageBridge_);
947     pipelineContext_->SetWindowModal(windowModal_);
948     pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
949     pipelineContext_->SetIsJsCard(type_ == FrontendType::JS_CARD);
950     if (installationFree_ && !isComponentMode_) {
951         LOGD("installationFree:%{public}d, labelId:%{public}d", installationFree_, labelId_);
952         pipelineContext_->SetInstallationFree(installationFree_);
953         pipelineContext_->SetAppLabelId(labelId_);
954     }
955     pipelineContext_->OnShow();
956     InitializeCallback();
957 
958     auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
959     if (cardFrontend) {
960         pipelineContext_->SetIsFormRender(true);
961         cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
962     }
963 
964     ThemeConstants::InitDeviceType();
965     // Only init global resource here, construct theme in UI thread
966     auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
967     if (themeManager) {
968         pipelineContext_->SetThemeManager(themeManager);
969         // Init resource, load theme map.
970         themeManager->InitResource(resourceInfo_);
971         themeManager->LoadSystemTheme(resourceInfo_.GetThemeId());
972         taskExecutor_->PostTask(
973             [themeManager, assetManager = assetManager_, colorScheme = colorScheme_, aceView = aceView_]() {
974                 themeManager->ParseSystemTheme();
975                 themeManager->SetColorScheme(colorScheme);
976                 themeManager->LoadCustomTheme(assetManager);
977                 // get background color from theme
978                 aceView->SetBackgroundColor(themeManager->GetBackgroundColor());
979             },
980             TaskExecutor::TaskType::UI);
981     }
982     if (!useNewPipeline_) {
983         taskExecutor_->PostTask(
984             [context = pipelineContext_, callback]() {
985                 CHECK_NULL_VOID(callback);
986                 callback(AceType::DynamicCast<PipelineContext>(context));
987             },
988             TaskExecutor::TaskType::UI);
989     }
990 
991     auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
992     taskExecutor_->PostTask(
993         [weak]() {
994             auto context = weak.Upgrade();
995             if (context == nullptr) {
996                 LOGE("context is nullptr");
997                 return;
998             }
999             context->SetupRootElement();
1000         },
1001         TaskExecutor::TaskType::UI);
1002     aceView_->Launch();
1003 
1004     frontend_->AttachPipelineContext(pipelineContext_);
1005     auto cardFronted = AceType::DynamicCast<CardFrontend>(frontend_);
1006     if (cardFronted) {
1007         cardFronted->SetDensity(static_cast<double>(density));
1008         taskExecutor_->PostTask(
1009             [weak, width, height]() {
1010                 auto context = weak.Upgrade();
1011                 if (context == nullptr) {
1012                     LOGE("context is nullptr");
1013                     return;
1014                 }
1015                 context->OnSurfaceChanged(width, height);
1016             },
1017             TaskExecutor::TaskType::UI);
1018     }
1019 
1020     AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
1021 }
1022 #endif
1023 
GetContainerInstance(int32_t instanceId)1024 RefPtr<AceContainer> AceContainer::GetContainerInstance(int32_t instanceId)
1025 {
1026     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1027     return container;
1028 }
1029 
GetContentInfo(int32_t instanceId)1030 std::string AceContainer::GetContentInfo(int32_t instanceId)
1031 {
1032     auto container = AceEngine::Get().GetContainer(instanceId);
1033     CHECK_NULL_RETURN_NOLOG(container, "");
1034     ContainerScope scope(instanceId);
1035     auto front = container->GetFrontend();
1036     CHECK_NULL_RETURN_NOLOG(front, "");
1037     return front->GetContentInfo();
1038 }
1039 
LoadDocument(const std::string & url,const std::string & componentName)1040 void AceContainer::LoadDocument(const std::string& url, const std::string& componentName)
1041 {
1042     ContainerScope scope(instanceId_);
1043     if (type_ != FrontendType::DECLARATIVE_JS) {
1044         LOGE("component preview not supported");
1045         return;
1046     }
1047     auto frontend = AceType::DynamicCast<OHOS::Ace::DeclarativeFrontend>(frontend_);
1048     if (!frontend) {
1049         LOGE("frontend is null, AceContainer::LoadDocument failed");
1050         return;
1051     }
1052     auto jsEngine = frontend->GetJsEngine();
1053     if (!jsEngine) {
1054         LOGE("jsEngine is null, AceContainer::LoadDocument failed");
1055         return;
1056     }
1057     taskExecutor_->PostTask(
1058         [front = frontend, componentName, url, jsEngine]() {
1059             front->SetPagePath(url);
1060             jsEngine->ReplaceJSContent(url, componentName);
1061         },
1062         TaskExecutor::TaskType::JS);
1063 }
1064 } // namespace OHOS::Ace::Platform
1065