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 #include "base/log/log.h"
21
22 #ifndef ENABLE_ROSEN_BACKEND
23 #include "flutter/lib/ui/ui_dart_state.h"
24 #include "adapter/ohos/entrance/file_asset_provider_impl.h"
25 #include "core/common/asset_manager_impl.h"
26 #else // ENABLE_ROSEN_BACKEND == true
27 #include "adapter/preview/entrance/rs_dir_asset_provider.h"
28 #include "core/common/rosen/rosen_asset_manager.h"
29 #endif
30
31 #include "native_engine/native_engine.h"
32 #include "previewer/include/window.h"
33
34 #include "adapter/preview/entrance/ace_application_info.h"
35 #include "adapter/preview/entrance/ace_preview_helper.h"
36 #include "adapter/preview/osal/stage_card_parser.h"
37 #include "base/log/ace_trace.h"
38 #include "base/log/event_report.h"
39 #include "base/log/log.h"
40 #include "base/utils/system_properties.h"
41 #include "base/utils/utils.h"
42 #include "bridge/card_frontend/card_frontend.h"
43 #include "bridge/card_frontend/card_frontend_declarative.h"
44 #include "bridge/card_frontend/form_frontend_declarative.h"
45 #include "bridge/common/utils/engine_helper.h"
46 #include "bridge/declarative_frontend/declarative_frontend.h"
47 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.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/resource/resource_manager.h"
56 #include "core/common/task_executor_impl.h"
57 #include "core/common/text_field_manager.h"
58 #include "core/common/window.h"
59 #include "core/components/theme/app_theme.h"
60 #include "core/components/theme/theme_constants.h"
61 #include "core/components/theme/theme_manager_impl.h"
62 #include "core/components_ng/pattern/text_field/text_field_manager.h"
63 #include "core/components_ng/render/adapter/rosen_window.h"
64 #include "core/pipeline/base/element.h"
65 #include "core/pipeline/pipeline_context.h"
66 #include "core/pipeline_ng/pipeline_context.h"
67 #include "frameworks/simulator/ability_simulator/include/ability_context.h"
68
69 namespace OHOS::Ace::Platform {
70 namespace {
71 const char LANGUAGE_TAG[] = "language";
72 const char COUNTRY_TAG[] = "countryOrRegion";
73 const char DIRECTION_TAG[] = "dir";
74 const char UNICODE_SETTING_TAG[] = "unicodeSetting";
75 const char LOCALE_DIR_LTR[] = "ltr";
76 const char LOCALE_DIR_RTL[] = "rtl";
77 const char LOCALE_KEY[] = "locale";
78
ReleaseStorageReference(void * sharedRuntime,NativeReference * storage)79 void ReleaseStorageReference(void* sharedRuntime, NativeReference* storage)
80 {
81 if (sharedRuntime && storage) {
82 auto nativeEngine = reinterpret_cast<NativeEngine*>(sharedRuntime);
83 auto env = reinterpret_cast<napi_env>(nativeEngine);
84 napi_delete_reference(env, reinterpret_cast<napi_ref>(storage));
85 }
86 }
87
EncodeBundleAndModule(const std::string & bundleName,const std::string & moduleName)88 std::string EncodeBundleAndModule(const std::string& bundleName, const std::string& moduleName)
89 {
90 return bundleName + " " + moduleName;
91 }
92
SaveResourceAdapter(const std::string & bundleName,const std::string & moduleName,int32_t instanceId,RefPtr<ResourceAdapter> & resourceAdapter)93 void SaveResourceAdapter(const std::string& bundleName, const std::string& moduleName, int32_t instanceId,
94 RefPtr<ResourceAdapter>& resourceAdapter)
95 {
96 auto defaultBundleName = "";
97 auto defaultModuleName = "";
98 ResourceManager::GetInstance().AddResourceAdapter(
99 defaultBundleName, defaultModuleName, instanceId, resourceAdapter);
100 LOGI("Save default adapter");
101
102 if (!bundleName.empty() && !moduleName.empty()) {
103 LOGI("Save resource adapter bundle: %{public}s, module: %{public}s", bundleName.c_str(), moduleName.c_str());
104 ResourceManager::GetInstance().AddResourceAdapter(bundleName, moduleName, instanceId, resourceAdapter);
105 }
106 }
107 } // namespace
108
109 std::once_flag AceContainer::onceFlag_;
110 bool AceContainer::isComponentMode_ = false;
AceContainer(int32_t instanceId,FrontendType type,bool useNewPipeline,bool useCurrentEventRunner)111 AceContainer::AceContainer(int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner)
112 : instanceId_(instanceId), messageBridge_(AceType::MakeRefPtr<PlatformBridge>()), type_(type)
113 {
114 LOGI("Using %{public}s pipeline context ...", (useNewPipeline ? "new" : "old"));
115 if (useNewPipeline) {
116 SetUseNewPipeline();
117 }
118 ThemeConstants::InitDeviceType();
119 auto taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
120 taskExecutorImpl->InitPlatformThread(useCurrentEventRunner);
121 if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::ETS_CARD) {
122 taskExecutorImpl->InitJsThread();
123 } else {
124 GetSettings().useUIAsJSThread = true;
125 }
126 taskExecutor_ = taskExecutorImpl;
127 }
128
Initialize()129 void AceContainer::Initialize()
130 {
131 ContainerScope scope(instanceId_);
132 if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::ETS_CARD) {
133 InitializeFrontend();
134 }
135 }
136
Destroy()137 void AceContainer::Destroy()
138 {
139 ContainerScope scope(instanceId_);
140 if (!pipelineContext_) {
141 return;
142 }
143 if (!taskExecutor_) {
144 return;
145 }
146 auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
147 taskExecutor_->PostTask(
148 [weak]() {
149 auto context = weak.Upgrade();
150 if (context == nullptr) {
151 return;
152 }
153 context->Destroy();
154 },
155 TaskExecutor::TaskType::UI, "ArkUIPipelineDestroy");
156
157 RefPtr<Frontend> frontend;
158 frontend_.Swap(frontend);
159 if (frontend && taskExecutor_) {
160 taskExecutor_->PostTask(
161 [frontend]() {
162 frontend->UpdateState(Frontend::State::ON_DESTROY);
163 frontend->Destroy();
164 },
165 TaskExecutor::TaskType::JS, "ArkUIFrontendDestroy");
166 }
167
168 messageBridge_.Reset();
169 resRegister_.Reset();
170 assetManager_.Reset();
171 pipelineContext_.Reset();
172 aceView_ = nullptr;
173 }
174
DestroyView()175 void AceContainer::DestroyView()
176 {
177 if (aceView_ != nullptr) {
178 aceView_ = nullptr;
179 }
180 }
181
InitializeFrontend()182 void AceContainer::InitializeFrontend()
183 {
184 if (type_ == FrontendType::JS) {
185 frontend_ = Frontend::Create();
186 auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
187 auto jsEngine = Framework::JsEngineLoader::Get().CreateJsEngine(GetInstanceId());
188 EngineHelper::AddEngine(instanceId_, jsEngine);
189 jsFrontend->SetJsEngine(jsEngine);
190 jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
191 jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
192 } else if (type_ == FrontendType::DECLARATIVE_JS) {
193 frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
194 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
195 auto& loader = Framework::JsEngineLoader::GetDeclarative();
196 RefPtr<Framework::JsEngine> jsEngine;
197 if (GetSettings().usingSharedRuntime) {
198 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
199 } else {
200 jsEngine = loader.CreateJsEngine(instanceId_);
201 }
202 EngineHelper::AddEngine(instanceId_, jsEngine);
203 declarativeFrontend->SetJsEngine(jsEngine);
204 declarativeFrontend->SetPageProfile(pageProfile_);
205 if (PkgContextInfo_) {
206 declarativeFrontend->SetPkgNameList(PkgContextInfo_->GetPkgNameMap());
207 declarativeFrontend->SetPkgAliasList(PkgContextInfo_->GetPkgAliasMap());
208 declarativeFrontend->SetpkgContextInfoList(PkgContextInfo_->GetPkgContextInfoMap());
209 }
210 } else if (type_ == FrontendType::JS_CARD) {
211 AceApplicationInfo::GetInstance().SetCardType();
212 frontend_ = AceType::MakeRefPtr<CardFrontend>();
213 } else if (type_ == FrontendType::ETS_CARD) {
214 frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
215 auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
216 auto jsEngine = Framework::JsEngineLoader::GetDeclarative().CreateJsEngine(instanceId_);
217 EngineHelper::AddEngine(instanceId_, jsEngine);
218 cardFrontend->SetJsEngine(jsEngine);
219 cardFrontend->SetPageProfile(pageProfile_);
220 cardFrontend->SetRunningCardId(0);
221 cardFrontend->SetIsFormRender(true);
222 cardFrontend->SetTaskExecutor(taskExecutor_);
223 if (PkgContextInfo_) {
224 cardFrontend->SetPkgNameList(PkgContextInfo_->GetPkgNameMap());
225 cardFrontend->SetPkgAliasList(PkgContextInfo_->GetPkgAliasMap());
226 cardFrontend->SetpkgContextInfoList(PkgContextInfo_->GetPkgContextInfoMap());
227 }
228 SetIsFRSCardContainer(true);
229 }
230 ACE_DCHECK(frontend_);
231 frontend_->DisallowPopLastPage();
232 frontend_->Initialize(type_, taskExecutor_);
233 if (assetManager_) {
234 frontend_->SetAssetManager(assetManager_);
235 }
236 }
237
RunNativeEngineLoop()238 void AceContainer::RunNativeEngineLoop()
239 {
240 taskExecutor_->PostTask([frontend = frontend_]() { frontend->RunNativeEngineLoop(); }, TaskExecutor::TaskType::JS,
241 "ArkUIRunNativeEngineLoop");
242 // After the JS thread executes frontend ->RunNativeEngineLoop(),
243 // it is thrown back into the Platform thread queue to form a loop.
244 taskExecutor_->PostTask([this]() { RunNativeEngineLoop(); },
245 TaskExecutor::TaskType::PLATFORM, "ArkUIRunNativeEngineLoop");
246 }
247
InitializeAppConfig(const std::string & assetPath,const std::string & bundleName,const std::string & moduleName,const std::string & compileMode)248 void AceContainer::InitializeAppConfig(const std::string& assetPath, const std::string& bundleName,
249 const std::string& moduleName, const std::string& compileMode)
250 {
251 bool isBundle = (compileMode != "esmodule");
252 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
253 CHECK_NULL_VOID(declarativeFrontend);
254 declarativeFrontend->InitializeModuleSearcher(bundleName, moduleName, assetPath, isBundle);
255
256 auto formFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
257 CHECK_NULL_VOID(formFrontend);
258 formFrontend->SetBundleName(bundleName);
259 formFrontend->SetModuleName(moduleName);
260 formFrontend->SetIsBundle(isBundle);
261 }
262
SetHspBufferTrackerCallback()263 void AceContainer::SetHspBufferTrackerCallback()
264 {
265 if (GetSettings().usingSharedRuntime) {
266 LOGI("The callback has been set by ability in the light simulator.");
267 return;
268 }
269 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
270 CHECK_NULL_VOID(frontend);
271 auto weak = WeakPtr(frontend->GetJsEngine());
272 taskExecutor_->PostTask(
273 [weak, instanceId = instanceId_]() {
274 ContainerScope scope(instanceId);
275 auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(weak.Upgrade());
276 CHECK_NULL_VOID(jsEngine);
277 jsEngine->SetHspBufferTrackerCallback(AcePreviewHelper::GetInstance()->GetCallbackOfHspBufferTracker());
278 },
279 TaskExecutor::TaskType::JS, "ArkUISetHspBufferTracker");
280 }
281
SetMockModuleListToJsEngine()282 void AceContainer::SetMockModuleListToJsEngine()
283 {
284 if (GetSettings().usingSharedRuntime) {
285 LOGI("The callback has been set by ability in the light simulator.");
286 return;
287 }
288 auto frontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
289 CHECK_NULL_VOID(frontend);
290 auto weak = WeakPtr(frontend->GetJsEngine());
291 taskExecutor_->PostTask(
292 [weak, instanceId = instanceId_, mockJsonInfo = mockJsonInfo_]() {
293 ContainerScope scope(instanceId);
294 auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(weak.Upgrade());
295 CHECK_NULL_VOID(jsEngine);
296 jsEngine->SetMockModuleList(mockJsonInfo);
297 },
298 TaskExecutor::TaskType::JS, "ArkUISetMockModuleList");
299 }
300
SetStageCardConfig(const std::string & pageProfile,const std::string & selectUrl)301 void AceContainer::SetStageCardConfig(const std::string& pageProfile, const std::string& selectUrl)
302 {
303 std::string fullPageProfile = pageProfile + ".json";
304 std::string formConfigs;
305 RefPtr<StageCardParser> stageCardParser = AceType::MakeRefPtr<StageCardParser>();
306 if (!Framework::GetAssetContentImpl(assetManager_, fullPageProfile, formConfigs)) {
307 LOGW("Can not load the form config, formConfigs is %{public}s", formConfigs.c_str());
308 return;
309 }
310 const std::string prefix("./js/");
311 stageCardParser->Parse(formConfigs, prefix + selectUrl);
312 auto cardFront = static_cast<CardFrontend*>(RawPtr(frontend_));
313 if (cardFront) {
314 cardFront->SetFormSrc(selectUrl);
315 cardFront->SetCardWindowConfig(stageCardParser->GetWindowConfig());
316 }
317 }
318
SetPkgContextInfo(const RefPtr<StagePkgContextInfo> & PkgContextInfo)319 void AceContainer::SetPkgContextInfo(const RefPtr<StagePkgContextInfo>& PkgContextInfo)
320 {
321 PkgContextInfo_ = PkgContextInfo;
322 }
323
InitializeCallback()324 void AceContainer::InitializeCallback()
325 {
326 ACE_FUNCTION_TRACE();
327
328 ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
329
330 auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
331 auto&& touchEventCallback = [weak, id = instanceId_](
332 const TouchEvent& event, const std::function<void()>& ignoreMark,
333 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
334 ContainerScope scope(id);
335 auto context = weak.Upgrade();
336 if (context == nullptr) {
337 return;
338 }
339 context->GetTaskExecutor()->PostTask(
340 [context, event]() { context->OnTouchEvent(event); },
341 TaskExecutor::TaskType::UI, "ArkUIAceContainerTouchEvent");
342 };
343 aceView_->RegisterTouchEventCallback(touchEventCallback);
344
345 auto&& keyEventCallback = [weak, id = instanceId_](const KeyEvent& event) {
346 ContainerScope scope(id);
347 auto context = weak.Upgrade();
348 if (context == nullptr) {
349 return false;
350 }
351 bool result = false;
352 context->GetTaskExecutor()->PostSyncTask(
353 [context, event, &result]() { result = context->OnNonPointerEvent(event); },
354 TaskExecutor::TaskType::UI, "ArkUIAceContainerKeyEvent");
355 return result;
356 };
357 aceView_->RegisterKeyEventCallback(keyEventCallback);
358
359 auto&& mouseEventCallback = [weak, id = instanceId_](
360 const MouseEvent& event, const std::function<void()>& ignoreMark,
361 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
362 ContainerScope scope(id);
363 auto context = weak.Upgrade();
364 if (context == nullptr) {
365 return;
366 }
367 context->GetTaskExecutor()->PostTask(
368 [context, event]() { context->OnMouseEvent(event); },
369 TaskExecutor::TaskType::UI, "ArkUIAceContainerMouseEvent");
370 };
371 aceView_->RegisterMouseEventCallback(mouseEventCallback);
372
373 auto&& axisEventCallback = [weak, id = instanceId_](
374 const AxisEvent& event, const std::function<void()>& ignoreMark,
375 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
376 ContainerScope scope(id);
377 auto context = weak.Upgrade();
378 if (context == nullptr) {
379 return;
380 }
381 context->GetTaskExecutor()->PostTask(
382 [context, event]() { context->OnAxisEvent(event); },
383 TaskExecutor::TaskType::UI, "ArkUIAceContainerAxisEvent");
384 };
385 aceView_->RegisterAxisEventCallback(axisEventCallback);
386
387 auto&& crownEventCallback = [weak, id = instanceId_](
388 const CrownEvent& event, const std::function<void()>& ignoreMark) {
389 ContainerScope scope(id);
390 auto context = weak.Upgrade();
391 if (context == nullptr) {
392 return;
393 }
394 context->GetTaskExecutor()->PostTask(
395 [context, event, id]() {
396 ContainerScope scope(id);
397 context->OnNonPointerEvent(event);
398 },
399 TaskExecutor::TaskType::UI, "ArkUIAceContainerCrownEvent");
400 };
401 aceView_->RegisterCrownEventCallback(crownEventCallback);
402
403 auto&& rotationEventCallback = [weak, id = instanceId_](const RotationEvent& event) {
404 ContainerScope scope(id);
405 auto context = weak.Upgrade();
406 if (context == nullptr) {
407 return false;
408 }
409 bool result = false;
410 context->GetTaskExecutor()->PostSyncTask(
411 [context, event, &result]() { result = context->OnRotationEvent(event); },
412 TaskExecutor::TaskType::UI, "ArkUIAceContainerRotationEvent");
413 return result;
414 };
415 aceView_->RegisterRotationEventCallback(rotationEventCallback);
416
417 auto&& cardViewPositionCallback = [weak, instanceId = instanceId_](int id, float offsetX, float offsetY) {
418 ContainerScope scope(instanceId);
419 auto context = AceType::DynamicCast<PipelineContext>(weak.Upgrade());
420 if (context == nullptr) {
421 return;
422 }
423 context->GetTaskExecutor()->PostSyncTask(
424 [context, id, offsetX, offsetY]() { context->SetCardViewPosition(id, offsetX, offsetY); },
425 TaskExecutor::TaskType::UI, "ArkUISetCardViewPosition");
426 };
427 aceView_->RegisterCardViewPositionCallback(cardViewPositionCallback);
428
429 auto&& cardViewParamsCallback = [weak, id = instanceId_](const std::string& key, bool focus) {
430 ContainerScope scope(id);
431 auto context = AceType::DynamicCast<PipelineContext>(weak.Upgrade());
432 if (context == nullptr) {
433 return;
434 }
435 context->GetTaskExecutor()->PostSyncTask(
436 [context, key, focus]() { context->SetCardViewAccessibilityParams(key, focus); },
437 TaskExecutor::TaskType::UI, "ArkUISetCardViewAccessibilityParams");
438 };
439 aceView_->RegisterCardViewAccessibilityParamsCallback(cardViewParamsCallback);
440
441 auto&& viewChangeCallback = [weak, id = instanceId_](int32_t width, int32_t height, WindowSizeChangeReason type,
442 const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
443 ContainerScope scope(id);
444 auto context = weak.Upgrade();
445 if (context == nullptr) {
446 return;
447 }
448 ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
449 context->GetTaskExecutor()->PostTask(
450 [context, width, height, type, rsTransaction]() {
451 context->OnSurfaceChanged(width, height, type, rsTransaction);
452 },
453 TaskExecutor::TaskType::UI, "ArkUISurfaceChanged");
454 };
455 aceView_->RegisterViewChangeCallback(viewChangeCallback);
456
457 auto&& densityChangeCallback = [weak, id = instanceId_](double density) {
458 ContainerScope scope(id);
459 auto context = weak.Upgrade();
460 if (context == nullptr) {
461 return;
462 }
463 ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
464 context->GetTaskExecutor()->PostTask(
465 [context, density]() { context->OnSurfaceDensityChanged(density); },
466 TaskExecutor::TaskType::UI, "ArkUIDensityChanged");
467 };
468 aceView_->RegisterDensityChangeCallback(densityChangeCallback);
469
470 auto&& systemBarHeightChangeCallback = [weak, id = instanceId_](double statusBar, double navigationBar) {
471 ContainerScope scope(id);
472 auto context = weak.Upgrade();
473 if (context == nullptr) {
474 return;
475 }
476 ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
477 context->GetTaskExecutor()->PostTask(
478 [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
479 TaskExecutor::TaskType::UI, "ArkUISystemBarHeightChanged");
480 };
481 aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
482
483 auto&& surfaceDestroyCallback = [weak, id = instanceId_]() {
484 ContainerScope scope(id);
485 auto context = weak.Upgrade();
486 if (context == nullptr) {
487 return;
488 }
489 context->GetTaskExecutor()->PostTask(
490 [context]() { context->OnSurfaceDestroyed(); },
491 TaskExecutor::TaskType::UI, "ArkUISurfaceDestroyed");
492 };
493 aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
494
495 auto&& idleCallback = [weak, id = instanceId_](int64_t deadline) {
496 ContainerScope scope(id);
497 auto context = weak.Upgrade();
498 if (context == nullptr) {
499 return;
500 }
501 context->GetTaskExecutor()->PostTask(
502 [context, deadline]() { context->OnIdle(deadline); }, TaskExecutor::TaskType::UI, "ArkUIIdleTask");
503 };
504 aceView_->RegisterIdleCallback(idleCallback);
505 }
506
CreateContainer(int32_t instanceId,FrontendType type,bool useNewPipeline,bool useCurrentEventRunner)507 void AceContainer::CreateContainer(
508 int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner)
509 {
510 auto aceContainer = AceType::MakeRefPtr<AceContainer>(instanceId, type, useNewPipeline, useCurrentEventRunner);
511 AceEngine::Get().AddContainer(aceContainer->GetInstanceId(), aceContainer);
512 aceContainer->Initialize();
513 ContainerScope scope(instanceId);
514 auto front = aceContainer->GetFrontend();
515 if (front) {
516 front->UpdateState(Frontend::State::ON_CREATE);
517 front->SetJsMessageDispatcher(aceContainer);
518 }
519 auto platMessageBridge = aceContainer->GetMessageBridge();
520 platMessageBridge->SetJsMessageDispatcher(aceContainer);
521 }
522
DestroyContainer(int32_t instanceId)523 void AceContainer::DestroyContainer(int32_t instanceId)
524 {
525 auto container = AceEngine::Get().GetContainer(instanceId);
526 if (!container) {
527 return;
528 }
529 container->Destroy();
530 // unregister watchdog before stop thread to avoid UI_BLOCK report
531 AceEngine::Get().UnRegisterFromWatchDog(instanceId);
532 auto taskExecutor = container->GetTaskExecutor();
533 if (taskExecutor) {
534 taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI, "ArkUIWaitLog");
535 taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS, "ArkUIWaitLog");
536 }
537 container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
538 EngineHelper::RemoveEngine(instanceId);
539 AceEngine::Get().RemoveContainer(instanceId);
540 }
541
RunPage(int32_t instanceId,const std::string & url,const std::string & params,bool isNamedRouter)542 UIContentErrorCode AceContainer::RunPage(
543 int32_t instanceId, const std::string& url, const std::string& params, bool isNamedRouter)
544 {
545 ACE_FUNCTION_TRACE();
546 auto container = AceEngine::Get().GetContainer(instanceId);
547 if (!container) {
548 return UIContentErrorCode::NULL_POINTER;
549 }
550
551 ContainerScope scope(instanceId);
552 auto front = container->GetFrontend();
553 CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
554 auto type = front->GetType();
555 if ((type == FrontendType::JS) || (type == FrontendType::DECLARATIVE_JS) || (type == FrontendType::JS_CARD) ||
556 (type == FrontendType::ETS_CARD)) {
557 if (isNamedRouter) {
558 return front->RunPageByNamedRouter(url, params);
559 }
560 return front->RunPage(url, params);
561 } else {
562 LOGE("Frontend type not supported when runpage");
563 }
564 return UIContentErrorCode::NULL_POINTER;
565 }
566
UpdateResourceConfiguration(const std::string & jsonStr)567 void AceContainer::UpdateResourceConfiguration(const std::string& jsonStr)
568 {
569 ContainerScope scope(instanceId_);
570 uint32_t updateFlags = 0;
571 auto resConfig = resourceInfo_.GetResourceConfiguration();
572 if (!resConfig.UpdateFromJsonString(jsonStr, updateFlags) || !updateFlags) {
573 return;
574 }
575 resourceInfo_.SetResourceConfiguration(resConfig);
576 if (ResourceConfiguration::TestFlag(updateFlags, ResourceConfiguration::COLOR_MODE_UPDATED_FLAG)) {
577 SetColorMode(resConfig.GetColorMode());
578 if (frontend_) {
579 frontend_->SetColorMode(resConfig.GetColorMode());
580 }
581 }
582 if (!pipelineContext_) {
583 return;
584 }
585 auto themeManager = pipelineContext_->GetThemeManager();
586 if (!themeManager) {
587 return;
588 }
589 themeManager->UpdateConfig(resConfig);
590 if (SystemProperties::GetResourceDecoupling()) {
591 ResourceManager::GetInstance().UpdateResourceConfig(GetBundleName(), GetModuleName(), instanceId_, resConfig);
592 }
593 taskExecutor_->PostTask(
594 [weakThemeManager = WeakPtr<ThemeManager>(themeManager), colorScheme = colorScheme_, config = resConfig,
595 weakContext = WeakPtr<PipelineBase>(pipelineContext_)]() {
596 auto themeManager = weakThemeManager.Upgrade();
597 auto context = weakContext.Upgrade();
598 if (!themeManager || !context) {
599 return;
600 }
601 themeManager->LoadResourceThemes();
602 themeManager->ParseSystemTheme();
603 themeManager->SetColorScheme(colorScheme);
604 context->RefreshRootBgColor();
605 context->UpdateFontWeightScale();
606 context->SetFontScale(config.GetFontRatio());
607 },
608 TaskExecutor::TaskType::UI, "ArkUIUpdateResourceConfig");
609 if (frontend_) {
610 frontend_->RebuildAllPages();
611 }
612 }
613
NativeOnConfigurationUpdated(int32_t instanceId)614 void AceContainer::NativeOnConfigurationUpdated(int32_t instanceId)
615 {
616 auto container = GetContainerInstance(instanceId);
617 if (!container) {
618 return;
619 }
620 ContainerScope scope(instanceId);
621 auto front = container->GetFrontend();
622 if (!front) {
623 return;
624 }
625
626 std::unique_ptr<JsonValue> value = JsonUtil::Create(true);
627 value->Put("fontScale", container->GetResourceConfiguration().GetFontRatio());
628 value->Put("colorMode", container->GetColorMode() == ColorMode::LIGHT ? "light" : "dark");
629 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(front);
630 if (declarativeFrontend) {
631 container->UpdateResourceConfiguration(value->ToString());
632 declarativeFrontend->OnConfigurationUpdated(value->ToString());
633 return;
634 }
635
636 std::unique_ptr<JsonValue> localeValue = JsonUtil::Create(true);
637 localeValue->Put(LANGUAGE_TAG, AceApplicationInfo::GetInstance().GetLanguage().c_str());
638 localeValue->Put(COUNTRY_TAG, AceApplicationInfo::GetInstance().GetCountryOrRegion().c_str());
639 localeValue->Put(
640 DIRECTION_TAG, AceApplicationInfo::GetInstance().IsRightToLeft() ? LOCALE_DIR_RTL : LOCALE_DIR_LTR);
641 localeValue->Put(UNICODE_SETTING_TAG, AceApplicationInfo::GetInstance().GetUnicodeSetting().c_str());
642 value->Put(LOCALE_KEY, localeValue);
643 front->OnConfigurationUpdated(value->ToString());
644 }
645
Dispatch(const std::string & group,std::vector<uint8_t> && data,int32_t id,bool replyToComponent) const646 void AceContainer::Dispatch(
647 const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
648 {}
649
FetchResponse(const ResponseData responseData,const int32_t callbackId) const650 void AceContainer::FetchResponse(const ResponseData responseData, const int32_t callbackId) const
651 {
652 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(0));
653 if (!container) {
654 return;
655 }
656 ContainerScope scope(instanceId_);
657 auto front = container->GetFrontend();
658 auto type = container->GetType();
659 if (type == FrontendType::JS) {
660 auto jsFrontend = AceType::DynamicCast<JsFrontend>(front);
661 if (jsFrontend) {
662 jsFrontend->TransferJsResponseDataPreview(callbackId, ACTION_SUCCESS, responseData);
663 }
664 } else if (type == FrontendType::DECLARATIVE_JS) {
665 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(front);
666 if (declarativeFrontend) {
667 declarativeFrontend->TransferJsResponseDataPreview(callbackId, ACTION_SUCCESS, responseData);
668 }
669 } else {
670 return;
671 }
672 }
673
CallCurlFunction(const RequestData requestData,const int32_t callbackId) const674 void AceContainer::CallCurlFunction(const RequestData requestData, const int32_t callbackId) const
675 {
676 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(ACE_INSTANCE_ID));
677 if (!container) {
678 return;
679 }
680
681 ContainerScope scope(instanceId_);
682 taskExecutor_->PostTask(
683 [container, requestData, callbackId]() mutable {
684 ResponseData responseData;
685 if (FetchManager::GetInstance().Fetch(requestData, callbackId, responseData)) {
686 container->FetchResponse(responseData, callbackId);
687 }
688 },
689 TaskExecutor::TaskType::BACKGROUND, "ArkUICallCurlFunction");
690 }
691
DispatchPluginError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const692 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
693 {
694 auto front = GetFrontend();
695 if (!front) {
696 return;
697 }
698
699 ContainerScope scope(instanceId_);
700 taskExecutor_->PostTask(
701 [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
702 front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
703 },
704 TaskExecutor::TaskType::BACKGROUND, "ArkUIDispatchPluginError");
705 }
706
AddRouterChangeCallback(int32_t instanceId,const OnRouterChangeCallback & onRouterChangeCallback)707 void AceContainer::AddRouterChangeCallback(int32_t instanceId, const OnRouterChangeCallback& onRouterChangeCallback)
708 {
709 auto container = GetContainerInstance(instanceId);
710 if (!container) {
711 return;
712 }
713 ContainerScope scope(instanceId);
714 if (!container->pipelineContext_) {
715 LOGW("container pipelineContext not init");
716 return;
717 }
718 container->pipelineContext_->AddRouterChangeCallback(onRouterChangeCallback);
719 }
720
721 #ifndef ENABLE_ROSEN_BACKEND
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::vector<std::string> & paths)722 void AceContainer::AddAssetPath(
723 int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths)
724 {
725 auto container = GetContainerInstance(instanceId);
726 CHECK_NULL_VOID(container);
727 if (!container->assetManager_) {
728 RefPtr<AssetManagerImpl> assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
729 container->assetManager_ = assetManagerImpl;
730 if (container->frontend_) {
731 container->frontend_->SetAssetManager(assetManagerImpl);
732 }
733 }
734 auto fileAssetProvider = AceType::MakeRefPtr<FileAssetProviderImpl>();
735 if (fileAssetProvider->Initialize("", paths)) {
736 LOGI("Push AssetProvider to queue.");
737 container->assetManager_->PushBack(std::move(fileAssetProvider));
738 }
739 }
740 #else
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::vector<std::string> & paths)741 void AceContainer::AddAssetPath(
742 int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths)
743 {
744 auto container = GetContainerInstance(instanceId);
745 CHECK_NULL_VOID(container);
746
747 if (!container->assetManager_) {
748 RefPtr<RSAssetManager> rsAssetManager = Referenced::MakeRefPtr<RSAssetManager>();
749 container->assetManager_ = rsAssetManager;
750 if (container->frontend_) {
751 container->frontend_->SetAssetManager(rsAssetManager);
752 }
753 }
754
755 for (const auto& path : paths) {
756 auto dirAssetProvider = AceType::MakeRefPtr<RSDirAssetProvider>(path);
757 container->assetManager_->PushBack(std::move(dirAssetProvider));
758 }
759 }
760 #endif
761
SetResourcesPathAndThemeStyle(int32_t instanceId,const std::string & systemResourcesPath,const std::string & hmsResourcesPath,const std::string & appResourcesPath,const int32_t & themeId,const ColorMode & colorMode)762 void AceContainer::SetResourcesPathAndThemeStyle(int32_t instanceId, const std::string& systemResourcesPath,
763 const std::string& hmsResourcesPath, const std::string& appResourcesPath, const int32_t& themeId,
764 const ColorMode& colorMode)
765 {
766 auto container = GetContainerInstance(instanceId);
767 if (!container) {
768 return;
769 }
770 ContainerScope scope(instanceId);
771 auto resConfig = container->resourceInfo_.GetResourceConfiguration();
772 resConfig.SetColorMode(static_cast<OHOS::Ace::ColorMode>(colorMode));
773 container->resourceInfo_.SetResourceConfiguration(resConfig);
774 container->resourceInfo_.SetPackagePath(appResourcesPath);
775 container->resourceInfo_.SetSystemPackagePath(systemResourcesPath);
776 if (!hmsResourcesPath.empty()) {
777 container->resourceInfo_.SetHmsPackagePath(hmsResourcesPath);
778 }
779 container->resourceInfo_.SetThemeId(themeId);
780 }
781
UpdateDeviceConfig(const DeviceConfig & deviceConfig)782 void AceContainer::UpdateDeviceConfig(const DeviceConfig& deviceConfig)
783 {
784 ContainerScope scope(instanceId_);
785 SystemProperties::InitDeviceType(deviceConfig.deviceType);
786 SystemProperties::SetDeviceOrientation(deviceConfig.orientation == DeviceOrientation::PORTRAIT ? 0 : 1);
787 SystemProperties::SetResolution(deviceConfig.density);
788 SetColorMode(deviceConfig.colorMode);
789 auto resConfig = resourceInfo_.GetResourceConfiguration();
790 if (resConfig.GetDeviceType() == deviceConfig.deviceType &&
791 resConfig.GetOrientation() == deviceConfig.orientation && resConfig.GetDensity() == deviceConfig.density &&
792 resConfig.GetColorMode() == deviceConfig.colorMode && resConfig.GetFontRatio() == deviceConfig.fontRatio) {
793 return;
794 } else {
795 resConfig.SetDeviceType(deviceConfig.deviceType);
796 resConfig.SetOrientation(deviceConfig.orientation);
797 resConfig.SetDensity(deviceConfig.density);
798 resConfig.SetColorMode(deviceConfig.colorMode);
799 resConfig.SetFontRatio(deviceConfig.fontRatio);
800 if (frontend_) {
801 frontend_->SetColorMode(deviceConfig.colorMode);
802 }
803 }
804 resourceInfo_.SetResourceConfiguration(resConfig);
805 if (!pipelineContext_) {
806 return;
807 }
808 auto themeManager = pipelineContext_->GetThemeManager();
809 if (!themeManager) {
810 return;
811 }
812 themeManager->UpdateConfig(resConfig);
813 if (SystemProperties::GetResourceDecoupling()) {
814 ResourceManager::GetInstance().UpdateResourceConfig(GetBundleName(), GetModuleName(), instanceId_, resConfig);
815 }
816 taskExecutor_->PostTask(
817 [weakThemeManager = WeakPtr<ThemeManager>(themeManager), colorScheme = colorScheme_,
818 weakContext = WeakPtr<PipelineBase>(pipelineContext_)]() {
819 auto themeManager = weakThemeManager.Upgrade();
820 auto context = weakContext.Upgrade();
821 if (!themeManager || !context) {
822 return;
823 }
824 themeManager->LoadResourceThemes();
825 themeManager->ParseSystemTheme();
826 themeManager->SetColorScheme(colorScheme);
827 context->RefreshRootBgColor();
828 },
829 TaskExecutor::TaskType::UI, "ArkUILoadTheme");
830 }
831
832 #ifndef ENABLE_ROSEN_BACKEND
SetView(AceViewPreview * view,double density,int32_t width,int32_t height)833 void AceContainer::SetView(AceViewPreview* view, double density, int32_t width, int32_t height)
834 {
835 if (view == nullptr) {
836 return;
837 }
838
839 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
840 if (!container) {
841 return;
842 }
843 auto platformWindow = PlatformWindow::Create(view);
844 if (!platformWindow) {
845 LOGE("Create PlatformWindow failed!");
846 return;
847 }
848
849 auto window = std::make_shared<Window>(std::move(platformWindow));
850 container->AttachView(std::move(window), view, density, width, height);
851 }
852 #else
SetView(AceViewPreview * view,sptr<Rosen::Window> rsWindow,double density,int32_t width,int32_t height,UIEnvCallback callback)853 void AceContainer::SetView(AceViewPreview* view, sptr<Rosen::Window> rsWindow, double density, int32_t width,
854 int32_t height, UIEnvCallback callback)
855 {
856 CHECK_NULL_VOID(view);
857 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
858 CHECK_NULL_VOID(container);
859 auto taskExecutor = container->GetTaskExecutor();
860 CHECK_NULL_VOID(taskExecutor);
861 auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
862 window->Init();
863 auto rsUIDirector = window->GetRSUIDirector();
864 CHECK_NULL_VOID(rsUIDirector);
865 rsUIDirector->SetFlushEmptyCallback(AcePreviewHelper::GetInstance()->GetCallbackFlushEmpty());
866 container->AttachView(std::move(window), view, density, width, height, callback);
867 }
868 #endif
869
870 #ifndef ENABLE_ROSEN_BACKEND
AttachView(std::shared_ptr<Window> window,AceViewPreview * view,double density,int32_t width,int32_t height)871 void AceContainer::AttachView(
872 std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height)
873 {
874 ContainerScope scope(instanceId_);
875 aceView_ = view;
876 auto instanceId = aceView_->GetInstanceId();
877
878 auto state = flutter::UIDartState::Current()->GetStateById(instanceId);
879 ACE_DCHECK(state != nullptr);
880 auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutorImpl_);
881 taskExecutorImpl->InitOtherThreads(state->GetTaskRunners());
882 if (type_ == FrontendType::DECLARATIVE_JS) {
883 // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
884 taskExecutorImpl->InitJsThread(false);
885 }
886 if (type_ == FrontendType::DECLARATIVE_JS) {
887 InitializeFrontend();
888 auto front = GetFrontend();
889 if (front) {
890 front->UpdateState(Frontend::State::ON_CREATE);
891 front->SetJsMessageDispatcher(AceType::Claim(this));
892 }
893 }
894 resRegister_ = aceView_->GetPlatformResRegister();
895 auto pipelineContext = AceType::MakeRefPtr<PipelineContext>(
896 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
897 pipelineContext->SetRootSize(density, width, height);
898 pipelineContext->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
899 pipelineContext->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
900 pipelineContext->SetMessageBridge(messageBridge_);
901 pipelineContext->SetWindowModal(windowModal_);
902 pipelineContext->SetDrawDelegate(aceView_->GetDrawDelegate());
903 pipelineContext->SetIsJsCard(type_ == FrontendType::JS_CARD);
904 pipelineContext_ = pipelineContext;
905 InitializeCallback();
906
907 ThemeConstants::InitDeviceType();
908 // Only init global resource here, construct theme in UI thread
909 auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
910
911 if (SystemProperties::GetResourceDecoupling()) {
912 auto resourceAdapter = ResourceAdapter::Create();
913 resourceAdapter->Init(resourceInfo);
914 SaveResourceAdapter(bundleName_, moduleName_, instanceId_, resourceAdapter);
915 themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resourceAdapter);
916 }
917 if (themeManager) {
918 pipelineContext_->SetThemeManager(themeManager);
919 // Init resource, load theme map.
920 if (!SystemProperties::GetResourceDecoupling()) {
921 themeManager->InitResource(resourceInfo_);
922 }
923 themeManager->LoadSystemTheme(resourceInfo_.GetThemeId());
924 taskExecutor_->PostTask(
925 [themeManager, assetManager = assetManager_, colorScheme = colorScheme_,
926 pipelineContext = pipelineContext_]() {
927 themeManager->ParseSystemTheme();
928 themeManager->SetColorScheme(colorScheme);
929 themeManager->LoadCustomTheme(assetManager);
930 // get background color from theme
931 pipelineContext->SetAppBgColor(themeManager->GetBackgroundColor());
932 },
933 TaskExecutor::TaskType::UI, "ArkUISetBackgroundColor");
934 }
935
936 auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
937 taskExecutor_->PostTask(
938 [weak]() {
939 auto context = weak.Upgrade();
940 if (context == nullptr) {
941 return;
942 }
943 context->SetupRootElement();
944 },
945 TaskExecutor::TaskType::UI, "ArkUISetupRootElement");
946 aceView_->Launch();
947
948 frontend_->AttachPipelineContext(pipelineContext_);
949 auto cardFronted = AceType::DynamicCast<CardFrontend>(frontend_);
950 if (cardFronted) {
951 cardFronted->SetDensity(static_cast<double>(density));
952 taskExecutor_->PostTask(
953 [weak, width, height]() {
954 auto context = weak.Upgrade();
955 if (context == nullptr) {
956 return;
957 }
958 context->OnSurfaceChanged(width, height);
959 },
960 TaskExecutor::TaskType::UI, "ArkUISurfaceChanged");
961 }
962
963 AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
964 }
965 #else
AttachView(std::shared_ptr<Window> window,AceViewPreview * view,double density,int32_t width,int32_t height,UIEnvCallback callback)966 void AceContainer::AttachView(std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width,
967 int32_t height, UIEnvCallback callback)
968 {
969 ContainerScope scope(instanceId_);
970 aceView_ = view;
971 auto instanceId = aceView_->GetInstanceId();
972
973 auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_);
974 CHECK_NULL_VOID(taskExecutorImpl);
975 taskExecutorImpl->InitOtherThreads(aceView_->GetThreadModelImpl());
976 if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::ETS_CARD) {
977 // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
978 taskExecutorImpl->InitJsThread(false);
979 }
980 if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::ETS_CARD) {
981 InitializeFrontend();
982 SetHspBufferTrackerCallback();
983 SetMockModuleListToJsEngine();
984 auto front = AceType::DynamicCast<DeclarativeFrontend>(GetFrontend());
985 if (front) {
986 front->UpdateState(Frontend::State::ON_CREATE);
987 front->SetJsMessageDispatcher(AceType::Claim(this));
988 auto weak = WeakPtr(front->GetJsEngine());
989 taskExecutor_->PostTask(
990 [weak, containerSdkPath = containerSdkPath_]() {
991 auto jsEngine = weak.Upgrade();
992 CHECK_NULL_VOID(jsEngine);
993 auto* nativeEngine = jsEngine->GetNativeEngine();
994 CHECK_NULL_VOID(nativeEngine);
995 auto* moduleManager = nativeEngine->GetModuleManager();
996 CHECK_NULL_VOID(moduleManager);
997 moduleManager->SetPreviewSearchPath(containerSdkPath);
998 },
999 TaskExecutor::TaskType::JS, "ArkUISetPreviewSearchPath");
1000 }
1001 }
1002 resRegister_ = aceView_->GetPlatformResRegister();
1003 if (useNewPipeline_) {
1004 pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
1005 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1006 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
1007 } else {
1008 pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
1009 std::move(window), taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1010 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
1011 }
1012 pipelineContext_->SetRootSize(density, width, height);
1013 pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
1014 pipelineContext_->SetMessageBridge(messageBridge_);
1015 pipelineContext_->SetWindowModal(windowModal_);
1016 pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
1017 pipelineContext_->SetIsJsCard(type_ == FrontendType::JS_CARD);
1018 if (installationFree_ && !isComponentMode_) {
1019 pipelineContext_->SetInstallationFree(installationFree_);
1020 pipelineContext_->SetAppLabelId(labelId_);
1021 }
1022 pipelineContext_->OnShow();
1023 pipelineContext_->WindowFocus(true);
1024 InitializeCallback();
1025
1026 auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
1027 if (cardFrontend) {
1028 pipelineContext_->SetIsFormRender(true);
1029 cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
1030 }
1031
1032 ThemeConstants::InitDeviceType();
1033 // Only init global resource here, construct theme in UI thread
1034 auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
1035
1036 if (SystemProperties::GetResourceDecoupling()) {
1037 auto resourceAdapter = ResourceAdapter::Create();
1038 resourceAdapter->Init(resourceInfo_);
1039 SaveResourceAdapter(bundleName_, moduleName_, instanceId_, resourceAdapter);
1040 themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resourceAdapter);
1041 }
1042
1043 if (themeManager) {
1044 pipelineContext_->SetThemeManager(themeManager);
1045 // Init resource, load theme map.
1046 if (!SystemProperties::GetResourceDecoupling()) {
1047 themeManager->InitResource(resourceInfo_);
1048 }
1049 themeManager->LoadSystemTheme(resourceInfo_.GetThemeId());
1050 taskExecutor_->PostTask(
1051 [themeManager, assetManager = assetManager_, colorScheme = colorScheme_,
1052 pipelineContext = pipelineContext_]() {
1053 themeManager->ParseSystemTheme();
1054 themeManager->SetColorScheme(colorScheme);
1055 themeManager->LoadCustomTheme(assetManager);
1056 // get background color from theme
1057 pipelineContext->SetAppBgColor(themeManager->GetBackgroundColor());
1058 },
1059 TaskExecutor::TaskType::UI, "ArkUISetBackgroundColor");
1060 }
1061 if (!useNewPipeline_) {
1062 taskExecutor_->PostTask(
1063 [context = pipelineContext_, callback]() {
1064 CHECK_NULL_VOID(callback);
1065 callback(AceType::DynamicCast<PipelineContext>(context));
1066 },
1067 TaskExecutor::TaskType::UI, "ArkUIEnvCallback");
1068 }
1069
1070 auto weak = AceType::WeakClaim(AceType::RawPtr(pipelineContext_));
1071 taskExecutor_->PostTask(
1072 [weak]() {
1073 auto context = weak.Upgrade();
1074 if (context == nullptr) {
1075 return;
1076 }
1077 context->SetupRootElement();
1078 },
1079 TaskExecutor::TaskType::UI, "ArkUISetupRootElement");
1080 aceView_->Launch();
1081
1082 frontend_->AttachPipelineContext(pipelineContext_);
1083 auto cardFronted = AceType::DynamicCast<CardFrontend>(frontend_);
1084 if (cardFronted) {
1085 cardFronted->SetDensity(static_cast<double>(density));
1086 taskExecutor_->PostTask(
1087 [weak, width, height]() {
1088 auto context = weak.Upgrade();
1089 if (context == nullptr) {
1090 return;
1091 }
1092 context->OnSurfaceChanged(width, height);
1093 },
1094 TaskExecutor::TaskType::UI, "ArkUISurfaceChanged");
1095 }
1096
1097 AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
1098 }
1099 #endif
1100
GetContainerInstance(int32_t instanceId)1101 RefPtr<AceContainer> AceContainer::GetContainerInstance(int32_t instanceId)
1102 {
1103 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1104 return container;
1105 }
1106
GetContentInfo(int32_t instanceId,ContentInfoType type)1107 std::string AceContainer::GetContentInfo(int32_t instanceId, ContentInfoType type)
1108 {
1109 auto container = AceEngine::Get().GetContainer(instanceId);
1110 CHECK_NULL_RETURN(container, "");
1111 ContainerScope scope(instanceId);
1112 auto front = container->GetFrontend();
1113 CHECK_NULL_RETURN(front, "");
1114 return front->GetContentInfo(type);
1115 }
1116
LoadDocument(const std::string & url,const std::string & componentName)1117 void AceContainer::LoadDocument(const std::string& url, const std::string& componentName)
1118 {
1119 ContainerScope scope(instanceId_);
1120 if (type_ != FrontendType::DECLARATIVE_JS) {
1121 LOGE("Component Preview failed: 1.0 not support");
1122 return;
1123 }
1124 auto frontend = AceType::DynamicCast<OHOS::Ace::DeclarativeFrontend>(frontend_);
1125 if (!frontend) {
1126 LOGE("Component Preview failed: the frontend is nullptr");
1127 return;
1128 }
1129 auto jsEngine = frontend->GetJsEngine();
1130 if (!jsEngine) {
1131 LOGE("Component Preview failed: the jsEngine is nullptr");
1132 return;
1133 }
1134 taskExecutor_->PostTask(
1135 [front = frontend, componentName, url, jsEngine]() {
1136 front->SetPagePath(url);
1137 jsEngine->ReplaceJSContent(url, componentName);
1138 },
1139 TaskExecutor::TaskType::JS, "ArkUIReplaceJsContent");
1140 }
1141
NotifyConfigurationChange(bool,const ConfigurationChange & configurationChange)1142 void AceContainer::NotifyConfigurationChange(bool, const ConfigurationChange& configurationChange)
1143 {
1144 taskExecutor_->PostTask(
1145 [weakContext = WeakPtr<PipelineBase>(pipelineContext_), configurationChange]() {
1146 auto pipeline = weakContext.Upgrade();
1147 CHECK_NULL_VOID(pipeline);
1148 pipeline->NotifyConfigurationChange();
1149 pipeline->FlushReload(configurationChange);
1150 },
1151 TaskExecutor::TaskType::UI, "ArkUINotifyConfigurationChange");
1152 }
1153
SetLocalStorage(NativeReference * storage,const std::shared_ptr<OHOS::AbilityRuntime::Context> & context)1154 void AceContainer::SetLocalStorage(
1155 NativeReference* storage, const std::shared_ptr<OHOS::AbilityRuntime::Context>& context)
1156 {
1157 ContainerScope scope(instanceId_);
1158 taskExecutor_->PostSyncTask(
1159 [frontend = WeakPtr<Frontend>(frontend_), storage,
1160 contextWeak = std::weak_ptr<OHOS::AbilityRuntime::Context>(context), id = instanceId_,
1161 sharedRuntime = sharedRuntime_] {
1162 auto sp = frontend.Upgrade();
1163 auto contextRef = contextWeak.lock();
1164 if (!sp || !contextRef) {
1165 ReleaseStorageReference(sharedRuntime, storage);
1166 return;
1167 }
1168 #ifdef NG_BUILD
1169 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(sp);
1170 #else
1171 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(sp);
1172 #endif
1173 if (!declarativeFrontend) {
1174 ReleaseStorageReference(sharedRuntime, storage);
1175 return;
1176 }
1177 auto jsEngine = declarativeFrontend->GetJsEngine();
1178 if (!jsEngine) {
1179 ReleaseStorageReference(sharedRuntime, storage);
1180 return;
1181 }
1182 if (contextRef->GetBindingObject() && contextRef->GetBindingObject()->Get<NativeReference>()) {
1183 jsEngine->SetContext(id, contextRef->GetBindingObject()->Get<NativeReference>());
1184 }
1185 if (storage) {
1186 jsEngine->SetLocalStorage(id, storage);
1187 }
1188 },
1189 TaskExecutor::TaskType::JS, "ArkUISetLocalStorage");
1190 }
1191
GetAbilityContextByModule(const std::string & bundle,const std::string & module)1192 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(
1193 const std::string& bundle, const std::string& module)
1194 {
1195 auto context = runtimeContext_.lock();
1196 CHECK_NULL_RETURN(context, nullptr);
1197 if (!bundle.empty() && !module.empty()) {
1198 std::string encode = EncodeBundleAndModule(bundle, module);
1199 if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1200 RecordResAdapter(encode);
1201 } else {
1202 taskExecutor_->PostTask(
1203 [encode, instanceId = instanceId_]() -> void {
1204 auto container = AceContainer::GetContainerInstance(instanceId);
1205 CHECK_NULL_VOID(container);
1206 container->RecordResAdapter(encode);
1207 },
1208 TaskExecutor::TaskType::UI, "ArkUIRecordResAdapter");
1209 }
1210 }
1211 return context->CreateModuleContext(bundle, module);
1212 }
1213
SetAbilityContext(const std::weak_ptr<OHOS::AbilityRuntime::Context> & context)1214 void AceContainer::SetAbilityContext(const std::weak_ptr<OHOS::AbilityRuntime::Context>& context)
1215 {
1216 runtimeContext_ = context;
1217 }
1218 } // namespace OHOS::Ace::Platform
1219