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