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