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