• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "adapter/preview/entrance/ace_container.h"
17 
18 #include <functional>
19 
20 #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