• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
17 
18 #include <mutex>
19 #include <optional>
20 #include <regex>
21 #include <shared_mutex>
22 #include <string>
23 #include <unistd.h>
24 
25 #include "dfx_jsnapi.h"
26 
27 #include "base/thread/task_executor.h"
28 #include "base/utils/utils.h"
29 #ifdef WINDOWS_PLATFORM
30 #include <algorithm>
31 #endif
32 
33 #include "ace_forward_compatibility.h"
34 #include "scope_manager/native_scope_manager.h"
35 
36 #include "base/base64/base64_util.h"
37 #include "base/i18n/localization.h"
38 #include "base/log/ace_trace.h"
39 #include "base/log/event_report.h"
40 #include "bridge/declarative_frontend/engine/jsi/nativeModule/ui_context_helper.h"
41 #include "core/common/ace_application_info.h"
42 #include "core/common/ace_view.h"
43 #include "core/common/card_scope.h"
44 #include "core/common/connect_server_manager.h"
45 #include "core/common/container.h"
46 #include "core/common/container_scope.h"
47 #include "core/common/layout_inspector.h"
48 #include "core/components_v2/inspector/inspector_constants.h"
49 #include "frameworks/bridge/card_frontend/card_frontend_declarative.h"
50 #include "frameworks/bridge/card_frontend/form_frontend_declarative.h"
51 #include "frameworks/bridge/common/utils/engine_helper.h"
52 #include "frameworks/bridge/declarative_frontend/engine/js_converter.h"
53 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
54 #include "frameworks/bridge/declarative_frontend/engine/js_types.h"
55 #include "frameworks/bridge/declarative_frontend/engine/jsi/js_ui_index.h"
56 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_group_js_bridge.h"
57 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_object_template.h"
58 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h"
59 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_view_register.h"
60 #include "frameworks/bridge/declarative_frontend/engine/jsi/modules/jsi_context_module.h"
61 #include "frameworks/bridge/declarative_frontend/engine/jsi/modules/jsi_module_manager.h"
62 #include "frameworks/bridge/declarative_frontend/engine/jsi/modules/jsi_syscap_module.h"
63 #include "frameworks/bridge/declarative_frontend/engine/jsi/modules/jsi_timer_module.h"
64 #include "frameworks/bridge/declarative_frontend/jsview/js_local_storage.h"
65 #include "frameworks/bridge/declarative_frontend/jsview/js_mock.h"
66 #include "frameworks/bridge/declarative_frontend/jsview/js_view_register.h"
67 #include "frameworks/bridge/declarative_frontend/jsview/js_view_stack_processor.h"
68 #include "frameworks/bridge/declarative_frontend/jsview/js_xcomponent.h"
69 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
70 #include "frameworks/bridge/js_frontend/engine/common/js_api_perf.h"
71 #include "frameworks/bridge/js_frontend/engine/common/runtime_constants.h"
72 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_runtime.h"
73 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_value.h"
74 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_base_utils.h"
75 #include "frameworks/core/components/xcomponent/xcomponent_component_client.h"
76 #include "frameworks/core/components_ng/base/view_stack_processor.h"
77 #include "frameworks/core/components_ng/pattern/xcomponent/xcomponent_pattern.h"
78 
79 #if defined(PREVIEW)
80 extern const char _binary_jsMockSystemPlugin_abc_start[];
81 extern const char _binary_jsMockSystemPlugin_abc_end[];
82 #endif
83 extern const char _binary_stateMgmt_abc_start[];
84 extern const char _binary_jsEnumStyle_abc_start[];
85 extern const char _binary_jsUIContext_abc_start[];
86 extern const char _binary_arkComponent_abc_start[];
87 extern const char _binary_arkTheme_abc_start[];
88 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
89 extern const char _binary_jsPreload_abc_start[];
90 extern const char _binary_jsPreload_abc_end[];
91 #endif
92 #if !defined(IOS_PLATFORM)
93 extern const char _binary_stateMgmt_abc_end[];
94 extern const char _binary_jsEnumStyle_abc_end[];
95 extern const char _binary_jsUIContext_abc_end[];
96 extern const char _binary_arkComponent_abc_end[];
97 extern const char _binary_arkTheme_abc_end[];
98 #else
99 extern const char* _binary_stateMgmt_abc_end;
100 extern const char* _binary_jsEnumStyle_abc_end;
101 extern const char* _binary_jsUIContext_abc_end;
102 extern const char* _binary_arkComponent_abc_end;
103 extern const char* _binary_arkTheme_abc_end;
104 #endif
105 
106 namespace OHOS::Ace::Framework {
107 namespace {
108 
109 const std::string OHMURL_START_TAG = "@bundle:";
110 
111 #if defined(ANDROID_PLATFORM)
112 const std::string ARK_DEBUGGER_LIB_PATH = "libark_inspector.so";
113 #elif defined(APP_USE_ARM)
114 const std::string ARK_DEBUGGER_LIB_PATH = "libark_inspector.z.so";
115 #else
116 const std::string ARK_DEBUGGER_LIB_PATH = "libark_inspector.z.so";
117 #endif
118 const std::string FORM_ES_MODULE_CARD_PATH = "ets/widgets.abc";
119 const std::string FORM_ES_MODULE_PATH = "ets/modules.abc";
120 
121 const std::string ASSET_PATH_PREFIX = "/data/storage/el1/bundle/";
122 
123 #ifdef PREVIEW
124 constexpr uint32_t PREFIX_LETTER_NUMBER = 4;
125 #endif
126 constexpr uint32_t MAX_STRING_CACHE_SIZE = 100;
127 
128 // native implementation for js function: perfutil.print()
JsPerfPrint(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)129 shared_ptr<JsValue> JsPerfPrint(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
130     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
131 {
132     std::string ret = JsApiPerf::GetInstance().PrintToLogs();
133     return runtime->NewString(ret);
134 }
135 
136 // native implementation for js function: perfutil.sleep()
JsPerfSleep(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)137 shared_ptr<JsValue> JsPerfSleep(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
138     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
139 {
140     int32_t valInt = argv[0]->ToInt32(runtime);
141     usleep(valInt);
142     return runtime->NewNull();
143 }
144 
145 // native implementation for js function: perfutil.begin()
JsPerfBegin(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)146 shared_ptr<JsValue> JsPerfBegin(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
147     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
148 {
149     int64_t currentTime = GetMicroTickCount();
150     JsApiPerf::GetInstance().InsertJsBeginLog(argv[0]->ToString(runtime), currentTime);
151     return runtime->NewNull();
152 }
153 
154 // native implementation for js function: perfutil.end()
JsPerfEnd(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)155 shared_ptr<JsValue> JsPerfEnd(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
156     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
157 {
158     int64_t currentTime = GetMicroTickCount();
159     JsApiPerf::GetInstance().InsertJsEndLog(argv[0]->ToString(runtime), currentTime);
160     return runtime->NewNull();
161 }
162 
RequireNativeModule(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)163 shared_ptr<JsValue> RequireNativeModule(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
164     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
165 {
166     std::string moduleName = argv[0]->ToString(runtime);
167 
168     // has already init module object
169     shared_ptr<JsValue> global = runtime->GetGlobal();
170     shared_ptr<JsValue> moduleObject = global->GetProperty(runtime, moduleName);
171     if (moduleObject != nullptr && moduleObject->IsObject(runtime)) {
172         return moduleObject;
173     }
174 
175     // init module object first time
176     shared_ptr<JsValue> newObject = runtime->NewObject();
177     if (ModuleManager::GetInstance()->InitModule(runtime, newObject, moduleName)) {
178         global->SetProperty(runtime, moduleName, newObject);
179         return newObject;
180     }
181 
182     return runtime->NewNull();
183 }
184 
PreloadJsEnums(const shared_ptr<JsRuntime> & runtime)185 inline bool PreloadJsEnums(const shared_ptr<JsRuntime>& runtime)
186 {
187     std::string str("arkui_binary_jsEnumStyle_abc_loadFile");
188     return runtime->EvaluateJsCode(
189         (uint8_t*)_binary_jsEnumStyle_abc_start, _binary_jsEnumStyle_abc_end - _binary_jsEnumStyle_abc_start, str);
190 }
191 
PreloadStateManagement(const shared_ptr<JsRuntime> & runtime)192 inline bool PreloadStateManagement(const shared_ptr<JsRuntime>& runtime)
193 {
194     // set __hasUIFramework__
195     runtime->GetGlobal()->SetProperty(runtime, "__hasUIFramework__", runtime->NewBoolean(true));
196 #ifdef STATE_MGMT_USE_AOT
197     return runtime->ExecuteJsBinForAOT("/etc/abc/framework/stateMgmt.abc");
198 #else
199     std::string str("arkui_binary_stateMgmt_abc_loadFile");
200     return runtime->EvaluateJsCode(
201         (uint8_t*)_binary_stateMgmt_abc_start, _binary_stateMgmt_abc_end - _binary_stateMgmt_abc_start, str);
202 #endif
203 }
204 
PreloadUIContent(const shared_ptr<JsRuntime> & runtime)205 inline bool PreloadUIContent(const shared_ptr<JsRuntime>& runtime)
206 {
207 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
208     uint8_t* codeStart = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(_binary_jsUIContext_abc_start));
209     int32_t codeLength = _binary_jsUIContext_abc_end - _binary_jsUIContext_abc_start;
210 #else
211     uint8_t* codeStart = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(_binary_jsPreload_abc_start));
212     int32_t codeLength = _binary_jsPreload_abc_end - _binary_jsPreload_abc_start;
213 #endif
214     return runtime->EvaluateJsCode(codeStart, codeLength);
215 }
216 
PreloadArkComponent(const shared_ptr<JsRuntime> & runtime)217 inline bool PreloadArkComponent(const shared_ptr<JsRuntime>& runtime)
218 {
219     std::string str("arkui_binary_arkComponent_abc_loadFile");
220     return runtime->EvaluateJsCode(
221         (uint8_t*)_binary_arkComponent_abc_start, _binary_arkComponent_abc_end - _binary_arkComponent_abc_start, str);
222 }
223 
PreloadArkTheme(const shared_ptr<JsRuntime> & runtime)224 inline bool PreloadArkTheme(const shared_ptr<JsRuntime>& runtime)
225 {
226     std::string str("arkui_binary_arkTheme_abc_loadFile");
227     return runtime->EvaluateJsCode(
228         (uint8_t*)_binary_arkTheme_abc_start, _binary_arkTheme_abc_end - _binary_arkTheme_abc_start, str);
229 }
230 
PreloadConsole(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)231 bool PreloadConsole(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
232 {
233     shared_ptr<JsValue> consoleObj = runtime->NewObject();
234     consoleObj->SetProperty(runtime, "log", runtime->NewFunction(JsiBaseUtils::AppInfoLogPrint));
235     consoleObj->SetProperty(runtime, "debug", runtime->NewFunction(JsiBaseUtils::AppDebugLogPrint));
236     consoleObj->SetProperty(runtime, "info", runtime->NewFunction(JsiBaseUtils::AppInfoLogPrint));
237     consoleObj->SetProperty(runtime, "warn", runtime->NewFunction(JsiBaseUtils::AppWarnLogPrint));
238     consoleObj->SetProperty(runtime, "error", runtime->NewFunction(JsiBaseUtils::AppErrorLogPrint));
239     return global->SetProperty(runtime, "console", consoleObj);
240 }
241 
PreloadAceConsole(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)242 bool PreloadAceConsole(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
243 {
244     shared_ptr<JsValue> aceConsoleObj = runtime->NewObject();
245     aceConsoleObj->SetProperty(runtime, "log", runtime->NewFunction(JsiBaseUtils::JsInfoLogPrint));
246     aceConsoleObj->SetProperty(runtime, "debug", runtime->NewFunction(JsiBaseUtils::JsDebugLogPrint));
247     aceConsoleObj->SetProperty(runtime, "info", runtime->NewFunction(JsiBaseUtils::JsInfoLogPrint));
248     aceConsoleObj->SetProperty(runtime, "warn", runtime->NewFunction(JsiBaseUtils::JsWarnLogPrint));
249     aceConsoleObj->SetProperty(runtime, "error", runtime->NewFunction(JsiBaseUtils::JsErrorLogPrint));
250     return global->SetProperty(runtime, "aceConsole", aceConsoleObj);
251 }
252 
PreloadAceTrace(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)253 bool PreloadAceTrace(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
254 {
255     shared_ptr<JsValue> aceTraceObj = runtime->NewObject();
256     aceTraceObj->SetProperty(runtime, "begin", runtime->NewFunction(JsiBaseUtils::JsTraceBegin));
257     aceTraceObj->SetProperty(runtime, "end", runtime->NewFunction(JsiBaseUtils::JsTraceEnd));
258     return global->SetProperty(runtime, "aceTrace", aceTraceObj);
259 }
260 
PreloadPerfutil(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)261 bool PreloadPerfutil(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
262 {
263     shared_ptr<JsValue> perfObj = runtime->NewObject();
264     perfObj->SetProperty(runtime, "printlog", runtime->NewFunction(JsPerfPrint));
265     perfObj->SetProperty(runtime, "sleep", runtime->NewFunction(JsPerfSleep));
266     perfObj->SetProperty(runtime, "begin", runtime->NewFunction(JsPerfBegin));
267     perfObj->SetProperty(runtime, "end", runtime->NewFunction(JsPerfEnd));
268     return global->SetProperty(runtime, "perfutil", perfObj);
269 }
270 
PreloadExports(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)271 inline bool PreloadExports(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
272 {
273     shared_ptr<JsValue> exportsUtilObj = runtime->NewObject();
274     return global->SetProperty(runtime, "exports", exportsUtilObj);
275 }
276 
PreloadRequireNative(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & global)277 inline bool PreloadRequireNative(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& global)
278 {
279     return global->SetProperty(runtime, "requireNativeModule", runtime->NewFunction(RequireNativeModule));
280 }
281 
282 /**
283  * The old version of the SDK will not generate the ohmUrl field, so we need to build it ourselves
284  * for forward compatibility. The basic ohmUrl formats are as follows:
285  *
286  * 1. @bundle:{bundleName}/{moduleName}/ets/{pagePath}
287  * examples as follow:
288  *   @bundle:com.example.app/entry/ets/pages/Index
289  *   @bundle:com.example.app/hsp/ets/pages/Second
290  *
291  * 2. @bundle:{bundleName}/{moduleName}@{harModuleName}/ets/{pagePath}
292  * examples as follow:
293  *   @bundle:com.example.app/entry@har/ets/pages/Index
294  *   @bundle:com.example.app/hsp@har/ets/pages/Second
295  * In this case, since the compiler did not generate the harModuleName field and pagePath is a relative path during
296  * compilation, wee need to split the harModuleName and normal pathPath fields from the original pagePath.
297  * for example:
298  *    original pagePath: "../../../../har/src/main/ets/pages/harPageTwo"
299  *     -> harModuleName: "har"
300  *     -> result pagePath: "pages/harPageTwo"
301  *
302  * For any other situation, currently only format 1 ohmUrl can be returned.
303  */
BuildOhmUrl(const std::string & bundleName,const std::string & moduleName,const std::string & pagePath)304 std::string BuildOhmUrl(const std::string& bundleName, const std::string& moduleName, const std::string& pagePath)
305 {
306     std::string tempUrl = OHMURL_START_TAG + bundleName + "/" + moduleName;
307     std::string ohmUrl = tempUrl + "/ets/" + pagePath;
308     auto pos = pagePath.rfind("../");
309     if (pos == std::string::npos) {
310         return ohmUrl;
311     }
312     std::string newPagePath = pagePath.substr(pos + 3);
313     pos = newPagePath.find("/");
314     if (pos == std::string::npos) {
315         return ohmUrl;
316     }
317     std::string harModuleName = newPagePath.substr(0, pos);
318     pos = newPagePath.find("ets");
319     if (pos == std::string::npos) {
320         return ohmUrl;
321     }
322     newPagePath = newPagePath.substr(pos);
323     return tempUrl + "@" + harModuleName + "/" + newPagePath;
324 }
325 
ParseNamedRouterParams(const EcmaVM * vm,const panda::Local<panda::ObjectRef> & params,std::string & bundleName,std::string & moduleName,std::string & pagePath,std::string & pageFullPath,std::string & ohmUrl)326 bool ParseNamedRouterParams(const EcmaVM* vm, const panda::Local<panda::ObjectRef>& params, std::string& bundleName,
327     std::string& moduleName, std::string& pagePath, std::string& pageFullPath, std::string& ohmUrl)
328 {
329     auto jsBundleName = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "bundleName"));
330     auto jsModuleName = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "moduleName"));
331     auto jsPagePath = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "pagePath"));
332     if (!jsBundleName->IsString(vm) || !jsModuleName->IsString(vm) || !jsPagePath->IsString(vm)) {
333         return false;
334     }
335     bundleName = jsBundleName->ToString(vm)->ToString(vm);
336     moduleName = jsModuleName->ToString(vm)->ToString(vm);
337     pagePath = jsPagePath->ToString(vm)->ToString(vm);
338     bool ohmUrlValid = false;
339     if (params->Has(vm, panda::StringRef::NewFromUtf8(vm, "ohmUrl"))) {
340         auto jsOhmUrl = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "ohmUrl"));
341         if (jsOhmUrl->IsString(vm)) {
342             ohmUrl = jsOhmUrl->ToString(vm)->ToString(vm);
343             ohmUrlValid = true;
344         } else {
345             TAG_LOGE(AceLogTag::ACE_ROUTER, "add named router record with invalid ohmUrl!");
346         }
347     }
348     if (!ohmUrlValid) {
349         TAG_LOGI(AceLogTag::ACE_ROUTER, "build ohmUrl for forward compatibility");
350         ohmUrl = BuildOhmUrl(bundleName, moduleName, pagePath);
351     }
352 
353     std::string integratedHspName = "false";
354     // Integrated hsp adaptation
355     if (params->Has(vm, panda::StringRef::NewFromUtf8(vm, "integratedHsp"))) {
356         auto integratedHsp = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "integratedHsp"));
357         if (integratedHsp->IsString(vm)) {
358             integratedHspName = integratedHsp->ToString(vm)->ToString(vm);
359         }
360     }
361     if (integratedHspName == "true") {
362         LocalScope scope(vm);
363         bundleName = JSNApi::GetBundleName(const_cast<EcmaVM *>(vm));
364     }
365 
366     if (params->Has(vm, panda::StringRef::NewFromUtf8(vm, "pageFullPath"))) {
367         auto pageFullPathInfo = params->Get(vm, panda::StringRef::NewFromUtf8(vm, "pageFullPath"));
368         if (pageFullPathInfo->IsString(vm)) {
369             pageFullPath = pageFullPathInfo->ToString(vm)->ToString(vm);
370         }
371     }
372 
373     return true;
374 }
375 } // namespace
376 
377 // -----------------------
378 // Start JsiDeclarativeEngineInstance
379 // -----------------------
380 std::map<std::string, std::string> JsiDeclarativeEngineInstance::mediaResourceFileMap_;
381 
382 std::unique_ptr<JsonValue> JsiDeclarativeEngineInstance::currentConfigResourceData_;
383 std::shared_mutex JsiDeclarativeEngineInstance::sharedMutex_;
384 
385 bool JsiDeclarativeEngineInstance::isModulePreloaded_ = false;
386 bool JsiDeclarativeEngineInstance::isModuleInitialized_ = false;
387 shared_ptr<JsRuntime> JsiDeclarativeEngineInstance::globalRuntime_;
388 std::shared_mutex JsiDeclarativeEngineInstance::globalRuntimeMutex_;
389 
390 // for async task callback executed after this instance has been destroyed.
391 thread_local void* cardRuntime_;
392 thread_local shared_ptr<JsRuntime> localRuntime_;
393 
394 // ArkTsCard start
395 thread_local bool isUnique_ = false;
396 // ArkTsCard end
397 
398 thread_local bool isWorker_ = false;
399 
400 thread_local bool isDynamicModulePreloaded_ = false;
401 
~JsiDeclarativeEngineInstance()402 JsiDeclarativeEngineInstance::~JsiDeclarativeEngineInstance()
403 {
404     CHECK_RUN_ON(JS);
405     LOGI("Declarative instance destroyed");
406 
407     if (runningPage_) {
408         runningPage_->OnJsEngineDestroy();
409     }
410 
411     if (stagingPage_) {
412         stagingPage_->OnJsEngineDestroy();
413     }
414 
415     if (runtime_) {
416         runtime_->RegisterUncaughtExceptionHandler(nullptr);
417         runtime_->Reset();
418     }
419     runtime_.reset();
420     runtime_ = nullptr;
421 }
422 
InitJsEnv(bool debuggerMode,const std::unordered_map<std::string,void * > & extraNativeObject,const shared_ptr<JsRuntime> & runtime)423 bool JsiDeclarativeEngineInstance::InitJsEnv(bool debuggerMode,
424     const std::unordered_map<std::string, void*>& extraNativeObject, const shared_ptr<JsRuntime>& runtime)
425 {
426     CHECK_RUN_ON(JS);
427     ACE_SCOPED_TRACE("JsiDeclarativeEngineInstance::InitJsEnv");
428     if (runtime != nullptr) {
429         runtime_ = runtime;
430         usingSharedRuntime_ = true;
431     } else {
432         runtime_.reset(new ArkJSRuntime());
433     }
434 
435     if (runtime_ == nullptr) {
436         EventReport::SendJsException(JsExcepType::JS_ENGINE_INIT_ERR);
437         return false;
438     }
439 
440 #if defined(PREVIEW)
441     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
442     arkRuntime->SetPkgNameList(pkgNameMap_);
443     arkRuntime->SetPkgAliasList(pkgAliasMap_);
444     arkRuntime->SetpkgContextInfoList(pkgContextInfoMap_);
445 #endif
446     auto container = Container::Current();
447     if (container) {
448         auto uid = container->GetAppRunningUniqueId();
449         runtime_->SetUniqueId(uid);
450     }
451     runtime_->SetLogPrint(PrintLog);
452     std::string libraryPath = "";
453     if (debuggerMode) {
454         libraryPath = ARK_DEBUGGER_LIB_PATH;
455         SetDebuggerPostTask();
456     }
457     if (!usingSharedRuntime_ && !runtime_->Initialize(libraryPath, isDebugMode_, instanceId_)) {
458         return false;
459     }
460 
461     runtime_->SetEmbedderData(this);
462     runtime_->RegisterUncaughtExceptionHandler(JsiBaseUtils::ReportJsErrorEvent);
463 
464 #if !defined(PREVIEW)
465     for (const auto& [key, value] : extraNativeObject) {
466         shared_ptr<JsValue> nativeValue = runtime_->NewNativePointer(value);
467         runtime_->GetGlobal()->SetProperty(runtime_, key, nativeValue);
468     }
469 
470     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
471     arkRuntime->SetLanguage("ets");
472     runtime_->StartDebugger();
473 #else
474     if (usingSharedRuntime_) {
475         auto global = runtime_->GetGlobal();
476         JsiTimerModule::GetInstance()->InitTimerModule(runtime_, global);
477     }
478 #endif
479     return true;
480 }
481 
InitJsObject()482 void JsiDeclarativeEngineInstance::InitJsObject()
483 {
484     CHECK_RUN_ON(JS);
485     LocalScope scope(std::static_pointer_cast<ArkJSRuntime>(runtime_)->GetEcmaVm());
486     if (!isModulePreloaded_ || !usingSharedRuntime_) {
487         InitGlobalObjectTemplate();
488     }
489 
490     // no need to initialize functions on global when use shared runtime
491     if (!usingSharedRuntime_ || !isModuleInitialized_ || isUnique_) { // ArtTsCard
492         InitGroupJsBridge();
493         if (!isModulePreloaded_ || !usingSharedRuntime_ || isUnique_) { // ArtTsCard
494             InitConsoleModule();
495             InitAceModule();
496             InitJsExportsUtilObject();
497             InitJsNativeModuleObject();
498             InitPerfUtilModule();
499             InitJsContextModuleObject();
500         }
501     } else {
502         auto container = Container::Current();
503         if (container && container->IsDynamicRender() && !isDynamicModulePreloaded_) {
504             isDynamicModulePreloaded_ = true;
505             LOGD("init ace module for dynamic component");
506             auto vm = std::static_pointer_cast<ArkJSRuntime>(runtime_)->GetEcmaVm();
507             LocalScope scope(vm);
508             RegisterStringCacheTable(vm, MAX_STRING_CACHE_SIZE);
509             // preload js views
510             JsRegisterViews(JSNApi::GetGlobalObject(vm));
511 
512             shared_ptr<JsValue> global = runtime_->GetGlobal();
513 
514             PreloadConsole(runtime_, global);
515             PreloadAceConsole(runtime_, global);
516             PreloadAceTrace(runtime_, global);
517 
518             // preload getContext
519             JsiContextModule::GetInstance()->InitContextModule(runtime_, global);
520 
521             PreloadPerfutil(runtime_, global);
522             PreloadExports(runtime_, global);
523             PreloadRequireNative(runtime_, global);
524             PreloadStateManagement(runtime_);
525             PreloadUIContent(runtime_);
526             PreloadArkComponent(runtime_);
527             PreloadArkTheme(runtime_);
528         }
529     }
530 
531     if (usingSharedRuntime_) {
532         isModuleInitialized_ = true;
533     }
534 
535     // load resourceConfig
536     std::unique_lock<std::shared_mutex> lock(sharedMutex_);
537     currentConfigResourceData_ = JsonUtil::CreateArray(true);
538     frontendDelegate_->LoadResourceConfiguration(mediaResourceFileMap_, currentConfigResourceData_);
539     isEngineInstanceInitialized_ = true;
540 }
541 
FireJsEvent(const std::string & eventStr)542 bool JsiDeclarativeEngineInstance::FireJsEvent(const std::string& eventStr)
543 {
544     return true;
545 }
546 
InitAceModule()547 void JsiDeclarativeEngineInstance::InitAceModule()
548 {
549     if (isUnique_ == false) {
550         PreloadStateManagement(runtime_);
551         PreloadJsEnums(runtime_);
552         PreloadArkComponent(runtime_);
553         PreloadArkTheme(runtime_);
554         PreloadUIContent(runtime_);
555     }
556 #if defined(PREVIEW)
557     std::string jsMockSystemPluginString(_binary_jsMockSystemPlugin_abc_start,
558         _binary_jsMockSystemPlugin_abc_end - _binary_jsMockSystemPlugin_abc_start);
559     runtime_->EvaluateJsCode((uint8_t*)(jsMockSystemPluginString.c_str()), jsMockSystemPluginString.length());
560     const std::string filename = "apiMock/jsMockHmos.abc";
561     std::string content;
562     if (!frontendDelegate_->GetAssetContent(filename, content)) {
563         LOGW("Failed to get the content from the file %{public}s", filename.c_str());
564         return;
565     }
566     if (!runtime_->EvaluateJsCode((uint8_t*)(content.c_str()), content.length())) {
567         LOGW("EvaluateJsCode jsMockHmos failed");
568     }
569 #endif
570 }
571 
OHOS_ACE_PreloadAceModuleWorker(void * runtime)572 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_PreloadAceModuleWorker(void* runtime)
573 {
574     JsiDeclarativeEngineInstance::PreloadAceModuleWorker(runtime);
575 }
576 
PreloadAceModuleWorker(void * runtime)577 void JsiDeclarativeEngineInstance::PreloadAceModuleWorker(void* runtime)
578 {
579     isWorker_ = true;
580     auto sharedRuntime = reinterpret_cast<NativeEngine*>(runtime);
581 
582     if (!sharedRuntime) {
583         return;
584     }
585     std::shared_ptr<ArkJSRuntime> arkRuntime = std::make_shared<ArkJSRuntime>();
586     auto nativeArkEngine = static_cast<ArkNativeEngine*>(sharedRuntime);
587     EcmaVM* vm = const_cast<EcmaVM*>(nativeArkEngine->GetEcmaVm());
588     if (vm == nullptr) {
589         return;
590     }
591     if (!arkRuntime->InitializeFromExistVM(vm)) {
592         return;
593     }
594     arkRuntime->SetNativeEngine(nativeArkEngine);
595     localRuntime_ = arkRuntime;
596     LocalScope scope(vm);
597 
598     RegisterStringCacheTable(vm, MAX_STRING_CACHE_SIZE);
599     // preload js views
600     shared_ptr<JsValue> global = arkRuntime->GetGlobal();
601     JsRegisterWorkerViews(JSNApi::GetGlobalObject(vm), runtime, global);
602 
603     // preload js enums
604     PreloadJsEnums(arkRuntime);
605 
606     // preload requireNative
607     JSMock::PreloadWorkerRequireNative(arkRuntime, global);
608 }
609 
ResetModulePreLoadFlag()610 void JsiDeclarativeEngineInstance::ResetModulePreLoadFlag()
611 {
612     isModulePreloaded_ = false;
613     isModuleInitialized_ = false;
614 }
615 
PrepareForResetModulePreLoadFlag()616 void JsiDeclarativeEngineInstance::PrepareForResetModulePreLoadFlag()
617 {
618     ElementRegister::GetInstance()->RegisterJSCleanUpIdleTaskFunc(nullptr);
619     JsiDeclarativeEngine::ResetNamedRouterRegisterMap();
620 }
621 
OHOS_ACE_PreloadAceModule(void * runtime)622 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_PreloadAceModule(void* runtime)
623 {
624     JsiDeclarativeEngineInstance::PreloadAceModule(runtime);
625 }
626 
PreloadAceModule(void * runtime)627 void JsiDeclarativeEngineInstance::PreloadAceModule(void* runtime)
628 {
629 #ifndef NG_BUILD
630     if (AceForwardCompatibility::PipelineChanged()) {
631         isModulePreloaded_ = false;
632     }
633 #endif
634     if (isModulePreloaded_ && !IsPlugin()) {
635         return;
636     }
637     auto sharedRuntime = reinterpret_cast<NativeEngine*>(runtime);
638 
639     if (!sharedRuntime) {
640         return;
641     }
642     std::shared_ptr<ArkJSRuntime> arkRuntime = std::make_shared<ArkJSRuntime>();
643     auto nativeArkEngine = static_cast<ArkNativeEngine*>(sharedRuntime);
644     EcmaVM* vm = const_cast<EcmaVM*>(nativeArkEngine->GetEcmaVm());
645     if (vm == nullptr) {
646         return;
647     }
648     if (!arkRuntime->InitializeFromExistVM(vm)) {
649         return;
650     }
651     LocalScope scope(vm);
652     {
653         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
654         globalRuntime_ = arkRuntime;
655     }
656 
657     RegisterStringCacheTable(vm, MAX_STRING_CACHE_SIZE);
658     // preload js views
659     JsRegisterViews(JSNApi::GetGlobalObject(vm), runtime);
660 
661     // preload aceConsole
662     shared_ptr<JsValue> global = arkRuntime->GetGlobal();
663     PreloadAceConsole(arkRuntime, global);
664 
665     // preload aceTrace
666     PreloadAceTrace(arkRuntime, global);
667 
668     // preload getContext
669     JsiContextModule::GetInstance()->InitContextModule(arkRuntime, global);
670 
671     // preload perfutil
672     PreloadPerfutil(arkRuntime, global);
673 
674     // preload exports and requireNative
675     PreloadExports(arkRuntime, global);
676     PreloadRequireNative(arkRuntime, global);
677 
678 #ifdef CROSS_PLATFORM
679     JsiSyscapModule::GetInstance()->InitSyscapModule(arkRuntime, global);
680 #endif
681 
682     // preload js enums
683     bool jsEnumStyleResult = PreloadJsEnums(arkRuntime);
684     if (!jsEnumStyleResult) {
685         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
686         globalRuntime_ = nullptr;
687         return;
688     }
689 
690     bool evalResult = PreloadStateManagement(arkRuntime);
691 
692     PreloadUIContent(arkRuntime);
693 
694     // preload ark component
695     bool arkComponentResult = PreloadArkComponent(arkRuntime);
696     if (!arkComponentResult) {
697         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
698         globalRuntime_ = nullptr;
699         return;
700     }
701 
702     // preload ark styles
703     bool arkThemeResult = PreloadArkTheme(arkRuntime);
704     if (!arkThemeResult) {
705         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
706         globalRuntime_ = nullptr;
707         return;
708     }
709 
710     isModulePreloaded_ = evalResult;
711     {
712         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
713         globalRuntime_ = nullptr;
714     }
715     localRuntime_ = arkRuntime;
716     cardRuntime_ = runtime;
717 }
718 
InitConsoleModule()719 void JsiDeclarativeEngineInstance::InitConsoleModule()
720 {
721     ACE_SCOPED_TRACE("JsiDeclarativeEngineInstance::InitConsoleModule");
722     shared_ptr<JsValue> global = runtime_->GetGlobal();
723 
724     // app log method
725     if (!usingSharedRuntime_) {
726         PreloadConsole(runtime_, global);
727     }
728 
729     if (isModulePreloaded_ && usingSharedRuntime_ && !IsPlugin() && !isUnique_) { // ArkTsCard
730         return;
731     }
732 
733     // js framework log method
734     PreloadAceConsole(runtime_, global);
735 
736     // js framework trace method
737     PreloadAceTrace(runtime_, global);
738 }
739 
InitConsoleModule(ArkNativeEngine * engine)740 void JsiDeclarativeEngineInstance::InitConsoleModule(ArkNativeEngine* engine)
741 {
742     ACE_SCOPED_TRACE("JsiDeclarativeEngineInstance::RegisterConsoleModule");
743     napi_env env = reinterpret_cast<napi_env>(engine);
744     napi_value globalObj;
745     napi_get_global(env, &globalObj);
746     napi_valuetype valueType = napi_undefined;
747     napi_typeof(env, globalObj, &valueType);
748     if (valueType != napi_object) {
749         return;
750     }
751 
752     napi_value logValue;
753     napi_create_function(env, "log", strlen("log"), AppInfoLogPrint, nullptr, &logValue);
754     napi_value debugValue;
755     napi_create_function(env, "debug", strlen("debug"), AppDebugLogPrint, nullptr, &debugValue);
756     napi_value infoValue;
757     napi_create_function(env, "info", strlen("info"), AppInfoLogPrint, nullptr, &infoValue);
758     napi_value warnValue;
759     napi_create_function(env, "warn", strlen("warn"), AppWarnLogPrint, nullptr, &warnValue);
760     napi_value errorValue;
761     napi_create_function(env, "error", strlen("error"), AppErrorLogPrint, nullptr, &errorValue);
762     napi_value consoleObj = nullptr;
763     napi_create_object(env, &consoleObj);
764     napi_set_named_property(env, consoleObj, "log", logValue);
765     napi_set_named_property(env, consoleObj, "debug", debugValue);
766     napi_set_named_property(env, consoleObj, "info", infoValue);
767     napi_set_named_property(env, consoleObj, "warn", warnValue);
768     napi_set_named_property(env, consoleObj, "error", errorValue);
769     napi_set_named_property(env, globalObj, "console", consoleObj);
770 }
771 
InitPerfUtilModule()772 void JsiDeclarativeEngineInstance::InitPerfUtilModule()
773 {
774     ACE_SCOPED_TRACE("JsiDeclarativeEngineInstance::InitPerfUtilModule");
775     shared_ptr<JsValue> global = runtime_->GetGlobal();
776     PreloadPerfutil(runtime_, global);
777 }
778 
InitJsExportsUtilObject()779 void JsiDeclarativeEngineInstance::InitJsExportsUtilObject()
780 {
781     shared_ptr<JsValue> global = runtime_->GetGlobal();
782     PreloadExports(runtime_, global);
783 }
784 
InitJsNativeModuleObject()785 void JsiDeclarativeEngineInstance::InitJsNativeModuleObject()
786 {
787     shared_ptr<JsValue> global = runtime_->GetGlobal();
788     PreloadRequireNative(runtime_, global);
789     auto context = PipelineBase::GetCurrentContext();
790     CHECK_NULL_VOID(context);
791     if (!usingSharedRuntime_) {
792         if (!context->IsFormRender()) {
793             JsiTimerModule::GetInstance()->InitTimerModule(runtime_, global);
794         }
795 
796         JsiSyscapModule::GetInstance()->InitSyscapModule(runtime_, global);
797     }
798 }
799 
InitJsContextModuleObject()800 void JsiDeclarativeEngineInstance::InitJsContextModuleObject()
801 {
802     JsiContextModule::GetInstance()->InitContextModule(runtime_, runtime_->GetGlobal());
803 }
804 
InitGlobalObjectTemplate()805 void JsiDeclarativeEngineInstance::InitGlobalObjectTemplate()
806 {
807     auto runtime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
808     RegisterStringCacheTable(runtime->GetEcmaVm(), MAX_STRING_CACHE_SIZE);
809     JsRegisterViews(JSNApi::GetGlobalObject(runtime->GetEcmaVm()), reinterpret_cast<void*>(nativeEngine_));
810 }
811 
InitGroupJsBridge()812 void JsiDeclarativeEngineInstance::InitGroupJsBridge()
813 {
814     auto groupJsBridge = DynamicCast<JsiDeclarativeGroupJsBridge>(frontendDelegate_->GetGroupJsBridge());
815     if (groupJsBridge == nullptr || groupJsBridge->InitializeGroupJsBridge(runtime_) == JS_CALL_FAIL) {
816         EventReport::SendJsException(JsExcepType::JS_ENGINE_INIT_ERR);
817     }
818     auto runtime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
819     JsUINodeRegisterCleanUp(JSNApi::GetGlobalObject(runtime->GetEcmaVm()));
820 }
821 
RootViewHandle(panda::Local<panda::ObjectRef> value)822 void JsiDeclarativeEngineInstance::RootViewHandle(panda::Local<panda::ObjectRef> value)
823 {
824     RefPtr<JsAcePage> page = JsiDeclarativeEngineInstance::GetStagingPage(Container::CurrentId());
825     if (page != nullptr) {
826         auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(GetCurrentRuntime());
827         if (!arkRuntime) {
828             return;
829         }
830         auto engine = EngineHelper::GetCurrentEngine();
831         auto jsiEngine = AceType::DynamicCast<JsiDeclarativeEngine>(engine);
832         if (!jsiEngine) {
833             return;
834         }
835         auto engineInstance = jsiEngine->GetEngineInstance();
836         if (engineInstance == nullptr) {
837             return;
838         }
839         engineInstance->SetRootView(page->GetPageId(), panda::Global<panda::ObjectRef>(arkRuntime->GetEcmaVm(), value));
840     }
841 }
842 
DestroyRootViewHandle(int32_t pageId)843 void JsiDeclarativeEngineInstance::DestroyRootViewHandle(int32_t pageId)
844 {
845     CHECK_RUN_ON(JS);
846     JAVASCRIPT_EXECUTION_SCOPE_STATIC;
847     auto iter = rootViewMap_.find(pageId);
848     if (iter != rootViewMap_.end()) {
849         auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
850         if (!arkRuntime) {
851             return;
852         }
853         panda::Local<panda::ObjectRef> rootView = iter->second.ToLocal(arkRuntime->GetEcmaVm());
854         auto* jsView = JsiObjectTemplate::GetNativeView(rootView, arkRuntime->GetEcmaVm());
855         if (jsView != nullptr) {
856             jsView->Destroy(nullptr);
857         }
858         iter->second.FreeGlobalHandleAddr();
859         rootViewMap_.erase(pageId);
860     }
861 }
862 
DestroyAllRootViewHandle()863 void JsiDeclarativeEngineInstance::DestroyAllRootViewHandle()
864 {
865     CHECK_RUN_ON(JS);
866     JAVASCRIPT_EXECUTION_SCOPE_STATIC;
867     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
868     if (!arkRuntime) {
869         return;
870     }
871     for (const auto& pair : rootViewMap_) {
872         auto globalRootView = pair.second;
873         panda::Local<panda::ObjectRef> rootView = globalRootView.ToLocal(arkRuntime->GetEcmaVm());
874         auto* jsView = JsiObjectTemplate::GetNativeView(rootView, arkRuntime->GetEcmaVm());
875         if (jsView != nullptr) {
876             jsView->Destroy(nullptr);
877         }
878         globalRootView.FreeGlobalHandleAddr();
879     }
880     rootViewMap_.clear();
881 }
882 
FlushReload()883 void JsiDeclarativeEngineInstance::FlushReload()
884 {
885     CHECK_RUN_ON(JS);
886     JAVASCRIPT_EXECUTION_SCOPE_STATIC;
887     if (rootViewMap_.empty()) {
888         return;
889     }
890     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
891     if (!arkRuntime) {
892         return;
893     }
894     for (const auto& pair : rootViewMap_) {
895         auto globalRootView = pair.second;
896         panda::Local<panda::ObjectRef> rootView = globalRootView.ToLocal(arkRuntime->GetEcmaVm());
897         auto* jsView = JsiObjectTemplate::GetNativeView(rootView, arkRuntime->GetEcmaVm());
898         if (jsView != nullptr) {
899             jsView->MarkNeedUpdate();
900         }
901     }
902 }
903 
GetI18nStringResource(const std::string & targetStringKey,const std::string & targetStringValue)904 std::unique_ptr<JsonValue> JsiDeclarativeEngineInstance::GetI18nStringResource(
905     const std::string& targetStringKey, const std::string& targetStringValue)
906 {
907     std::shared_lock<std::shared_mutex> lock(sharedMutex_);
908     auto resourceI18nFileNum = currentConfigResourceData_->GetArraySize();
909     for (int i = 0; i < resourceI18nFileNum; i++) {
910         auto priorResource = currentConfigResourceData_->GetArrayItem(i);
911         if ((priorResource->Contains(targetStringKey))) {
912             auto valuePair = priorResource->GetValue(targetStringKey);
913             if (valuePair->Contains(targetStringValue)) {
914                 return valuePair->GetValue(targetStringValue);
915             }
916         }
917     }
918 
919     return JsonUtil::Create(true);
920 }
921 
GetMediaResource(const std::string & targetFileName)922 std::string JsiDeclarativeEngineInstance::GetMediaResource(const std::string& targetFileName)
923 {
924     auto iter = mediaResourceFileMap_.find(targetFileName);
925 
926     if (iter != mediaResourceFileMap_.end()) {
927         return iter->second;
928     }
929 
930     return std::string();
931 }
932 
GetRunningPage(int32_t instanceId)933 RefPtr<JsAcePage> JsiDeclarativeEngineInstance::GetRunningPage(int32_t instanceId)
934 {
935     auto engine = EngineHelper::GetEngine(instanceId);
936     auto jsiEngine = AceType::DynamicCast<JsiDeclarativeEngine>(engine);
937     if (!jsiEngine) {
938         return nullptr;
939     }
940     auto engineInstance = jsiEngine->GetEngineInstance();
941     if (engineInstance == nullptr) {
942         return nullptr;
943     }
944     return engineInstance->GetRunningPage();
945 }
946 
GetStagingPage(int32_t instanceId)947 RefPtr<JsAcePage> JsiDeclarativeEngineInstance::GetStagingPage(int32_t instanceId)
948 {
949     auto engine = EngineHelper::GetEngine(instanceId);
950     auto jsiEngine = AceType::DynamicCast<JsiDeclarativeEngine>(engine);
951     if (!jsiEngine) {
952         return nullptr;
953     }
954     auto engineInstance = jsiEngine->GetEngineInstance();
955     if (engineInstance == nullptr) {
956         return nullptr;
957     }
958     return engineInstance->GetStagingPage();
959 }
960 
GetCurrentRuntime()961 shared_ptr<JsRuntime> JsiDeclarativeEngineInstance::GetCurrentRuntime()
962 {
963     auto jsRuntime = InnerGetCurrentRuntime();
964     if (isUnique_ && jsRuntime) {
965         return jsRuntime;
966     }
967 
968     // ArkTsCard
969     if (isUnique_ && localRuntime_) {
970         return localRuntime_;
971     }
972 
973     if (isWorker_ && localRuntime_) {
974         return localRuntime_;
975     }
976 
977     // Preload
978     std::shared_lock<std::shared_mutex> lock(globalRuntimeMutex_);
979     if (globalRuntime_) {
980         return globalRuntime_;
981     }
982 
983     return jsRuntime == nullptr ? localRuntime_ : jsRuntime;
984 }
985 
InnerGetCurrentRuntime()986 shared_ptr<JsRuntime> JsiDeclarativeEngineInstance::InnerGetCurrentRuntime()
987 {
988     auto engine = EngineHelper::GetCurrentEngine();
989     auto jsiEngine = AceType::DynamicCast<JsiDeclarativeEngine>(engine);
990     if (!jsiEngine) {
991         return nullptr;
992     }
993 
994     auto engineInstance = jsiEngine->GetEngineInstance();
995     if (engineInstance == nullptr) {
996         return nullptr;
997     }
998 
999     if (isUnique_ && !engineInstance->IsEngineInstanceInitialized()) {
1000         return nullptr;
1001     }
1002 
1003     return engineInstance->GetJsRuntime();
1004 }
1005 
CallGetUIContextFunc(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv)1006 shared_ptr<JsValue> JsiDeclarativeEngineInstance::CallGetUIContextFunc(
1007     const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv)
1008 {
1009     shared_ptr<JsValue> global = runtime->GetGlobal();
1010     shared_ptr<JsValue> func = global->GetProperty(runtime, "__getUIContext__");
1011     if (!func->IsFunction(runtime)) {
1012         return nullptr;
1013     }
1014 
1015     shared_ptr<JsValue> retVal = func->Call(runtime, global, argv, argv.size());
1016     if (!retVal) {
1017         return nullptr;
1018     }
1019 
1020     return retVal;
1021 }
1022 
CallGetFrameNodeByNodeIdFunc(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv)1023 shared_ptr<JsValue> JsiDeclarativeEngineInstance::CallGetFrameNodeByNodeIdFunc(
1024     const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv)
1025 {
1026     shared_ptr<JsValue> global = runtime->GetGlobal();
1027     shared_ptr<JsValue> func = global->GetProperty(runtime, "__getFrameNodeByNodeId__");
1028     if (!func->IsFunction(runtime)) {
1029         return nullptr;
1030     }
1031 
1032     shared_ptr<JsValue> retVal = func->Call(runtime, global, argv, argv.size());
1033     if (!retVal) {
1034         return nullptr;
1035     }
1036 
1037     return retVal;
1038 }
1039 
PostJsTask(const shared_ptr<JsRuntime> & runtime,std::function<void ()> && task,const std::string & name)1040 void JsiDeclarativeEngineInstance::PostJsTask(
1041     const shared_ptr<JsRuntime>& runtime, std::function<void()>&& task, const std::string& name)
1042 {
1043     if (runtime == nullptr) {
1044         return;
1045     }
1046     auto engineInstance = static_cast<JsiDeclarativeEngineInstance*>(runtime->GetEmbedderData());
1047     if (engineInstance == nullptr) {
1048         return;
1049     }
1050     engineInstance->GetDelegate()->PostJsTask(std::move(task), name);
1051 }
1052 
TriggerPageUpdate(const shared_ptr<JsRuntime> & runtime)1053 void JsiDeclarativeEngineInstance::TriggerPageUpdate(const shared_ptr<JsRuntime>& runtime)
1054 {
1055     CHECK_NULL_VOID(runtime);
1056     auto engineInstance = static_cast<JsiDeclarativeEngineInstance*>(runtime->GetEmbedderData());
1057     CHECK_NULL_VOID(engineInstance);
1058     auto page = engineInstance->GetRunningPage();
1059     CHECK_NULL_VOID(page);
1060     engineInstance->GetDelegate()->TriggerPageUpdate(page->GetPageId());
1061 }
1062 
GetPipelineContext(const shared_ptr<JsRuntime> & runtime)1063 RefPtr<PipelineBase> JsiDeclarativeEngineInstance::GetPipelineContext(const shared_ptr<JsRuntime>& runtime)
1064 {
1065     if (runtime == nullptr) {
1066         return nullptr;
1067     }
1068     auto engineInstance = static_cast<JsiDeclarativeEngineInstance*>(runtime->GetEmbedderData());
1069     if (engineInstance == nullptr) {
1070         return nullptr;
1071     }
1072     return engineInstance->GetDelegate()->GetPipelineContext();
1073 }
1074 
FlushCommandBuffer(void * context,const std::string & command)1075 void JsiDeclarativeEngineInstance::FlushCommandBuffer(void* context, const std::string& command)
1076 {
1077     return;
1078 }
1079 
IsPlugin()1080 bool JsiDeclarativeEngineInstance::IsPlugin()
1081 {
1082     return (ContainerScope::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID);
1083 }
1084 
SetDebuggerPostTask()1085 void JsiDeclarativeEngineInstance::SetDebuggerPostTask()
1086 {
1087     auto weakDelegate = AceType::WeakClaim(AceType::RawPtr(frontendDelegate_));
1088     auto&& postTask = [weakDelegate](std::function<void()>&& task) {
1089         auto delegate = weakDelegate.Upgrade();
1090         if (delegate == nullptr) {
1091             return;
1092         }
1093         delegate->PostJsTask(std::move(task), "ArkUIDebuggerTask");
1094     };
1095     std::static_pointer_cast<ArkJSRuntime>(runtime_)->SetDebuggerPostTask(postTask);
1096 }
1097 
RegisterFaPlugin()1098 void JsiDeclarativeEngineInstance::RegisterFaPlugin()
1099 {
1100     shared_ptr<JsValue> global = runtime_->GetGlobal();
1101     shared_ptr<JsValue> requireNapiFunc = global->GetProperty(runtime_, "requireNapi");
1102     if (!requireNapiFunc || !requireNapiFunc->IsFunction(runtime_)) {
1103         return;
1104     }
1105     std::vector<shared_ptr<JsValue>> argv = { runtime_->NewString("FeatureAbility") };
1106     requireNapiFunc->Call(runtime_, global, argv, argv.size());
1107 }
1108 
GetContextValue()1109 napi_value JsiDeclarativeEngineInstance::GetContextValue()
1110 {
1111     auto runtime = GetJsRuntime();
1112 
1113     // obtain uiContext instance
1114     std::vector<shared_ptr<JsValue>> argv = { runtime->NewNumber(instanceId_) };
1115     shared_ptr<JsValue> uiContext = CallGetUIContextFunc(runtime, argv);
1116     if (uiContext) {
1117         SetContextValue(uiContext);
1118     }
1119 
1120     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1121     if (!arkJSRuntime) {
1122         return nullptr;
1123     }
1124     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(uiContext_);
1125     if (!arkJSValue) {
1126         return nullptr;
1127     }
1128     auto arkNativeEngine = static_cast<ArkNativeEngine*>(GetNativeEngine());
1129     if (!arkNativeEngine) {
1130         return nullptr;
1131     }
1132     napi_value napiValue = ArkNativeEngine::ArkValueToNapiValue(
1133         reinterpret_cast<napi_env>(GetNativeEngine()), arkJSValue->GetValue(arkJSRuntime));
1134 
1135     return napiValue;
1136 }
1137 
GetFrameNodeValueByNodeId(int32_t nodeId)1138 napi_value JsiDeclarativeEngineInstance::GetFrameNodeValueByNodeId(int32_t nodeId)
1139 {
1140     auto runtime = GetJsRuntime();
1141 
1142     // obtain frameNode instance
1143     std::vector<shared_ptr<JsValue>> argv = { runtime->NewNumber(instanceId_), runtime->NewNumber(nodeId) };
1144     shared_ptr<JsValue> frameNode = CallGetFrameNodeByNodeIdFunc(runtime, argv);
1145 
1146     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1147     if (!arkJSRuntime) {
1148         return nullptr;
1149     }
1150     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(frameNode);
1151     if (!arkJSValue) {
1152         return nullptr;
1153     }
1154     auto arkNativeEngine = static_cast<ArkNativeEngine*>(GetNativeEngine());
1155     if (!arkNativeEngine) {
1156         return nullptr;
1157     }
1158     napi_value napiValue = ArkNativeEngine::ArkValueToNapiValue(
1159         reinterpret_cast<napi_env>(GetNativeEngine()), arkJSValue->GetValue(arkJSRuntime));
1160 
1161     return napiValue;
1162 }
1163 
1164 thread_local std::unordered_map<std::string, NamedRouterProperty> JsiDeclarativeEngine::namedRouterRegisterMap_;
1165 thread_local std::unordered_map<std::string, std::string> JsiDeclarativeEngine::routerPathInfoMap_;
1166 thread_local std::unordered_map<std::string, panda::Global<panda::ObjectRef>> JsiDeclarativeEngine::builderMap_;
1167 thread_local panda::Global<panda::ObjectRef> JsiDeclarativeEngine::obj_;
1168 
1169 // -----------------------
1170 // Start JsiDeclarativeEngine
1171 // -----------------------
~JsiDeclarativeEngine()1172 JsiDeclarativeEngine::~JsiDeclarativeEngine()
1173 {
1174     CHECK_RUN_ON(JS);
1175     LOGI("Declarative engine destroyed");
1176 }
1177 
Destroy()1178 void JsiDeclarativeEngine::Destroy()
1179 {
1180     CHECK_RUN_ON(JS);
1181 
1182 #ifdef USE_ARK_ENGINE
1183     JSLocalStorage::RemoveStorage(instanceId_);
1184     JsiContextModule::RemoveContext(instanceId_);
1185 #endif
1186 
1187     engineInstance_->GetDelegate()->RemoveTaskObserver();
1188     engineInstance_->DestroyAllRootViewHandle();
1189     if (isUnique_) {
1190         RunFullGarbageCollection();
1191     }
1192 
1193     if (!runtime_ && nativeEngine_ != nullptr) {
1194 #if !defined(PREVIEW)
1195         nativeEngine_->CancelCheckUVLoop();
1196 #endif
1197         delete nativeEngine_;
1198         nativeEngine_ = nullptr;
1199     }
1200 }
1201 
Initialize(const RefPtr<FrontendDelegate> & delegate)1202 bool JsiDeclarativeEngine::Initialize(const RefPtr<FrontendDelegate>& delegate)
1203 {
1204     CHECK_RUN_ON(JS);
1205     ACE_SCOPED_TRACE("JsiDeclarativeEngine::Initialize");
1206     ACE_DCHECK(delegate);
1207     NG::UIContextHelper::RegisterRemoveUIContextFunc();
1208     engineInstance_ = AceType::MakeRefPtr<JsiDeclarativeEngineInstance>(delegate);
1209     auto sharedRuntime = reinterpret_cast<NativeEngine*>(runtime_);
1210     std::shared_ptr<ArkJSRuntime> arkRuntime;
1211     EcmaVM* vm = nullptr;
1212     if (sharedRuntime) {
1213         arkRuntime = std::make_shared<ArkJSRuntime>();
1214         if (isUnique_ && reinterpret_cast<NativeEngine*>(cardRuntime_) != nullptr) {
1215             sharedRuntime = reinterpret_cast<NativeEngine*>(cardRuntime_);
1216         }
1217         auto nativeArkEngine = static_cast<ArkNativeEngine*>(sharedRuntime);
1218         vm = const_cast<EcmaVM*>(nativeArkEngine->GetEcmaVm());
1219         if (vm == nullptr) {
1220             return false;
1221         }
1222         if (!arkRuntime->InitializeFromExistVM(vm)) {
1223             return false;
1224         }
1225         nativeEngine_ = nativeArkEngine;
1226         arkRuntime->SetNativeEngine(nativeArkEngine);
1227     }
1228     engineInstance_->SetInstanceId(instanceId_);
1229     engineInstance_->SetDebugMode(NeedDebugBreakPoint());
1230 #if defined(PREVIEW)
1231     engineInstance_->SetPkgNameList(pkgNameMap_);
1232     engineInstance_->SetPkgAliasList(pkgAliasMap_);
1233     engineInstance_->SetpkgContextInfoList(pkgContextInfoMap_);
1234 #endif
1235     bool result = engineInstance_->InitJsEnv(IsDebugVersion(), GetExtraNativeObject(), arkRuntime);
1236     if (!result) {
1237         return false;
1238     }
1239 
1240     auto runtime = engineInstance_->GetJsRuntime();
1241     vm = vm ? vm : const_cast<EcmaVM*>(std::static_pointer_cast<ArkJSRuntime>(runtime)->GetEcmaVm());
1242     if (vm == nullptr) {
1243         return false;
1244     }
1245 
1246     if (nativeEngine_ == nullptr) {
1247         nativeEngine_ = new ArkNativeEngine(vm, static_cast<void*>(this));
1248     }
1249     EngineTask(sharedRuntime);
1250     return result;
1251 }
1252 
EngineTask(bool sharedRuntime)1253 void JsiDeclarativeEngine::EngineTask(bool sharedRuntime)
1254 {
1255     engineInstance_->SetNativeEngine(nativeEngine_);
1256     engineInstance_->InitJsObject();
1257     if (!sharedRuntime) {
1258         SetPostTask(nativeEngine_);
1259 #if !defined(PREVIEW)
1260         nativeEngine_->CheckUVLoop();
1261 #endif
1262         RegisterWorker();
1263         engineInstance_->RegisterFaPlugin();
1264     }
1265 }
1266 
SetPostTask(NativeEngine * nativeEngine)1267 void JsiDeclarativeEngine::SetPostTask(NativeEngine* nativeEngine)
1268 {
1269     auto weakDelegate = WeakPtr(engineInstance_->GetDelegate());
1270     auto&& postTask = [weakDelegate, weakEngine = AceType::WeakClaim(this), id = instanceId_](bool needSync) {
1271         auto delegate = weakDelegate.Upgrade();
1272         if (delegate == nullptr) {
1273             return;
1274         }
1275         delegate->PostJsTask(
1276             [weakEngine, needSync, id]() {
1277                 auto jsEngine = weakEngine.Upgrade();
1278                 if (jsEngine == nullptr) {
1279                     return;
1280                 }
1281                 auto nativeEngine = jsEngine->GetNativeEngine();
1282                 if (nativeEngine == nullptr) {
1283                     return;
1284                 }
1285                 ContainerScope scope(id);
1286                 nativeEngine->Loop(LOOP_NOWAIT, needSync);
1287             },
1288             "ArkUISetNativeEngineLoop");
1289     };
1290     nativeEngine_->SetPostTask(postTask);
1291 }
1292 
RegisterInitWorkerFunc()1293 void JsiDeclarativeEngine::RegisterInitWorkerFunc()
1294 {
1295     auto weakInstance = AceType::WeakClaim(AceType::RawPtr(engineInstance_));
1296     bool debugVersion = IsDebugVersion();
1297     std::string libraryPath = "";
1298     if (debugVersion) {
1299         libraryPath = ARK_DEBUGGER_LIB_PATH;
1300     }
1301     auto&& initWorkerFunc = [weakInstance, libraryPath, debugVersion](
1302                                 NativeEngine* nativeEngine) {
1303         if (nativeEngine == nullptr) {
1304             return;
1305         }
1306         auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
1307         if (arkNativeEngine == nullptr) {
1308             return;
1309         }
1310         auto instance = weakInstance.Upgrade();
1311         if (instance == nullptr) {
1312             return;
1313         }
1314 #ifdef OHOS_PLATFORM
1315         auto tid = gettid();
1316         ConnectServerManager::Get().AddInstance(tid, "ets");
1317         auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
1318         auto workerPostTask = [nativeEngine](std::function<void()>&& callback) {
1319             nativeEngine->CallDebuggerPostTaskFunc(std::move(callback));
1320         };
1321         bool debugMode = AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint();
1322         panda::JSNApi::DebugOption debugOption = { libraryPath.c_str(), debugMode, -1, true }; //FA:true port:-1
1323         JSNApi::NotifyDebugMode(tid, vm, debugOption, tid, workerPostTask, debugVersion);
1324 #endif
1325         instance->InitConsoleModule(arkNativeEngine);
1326 
1327         std::vector<uint8_t> buffer((uint8_t*)_binary_jsEnumStyle_abc_start, (uint8_t*)_binary_jsEnumStyle_abc_end);
1328         arkNativeEngine->RunBufferScript(buffer);
1329     };
1330     nativeEngine_->SetInitWorkerFunc(initWorkerFunc);
1331 }
1332 
1333 #ifdef OHOS_PLATFORM
RegisterOffWorkerFunc()1334 void JsiDeclarativeEngine::RegisterOffWorkerFunc()
1335 {
1336     auto weakInstance = AceType::WeakClaim(AceType::RawPtr(engineInstance_));
1337     bool debugVersion = IsDebugVersion();
1338     auto&& offWorkerFunc = [debugVersion](NativeEngine* nativeEngine) {
1339         if (!debugVersion) {
1340             return;
1341         }
1342         if (nativeEngine == nullptr) {
1343             return;
1344         }
1345         auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
1346         if (arkNativeEngine == nullptr) {
1347             return;
1348         }
1349         ConnectServerManager::Get().RemoveInstance(gettid());
1350         auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
1351         panda::JSNApi::StopDebugger(vm);
1352     };
1353     nativeEngine_->SetOffWorkerFunc(offWorkerFunc);
1354 }
1355 #endif
1356 
RegisterAssetFunc()1357 void JsiDeclarativeEngine::RegisterAssetFunc()
1358 {
1359     auto weakDelegate = WeakPtr(engineInstance_->GetDelegate());
1360     auto&& assetFunc = [weakDelegate](const std::string& uri, uint8_t** buff, size_t* buffSize,
1361         std::vector<uint8_t>& content, std::string& ami, bool& useSecureMem, bool isRestricted) {
1362         auto delegate = weakDelegate.Upgrade();
1363         if (delegate == nullptr) {
1364             return;
1365         }
1366         size_t index = uri.find_last_of(".");
1367         if (index != std::string::npos) {
1368             delegate->GetResourceData(uri.substr(0, index) + ".abc", content, ami);
1369             useSecureMem = false;
1370         }
1371     };
1372     nativeEngine_->SetGetAssetFunc(assetFunc);
1373 }
1374 
RegisterWorker()1375 void JsiDeclarativeEngine::RegisterWorker()
1376 {
1377     RegisterInitWorkerFunc();
1378 #ifdef OHOS_PLATFORM
1379     RegisterOffWorkerFunc();
1380 #endif
1381     RegisterAssetFunc();
1382 }
1383 
ExecuteAbc(const std::string & fileName)1384 bool JsiDeclarativeEngine::ExecuteAbc(const std::string& fileName)
1385 {
1386     ACE_SCOPED_TRACE("JsiDeclarativeEngine::ExecuteAbc Execute Page code : %s", fileName.c_str());
1387     auto runtime = engineInstance_->GetJsRuntime();
1388     auto delegate = engineInstance_->GetDelegate();
1389     std::vector<uint8_t> content;
1390     if (!delegate->GetAssetContent(fileName, content)) {
1391         return true;
1392     }
1393 #if !defined(PREVIEW)
1394     const std::string abcPath = delegate->GetAssetPath(fileName).append(fileName);
1395 #else
1396     const std::string& abcPath = fileName;
1397 #endif
1398     if (!runtime->EvaluateJsCode(content.data(), content.size(), abcPath, needUpdate_)) {
1399         return false;
1400     }
1401     return true;
1402 }
1403 
ExecuteJs(const uint8_t * content,int32_t size)1404 bool JsiDeclarativeEngine::ExecuteJs(const uint8_t* content, int32_t size)
1405 {
1406     auto runtime = engineInstance_->GetJsRuntime();
1407     CHECK_NULL_RETURN(runtime, false);
1408     if (!runtime->EvaluateJsCode(content, size)) {
1409         return false;
1410     }
1411     return true;
1412 }
1413 
ExecuteCardAbc(const std::string & fileName,int64_t cardId)1414 bool JsiDeclarativeEngine::ExecuteCardAbc(const std::string& fileName, int64_t cardId)
1415 {
1416     auto runtime = engineInstance_->GetJsRuntime();
1417     CHECK_NULL_RETURN(runtime, false);
1418     auto container = Container::Current();
1419     CHECK_NULL_RETURN(container, false);
1420     CardScope cardScope(cardId);
1421     std::string abcPath;
1422     std::vector<uint8_t> content;
1423     if (container->IsFRSCardContainer()) {
1424         auto frontEnd = AceType::DynamicCast<FormFrontendDeclarative>(container->GetCardFrontend(cardId).Upgrade());
1425         CHECK_NULL_RETURN(frontEnd, false);
1426         auto delegate = frontEnd->GetDelegate();
1427         CHECK_NULL_RETURN(delegate, false);
1428         if (frontEnd->IsBundle()) {
1429             if (!delegate->GetAssetContent(fileName, content)) {
1430                 return false;
1431             }
1432             abcPath = delegate->GetAssetPath(fileName).append(fileName);
1433             if (!runtime->EvaluateJsCode(content.data(), content.size(), abcPath)) {
1434                 return false;
1435             }
1436             return true;
1437         }
1438         if (!delegate->GetAssetContent(FORM_ES_MODULE_CARD_PATH, content)) {
1439             return false;
1440         }
1441         const std::string bundleName = frontEnd->GetBundleName();
1442         std::string moduleName = frontEnd->GetModuleName();
1443 #ifdef PREVIEW
1444         const std::string assetPath = delegate->GetAssetPath(FORM_ES_MODULE_CARD_PATH).append(FORM_ES_MODULE_CARD_PATH);
1445 #else
1446         const std::string assetPath =
1447             ASSET_PATH_PREFIX + bundleName + "/" + moduleName + "/" + FORM_ES_MODULE_CARD_PATH;
1448 #endif
1449         auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1450         CHECK_NULL_RETURN(arkRuntime, false);
1451         arkRuntime->SetBundleName(bundleName);
1452         arkRuntime->SetAssetPath(assetPath);
1453         arkRuntime->SetBundle(false);
1454         arkRuntime->SetModuleName(moduleName);
1455 #ifdef PREVIEW
1456         // remove the prefix of "ets/"
1457         abcPath = fileName.substr(PREFIX_LETTER_NUMBER);
1458 #else
1459         abcPath = moduleName.append("/").append(fileName);
1460 #endif
1461         {
1462             if (!arkRuntime->ExecuteModuleBuffer(content.data(), content.size(), abcPath, true)) {
1463                 return false;
1464             }
1465         }
1466         return true;
1467     } else {
1468         auto frontEnd = AceType::DynamicCast<CardFrontendDeclarative>(container->GetCardFrontend(cardId).Upgrade());
1469         CHECK_NULL_RETURN(frontEnd, false);
1470         auto delegate = frontEnd->GetDelegate();
1471         CHECK_NULL_RETURN(delegate, false);
1472         if (!delegate->GetAssetContent(fileName, content)) {
1473             return false;
1474         }
1475         abcPath = delegate->GetAssetPath(fileName).append(fileName);
1476     }
1477     if (!runtime->EvaluateJsCode(content.data(), content.size(), abcPath)) {
1478         return false;
1479     }
1480     return true;
1481 }
1482 
ExecuteDynamicAbc(const std::string & fileName,const std::string & entryPoint)1483 bool JsiDeclarativeEngine::ExecuteDynamicAbc(const std::string& fileName, const std::string& entryPoint)
1484 {
1485     auto container = Container::Current();
1486     CHECK_NULL_RETURN(container, false);
1487     auto uiContentType = container->GetUIContentType();
1488     LOGI("ExecuteDynamicAbc uiContentType: %{public}d", static_cast<int32_t>(uiContentType));
1489     if (uiContentType == UIContentType::DYNAMIC_COMPONENT) {
1490         return InnerExecuteDynamicAbc(fileName, entryPoint);
1491     }
1492 
1493     return InnerExecuteIsolatedAbc(fileName, entryPoint);
1494 }
1495 
InnerExecuteIsolatedAbc(const std::string & fileName,const std::string & entryPoint)1496 bool JsiDeclarativeEngine::InnerExecuteIsolatedAbc(
1497     const std::string& fileName, const std::string& entryPoint)
1498 {
1499     CHECK_NULL_RETURN(runtime_, false);
1500     auto engine = reinterpret_cast<NativeEngine*>(runtime_);
1501     CHECK_NULL_RETURN(engine, false);
1502     auto vm = engine->GetEcmaVm();
1503     CHECK_NULL_RETURN(vm, false);
1504     panda::TryCatch trycatch(vm);
1505 
1506     panda::JSNApi::SetModuleInfo(const_cast<EcmaVM*>(vm), ASSET_PATH_PREFIX + fileName, entryPoint);
1507     if (trycatch.HasCaught()) {
1508         engine->lastException_ = trycatch.GetException();
1509         return false;
1510     }
1511 
1512     engine->RunScriptForAbc(fileName.c_str(), const_cast<char*>(entryPoint.c_str()));
1513     if (trycatch.HasCaught()) {
1514         engine->lastException_ = trycatch.GetException();
1515         return false;
1516     }
1517     return true;
1518 }
1519 
InnerExecuteDynamicAbc(const std::string & fileName,const std::string & entryPoint)1520 bool JsiDeclarativeEngine::InnerExecuteDynamicAbc(
1521     const std::string& fileName, const std::string& entryPoint)
1522 {
1523     auto container = Container::Current();
1524     CHECK_NULL_RETURN(container, false);
1525     CHECK_NULL_RETURN(runtime_, false);
1526     auto engine = reinterpret_cast<NativeEngine*>(runtime_);
1527     CHECK_NULL_RETURN(engine, false);
1528     auto vm = engine->GetEcmaVm();
1529     CHECK_NULL_RETURN(vm, false);
1530     CHECK_NULL_RETURN(engineInstance_, false);
1531     auto runtime = engineInstance_->GetJsRuntime();
1532     CHECK_NULL_RETURN(runtime, false);
1533     auto arkJsRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1534     CHECK_NULL_RETURN(arkJsRuntime, false);
1535     auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(container->GetFrontend());
1536     CHECK_NULL_RETURN(frontend, false);
1537     auto bundleName = frontend->GetBundleName();
1538     auto moduleName = frontend->GetModuleName();
1539     if (bundleName.empty() || moduleName.empty()) {
1540         LOGW("Get bundleName(%{public}s) or moduleName(%{public}s) failed",
1541             bundleName.c_str(), moduleName.c_str());
1542         return false;
1543     }
1544 
1545     std::string assetPath = ASSET_PATH_PREFIX + moduleName + "/" + FORM_ES_MODULE_PATH;
1546     LOGD("InnerExecuteDynamicAbc bundleName: %{public}s, moduleName: %{public}s, assetPath: %{public}s",
1547         bundleName.c_str(), moduleName.c_str(), assetPath.c_str());
1548     panda::TryCatch trycatch(vm);
1549     panda::JSNApi::SetModuleInfo(const_cast<EcmaVM*>(vm), assetPath.c_str(), entryPoint);
1550     if (trycatch.HasCaught()) {
1551         engine->lastException_ = trycatch.GetException();
1552         return false;
1553     }
1554 
1555     const char binExt[] = ".abc";
1556     std::string urlName = entryPoint.substr(bundleName.size() + 1) + binExt;
1557     LOGD("InnerExecuteDynamicAbc ExecuteJsBin urlName: %{public}s", urlName.c_str());
1558     runtime->ExecuteJsBin(urlName);
1559     if (trycatch.HasCaught()) {
1560         engine->lastException_ = trycatch.GetException();
1561         return false;
1562     }
1563 
1564     return true;
1565 }
1566 
UpdateRootComponent()1567 bool JsiDeclarativeEngine::UpdateRootComponent()
1568 {
1569     if (!JsiDeclarativeEngine::obj_.IsEmpty()) {
1570         LOGI("update rootComponent start");
1571         LocalScope scope(obj_.GetEcmaVM());
1572         Framework::UpdateRootComponent(obj_.GetEcmaVM(), JsiDeclarativeEngine::obj_.ToLocal());
1573         // Clear the global object to avoid load this obj next time
1574         JsiDeclarativeEngine::obj_.FreeGlobalHandleAddr();
1575         JsiDeclarativeEngine::obj_.Empty();
1576         return true;
1577     }
1578     return false;
1579 }
1580 
LoadPluginComponent(const std::string & url,const RefPtr<JsAcePage> & page,bool isMainPage)1581 bool JsiDeclarativeEngine::LoadPluginComponent(const std::string &url, const RefPtr<JsAcePage>& page, bool isMainPage)
1582 {
1583     LoadJs(url, page, isMainPage);
1584     if (!UpdateRootComponent()) {
1585         auto pagePath = url;
1586         if (pagePath.rfind(".js") != std::string::npos) {
1587             pagePath = pagePath.substr(0, pagePath.length() - strlen(".js"));
1588         }
1589         std::string pluginUrlName = OHMURL_START_TAG + pluginBundleName_ + "/" + pluginModuleName_ + "/ets/" + pagePath;
1590         return LoadNamedRouterSource(pluginUrlName, false);
1591     }
1592     return true;
1593 }
1594 
LoadJs(const std::string & url,const RefPtr<JsAcePage> & page,bool isMainPage)1595 void JsiDeclarativeEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage>& page, bool isMainPage)
1596 {
1597     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadJs url : %s", url.c_str());
1598     LOGI("LoadJs page:%{public}d", page->GetPageId());
1599     ACE_DCHECK(engineInstance_);
1600     engineInstance_->SetStagingPage(page);
1601     if (isMainPage) {
1602         ACE_DCHECK(!engineInstance_->GetRunningPage());
1603         engineInstance_->SetRunningPage(page);
1604     }
1605     auto runtime = engineInstance_->GetJsRuntime();
1606     auto delegate = engineInstance_->GetDelegate();
1607     auto vm = const_cast<EcmaVM*>(std::static_pointer_cast<ArkJSRuntime>(runtime)->GetEcmaVm());
1608     // get source map
1609     std::string jsSourceMap;
1610     if (JSNApi::IsBundle(vm)) {
1611         if (delegate->GetAssetContent(url + ".map", jsSourceMap)) {
1612             page->SetPageMap(jsSourceMap);
1613         }
1614     }
1615     // get js bundle content
1616     shared_ptr<JsValue> jsCode = runtime->NewUndefined();
1617     shared_ptr<JsValue> jsAppCode = runtime->NewUndefined();
1618     const char js_ext[] = ".js";
1619     const char bin_ext[] = ".abc";
1620     auto pos = url.rfind(js_ext);
1621     if (pos != std::string::npos && pos == url.length() - (sizeof(js_ext) - 1)) {
1622         std::string urlName = url.substr(0, pos) + bin_ext;
1623 #if !defined(PREVIEW)
1624         if (IsModule()) {
1625             if (!engineInstance_->IsPlugin()) {
1626                 LoadJsWithModule(urlName);
1627                 return;
1628             }
1629             if (!pluginModuleName_.empty()) {
1630                 LoadPluginJsWithModule(urlName);
1631                 return;
1632             }
1633         }
1634 #endif
1635         if (isMainPage) {
1636             if (!ExecuteAbc("commons.abc")) {
1637                 return;
1638             }
1639             if (!ExecuteAbc("vendors.abc")) {
1640                 return;
1641             }
1642             std::string appMap;
1643             if (delegate->GetAssetContent("app.js.map", appMap)) {
1644                 page->SetAppMap(appMap);
1645             }
1646             if (ExecuteAbc("app.abc")) {
1647                 CallAppFunc("onCreate");
1648             }
1649         }
1650 #if !defined(PREVIEW)
1651         if (!ExecuteAbc(urlName)) {
1652             return;
1653         }
1654 #else
1655         if (!assetPath_.empty() && !isBundle_) {
1656             auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1657             arkRuntime->SetBundleName(bundleName_);
1658             arkRuntime->SetAssetPath(assetPath_);
1659             arkRuntime->SetBundle(isBundle_);
1660             arkRuntime->SetModuleName(moduleName_);
1661             std::vector<uint8_t> content;
1662             if (!delegate->GetAssetContent("modules.abc", content)) {
1663                 LOGW("GetAssetContent \"%{public}s\" failed.", urlName.c_str());
1664                 return;
1665             }
1666             if (!arkRuntime->ExecuteModuleBuffer(content.data(), content.size(), urlName)) {
1667                 LOGW("EvaluateJsCode \"%{public}s\" failed.", urlName.c_str());
1668                 return;
1669             }
1670         } else {
1671             ExecuteAbc(urlName);
1672         }
1673 #endif
1674     }
1675 }
1676 #if !defined(PREVIEW)
IsModule()1677 bool JsiDeclarativeEngine::IsModule()
1678 {
1679     auto container = Container::Current();
1680     CHECK_NULL_RETURN(container, false);
1681     return container->IsModule();
1682 }
1683 
LoadPluginJsWithModule(std::string & urlName)1684 void JsiDeclarativeEngine::LoadPluginJsWithModule(std::string& urlName)
1685 {
1686     auto runtime = std::static_pointer_cast<ArkJSRuntime>(engineInstance_->GetJsRuntime());
1687     auto delegate = engineInstance_->GetDelegate();
1688     auto pluginUrlName = OHMURL_START_TAG + pluginBundleName_ + "/" + pluginModuleName_ + "/ets/" + urlName;
1689     std::vector<uint8_t> content;
1690     if (!delegate->GetAssetContent("ets/modules.abc", content)) {
1691         return;
1692     }
1693     if (!runtime->ExecuteModuleBuffer(content.data(), content.size(), pluginUrlName, true)) {
1694         return;
1695     }
1696 }
1697 
LoadJsWithModule(std::string & urlName,const std::function<void (const std::string &,int32_t)> & errorCallback)1698 void JsiDeclarativeEngine::LoadJsWithModule(
1699     std::string& urlName, const std::function<void(const std::string&, int32_t)>& errorCallback)
1700 {
1701     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadJsWithModule Execute Page code : %s", urlName.c_str());
1702     auto container = Container::Current();
1703     CHECK_NULL_VOID(container);
1704     auto runtime = std::static_pointer_cast<ArkJSRuntime>(engineInstance_->GetJsRuntime());
1705     const std::string moduleName = container->GetModuleName();
1706     const std::string assetPath = ASSET_PATH_PREFIX + moduleName + "/" + FORM_ES_MODULE_PATH;
1707     runtime->SetAssetPath(assetPath);
1708     runtime->SetModuleName(moduleName);
1709     if (urlName.substr(0, strlen(BUNDLE_TAG)) != BUNDLE_TAG) {
1710         urlName = container->GetModuleName() + "/ets/" + urlName;
1711     }
1712     runtime->ExecuteJsBin(urlName, errorCallback);
1713 }
1714 #endif
1715 // Load the app.js file of the FA model in NG structure.
LoadFaAppSource()1716 bool JsiDeclarativeEngine::LoadFaAppSource()
1717 {
1718     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadFaAppSource");
1719     if (!ExecuteAbc("commons.abc") || !ExecuteAbc("vendors.abc") || !ExecuteAbc("app.abc")) {
1720         return false;
1721     }
1722     CallAppFunc("onCreate");
1723     return true;
1724 }
1725 
1726 // Load the js file of the page in NG structure..
LoadPageSource(const std::string & url,const std::function<void (const std::string &,int32_t)> & errorCallback)1727 bool JsiDeclarativeEngine::LoadPageSource(
1728     const std::string& url, const std::function<void(const std::string&, int32_t)>& errorCallback)
1729 {
1730     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadPageSource");
1731     ACE_DCHECK(engineInstance_);
1732     // get js bundle content
1733     const char jsExt[] = ".js";
1734     const char binExt[] = ".abc";
1735     std::optional<std::string> urlName;
1736     auto pos = url.rfind(jsExt);
1737     if (pos != std::string::npos && pos == url.length() - (sizeof(jsExt) - 1)) {
1738         urlName = url.substr(0, pos) + binExt;
1739     }
1740     if (!urlName.has_value()) {
1741         return false;
1742     }
1743 
1744 #if !defined(PREVIEW)
1745     if (IsModule()) {
1746         LoadJsWithModule(urlName.value(), errorCallback);
1747         return true;
1748     }
1749 #else
1750     auto runtime = engineInstance_->GetJsRuntime();
1751     auto delegate = engineInstance_->GetDelegate();
1752     if (!assetPath_.empty() && !isBundle_) {
1753         auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1754         arkRuntime->SetBundleName(bundleName_);
1755         arkRuntime->SetAssetPath(assetPath_);
1756         arkRuntime->SetBundle(isBundle_);
1757         arkRuntime->SetModuleName(moduleName_);
1758         std::vector<uint8_t> content;
1759         if (!delegate->GetAssetContent("modules.abc", content)) {
1760             return false;
1761         }
1762         if (!arkRuntime->ExecuteModuleBuffer(content.data(), content.size(), urlName.value())) {
1763             return false;
1764         }
1765         return true;
1766     }
1767 #endif
1768     return ExecuteAbc(urlName.value());
1769 }
1770 
LoadPageSource(const std::shared_ptr<std::vector<uint8_t>> & content,const std::function<void (const std::string &,int32_t)> & errorCallback,const std::string & contentName)1771 bool JsiDeclarativeEngine::LoadPageSource(
1772     const std::shared_ptr<std::vector<uint8_t>>& content,
1773     const std::function<void(const std::string&, int32_t)>& errorCallback,
1774     const std::string& contentName)
1775 {
1776     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadPageSource");
1777     LOGI("LoadJs by buffer");
1778     ACE_DCHECK(engineInstance_);
1779     auto container = Container::Current();
1780     CHECK_NULL_RETURN(container, false);
1781     auto runtime = engineInstance_->GetJsRuntime();
1782     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1783     if (!arkRuntime->EvaluateJsCode(content->data(), content->size(), contentName)) {
1784         return false;
1785     }
1786     return true;
1787 }
1788 
LoadNavDestinationSource(const std::string & bundleName,const std::string & moduleName,const std::string & pageSourceFile,bool isSingleton)1789 int32_t JsiDeclarativeEngine::LoadNavDestinationSource(const std::string& bundleName,
1790     const std::string& moduleName, const std::string& pageSourceFile, bool isSingleton)
1791 {
1792     auto runtime = engineInstance_->GetJsRuntime();
1793     CHECK_NULL_RETURN(runtime, false);
1794     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1795     return arkRuntime->LoadDestinationFile(bundleName, moduleName, pageSourceFile, isSingleton);
1796 }
1797 
AddToNamedRouterMap(const EcmaVM * vm,panda::Global<panda::FunctionRef> pageGenerator,const std::string & namedRoute,panda::Local<panda::ObjectRef> params)1798 void JsiDeclarativeEngine::AddToNamedRouterMap(const EcmaVM* vm, panda::Global<panda::FunctionRef> pageGenerator,
1799     const std::string& namedRoute, panda::Local<panda::ObjectRef> params)
1800 {
1801     std::string bundleName;
1802     std::string moduleName;
1803     std::string pagePath;
1804     std::string pageFullPath;
1805     std::string ohmUrl;
1806     if (!ParseNamedRouterParams(vm, params, bundleName, moduleName, pagePath, pageFullPath, ohmUrl)) {
1807         return;
1808     }
1809 
1810     TAG_LOGI(AceLogTag::ACE_ROUTER,
1811         "add named router record, name: %{public}s, bundleName: %{public}s, moduleName: %{public}s, "
1812         "pagePath: %{public}s, pageFullPath: %{public}s, ohmUrl: %{public}s",
1813         namedRoute.c_str(), bundleName.c_str(), moduleName.c_str(), pagePath.c_str(), pageFullPath.c_str(),
1814         ohmUrl.c_str());
1815     NamedRouterProperty namedRouterProperty({ pageGenerator, bundleName, moduleName, pagePath, ohmUrl });
1816     auto ret = namedRouterRegisterMap_.insert(std::make_pair(namedRoute, namedRouterProperty));
1817     if (!ret.second) {
1818         ret.first->second.pageGenerator.FreeGlobalHandleAddr();
1819         namedRouterRegisterMap_[namedRoute] = namedRouterProperty;
1820     }
1821     auto pagePathKey = moduleName + pagePath;
1822     auto pageRet = routerPathInfoMap_.insert(std::make_pair(pagePathKey, pageFullPath));
1823     if (!pageRet.second) {
1824         routerPathInfoMap_[pagePathKey] = pageFullPath;
1825     }
1826     if (!namedRoute.empty()) {
1827         auto ret = routerPathInfoMap_.insert(std::make_pair(namedRoute, pageFullPath));
1828         if (!ret.second) {
1829             routerPathInfoMap_[namedRoute] = pageFullPath;
1830         }
1831     }
1832 }
1833 
SearchRouterRegisterMap(const std::string & pageName)1834 std::string JsiDeclarativeEngine::SearchRouterRegisterMap(const std::string& pageName)
1835 {
1836     auto it = namedRouterRegisterMap_.find(pageName);
1837     if (it != namedRouterRegisterMap_.end()) {
1838         return it->second.moduleName;
1839     }
1840     return "";
1841 }
1842 
LoadNamedRouterSource(const std::string & namedRoute,bool isTriggeredByJs)1843 bool JsiDeclarativeEngine::LoadNamedRouterSource(const std::string& namedRoute, bool isTriggeredByJs)
1844 {
1845     CHECK_NULL_RETURN(!namedRouterRegisterMap_.empty(), false);
1846     auto iter = namedRouterRegisterMap_.find(namedRoute);
1847     if (isTriggeredByJs && iter == namedRouterRegisterMap_.end()) {
1848         LOGW("named route %{public}s not found!", namedRoute.c_str());
1849         return false;
1850     }
1851     // if this triggering is not from js named router api,
1852     // 'namedRoute' will be used as url to find the page in 'main_pages.json'
1853     if (!isTriggeredByJs) {
1854         std::string bundleName;
1855         std::string moduleName;
1856         std::string url = namedRoute;
1857 #if !defined(PREVIEW)
1858         if (namedRoute.substr(0, strlen(BUNDLE_TAG)) == BUNDLE_TAG) {
1859             size_t bundleEndPos = namedRoute.find('/');
1860             bundleName = namedRoute.substr(strlen(BUNDLE_TAG), bundleEndPos - strlen(BUNDLE_TAG));
1861             size_t moduleStartPos = bundleEndPos + 1;
1862             size_t moduleEndPos = namedRoute.find('/', moduleStartPos);
1863             moduleName = namedRoute.substr(moduleStartPos, moduleEndPos - moduleStartPos);
1864             url = namedRoute.substr(moduleEndPos + strlen("/ets/"));
1865         } else {
1866             bundleName = AceApplicationInfo::GetInstance().GetPackageName();
1867             auto container = Container::Current();
1868             CHECK_NULL_RETURN(container, false);
1869             moduleName = container->GetModuleName();
1870         }
1871 #else
1872         bundleName = bundleName_;
1873         moduleName = moduleName_;
1874 #endif
1875         // when need to locate page in main_pages.json, url shouldn't be empty
1876         if (url == "") {
1877             LOGW("page not found! bundleName: %{public}s, moduleName: %{public}s, url: %{public}s",
1878                 bundleName.c_str(), moduleName.c_str(), url.c_str());
1879             return false;
1880         }
1881         iter = std::find_if(namedRouterRegisterMap_.begin(), namedRouterRegisterMap_.end(),
1882             [&bundleName, &moduleName, &url](const auto& item) {
1883                 return item.second.bundleName == bundleName && item.second.moduleName == moduleName &&
1884                        item.second.pagePath == url;
1885             });
1886         if (iter == namedRouterRegisterMap_.end()) {
1887             LOGW("page not found! bundleName: %{public}s, moduleName: %{public}s, url: %{public}s",
1888                 bundleName.c_str(), moduleName.c_str(), url.c_str());
1889             return false;
1890         }
1891     }
1892 
1893     /**
1894      * The pageGenerator may be filled in two situations: one is when the developer explicitly imports it(
1895      * dynamic import in ets, eg: import("hsp"); ), and the other is when the PageRouterManager preload namedRoute
1896      * in Backup&Restore scenario.
1897      */
1898     if (iter->second.pageGenerator.IsEmpty()) {
1899         LOGE("Named router %{public}s has no PageGenerator", iter->first.c_str());
1900         return false;
1901     }
1902 
1903     CHECK_NULL_RETURN(engineInstance_, false);
1904     auto runtime = engineInstance_->GetJsRuntime();
1905     auto vm = const_cast<EcmaVM*>(std::static_pointer_cast<ArkJSRuntime>(runtime)->GetEcmaVm());
1906     std::vector<Local<JSValueRef>> argv;
1907     LocalScope scope(vm);
1908     JSViewStackProcessor::JsStartGetAccessRecordingFor(JSViewStackProcessor::JsAllocateNewElmetIdForNextComponent());
1909     auto ret = iter->second.pageGenerator->Call(vm, JSNApi::GetGlobalObject(vm), argv.data(), 0);
1910     if (!ret->IsObject(vm)) {
1911         return false;
1912     }
1913 #if defined(PREVIEW)
1914     panda::Global<panda::ObjectRef> rootView(vm, ret->ToObject(vm));
1915     shared_ptr<ArkJSRuntime> arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1916     arkRuntime->AddRootView(rootView);
1917 #endif
1918     Framework::UpdateRootComponent(vm, ret->ToObject(vm));
1919     JSViewStackProcessor::JsStopGetAccessRecording();
1920     return true;
1921 }
1922 
GetFullPathInfo()1923 std::unique_ptr<JsonValue> JsiDeclarativeEngine::GetFullPathInfo()
1924 {
1925     auto jsonFullPathInfo = JsonUtil::CreateArray(true);
1926     auto recordIter = routerPathInfoMap_.begin();
1927     while (recordIter != routerPathInfoMap_.end()) {
1928         auto jsonItem = JsonUtil::Create(true);
1929         jsonItem->Put("url", recordIter->first.c_str());
1930         jsonItem->Put("fullPathInfo", recordIter->second.c_str());
1931         jsonFullPathInfo->Put(jsonItem);
1932         ++recordIter;
1933     }
1934     return jsonFullPathInfo;
1935 }
1936 
RestoreFullPathInfo(std::unique_ptr<JsonValue> fullPathInfo)1937 void JsiDeclarativeEngine::RestoreFullPathInfo(std::unique_ptr<JsonValue> fullPathInfo)
1938 {
1939     std::unordered_map<std::string, std::string> routerPathInfoMap;
1940     if (!fullPathInfo || !fullPathInfo->IsValid() || !fullPathInfo->IsArray()) {
1941         LOGW("Invalid fullPathInfo");
1942         return;
1943     }
1944 
1945     NamedRouterProperty property;
1946     int32_t size = fullPathInfo->GetArraySize();
1947     for (int32_t i = 0; i < size; ++i) {
1948         auto item = fullPathInfo->GetArrayItem(i);
1949         if (!item) {
1950             LOGW("failed to get fullPathInfo item");
1951             continue;
1952         }
1953         auto urlJsonValue = item->GetValue("url");
1954         auto fullPathInfoJsonValue = item->GetValue("fullPathInfo");
1955         if (!urlJsonValue || !urlJsonValue->IsString() ||
1956             !fullPathInfoJsonValue || !fullPathInfoJsonValue->IsString()) {
1957             LOGW("Invalid fullPathInfo item");
1958             continue;
1959         }
1960 
1961         std::string url = urlJsonValue->GetString();
1962         std::string pathInfo = fullPathInfoJsonValue->GetString();
1963         routerPathInfoMap.emplace(url, pathInfo);
1964     }
1965 
1966     std::swap(routerPathInfoMap_, routerPathInfoMap);
1967 }
1968 
GetNamedRouterInfo()1969 std::unique_ptr<JsonValue> JsiDeclarativeEngine::GetNamedRouterInfo()
1970 {
1971     auto jsonNamedRouterInfo = JsonUtil::CreateArray(true);
1972     auto recordIter = namedRouterRegisterMap_.begin();
1973     while (recordIter != namedRouterRegisterMap_.end()) {
1974         auto jsonItem = JsonUtil::Create(true);
1975         jsonItem->Put("name", recordIter->first.c_str());
1976         const auto& property = recordIter->second;
1977         jsonItem->Put("bundleName", property.bundleName.c_str());
1978         jsonItem->Put("moduleName", property.moduleName.c_str());
1979         jsonItem->Put("pagePath", property.pagePath.c_str());
1980         jsonItem->Put("ohmUrl", property.ohmUrl.c_str());
1981         jsonNamedRouterInfo->Put(jsonItem);
1982         ++recordIter;
1983     }
1984     return jsonNamedRouterInfo;
1985 }
1986 
RestoreNamedRouterInfo(std::unique_ptr<JsonValue> namedRouterInfo)1987 void JsiDeclarativeEngine::RestoreNamedRouterInfo(std::unique_ptr<JsonValue> namedRouterInfo)
1988 {
1989     std::unordered_map<std::string, NamedRouterProperty> namedRouterMap;
1990     if (!namedRouterInfo || !namedRouterInfo->IsValid() || !namedRouterInfo->IsArray()) {
1991         LOGW("Invalid namedRouterInfo");
1992         return;
1993     }
1994 
1995     NamedRouterProperty property;
1996     int32_t size = namedRouterInfo->GetArraySize();
1997     for (int32_t i = 0; i < size; ++i) {
1998         auto item = namedRouterInfo->GetArrayItem(i);
1999         if (!item) {
2000             LOGW("failed to get namedRouterInfo item");
2001             continue;
2002         }
2003         auto nameJsonValue = item->GetValue("name");
2004         auto bundleNameJsonValue = item->GetValue("bundleName");
2005         auto moduleNameJsonValue = item->GetValue("moduleName");
2006         auto pagePathJsonValue = item->GetValue("pagePath");
2007         auto ohmUrlJsonValue = item->GetValue("ohmUrl");
2008         if (!nameJsonValue || !nameJsonValue->IsString() ||
2009             !bundleNameJsonValue || !bundleNameJsonValue->IsString() ||
2010             !moduleNameJsonValue || !moduleNameJsonValue->IsString() ||
2011             !pagePathJsonValue || !pagePathJsonValue->IsString() ||
2012             !ohmUrlJsonValue || !ohmUrlJsonValue->IsString()) {
2013             LOGW("Invalid NamedRouterInfo item");
2014             continue;
2015         }
2016 
2017         std::string name = nameJsonValue->GetString();
2018         property.bundleName = bundleNameJsonValue->GetString();
2019         property.moduleName = moduleNameJsonValue->GetString();
2020         property.pagePath = pagePathJsonValue->GetString();
2021         property.ohmUrl = ohmUrlJsonValue->GetString();
2022         namedRouterMap.emplace(name, property);
2023     }
2024 
2025     std::swap(namedRouterRegisterMap_, namedRouterMap);
2026 }
2027 
IsNamedRouterNeedPreload(const std::string & name)2028 bool JsiDeclarativeEngine::IsNamedRouterNeedPreload(const std::string& name)
2029 {
2030     auto it = namedRouterRegisterMap_.find(name);
2031     if (it == namedRouterRegisterMap_.end()) {
2032         return false;
2033     }
2034     return it->second.pageGenerator.IsEmpty();
2035 }
2036 
PreloadNamedRouter(const std::string & name,std::function<void (bool)> && loadFinishCallback)2037 void JsiDeclarativeEngine::PreloadNamedRouter(const std::string& name, std::function<void(bool)>&& loadFinishCallback)
2038 {
2039     if (!pageUrlCheckFunc_) {
2040         LOGW("JSEngine didn't set PageUrlCheckFunc");
2041         if (loadFinishCallback) {
2042             loadFinishCallback(false);
2043         }
2044         return;
2045     }
2046     auto it = namedRouterRegisterMap_.find(name);
2047     if (it == namedRouterRegisterMap_.end() || !it->second.pageGenerator.IsEmpty()) {
2048         if (loadFinishCallback) {
2049             loadFinishCallback(true);
2050         }
2051         return;
2052     }
2053     const auto& bundleName = it->second.bundleName;
2054     const auto& moduleName = it->second.moduleName;
2055     const auto& pagePath = it->second.pagePath;
2056     std::string ohmUrl = it->second.ohmUrl + ".js";
2057     TAG_LOGI(AceLogTag::ACE_ROUTER, "preload named rotuer, bundleName:"
2058         "%{public}s, moduleName: %{public}s, pagePath: %{public}s, ohmUrl: %{public}s",
2059         bundleName.c_str(), moduleName.c_str(), pagePath.c_str(), ohmUrl.c_str());
2060 
2061     auto callback = [weak = AceType::WeakClaim(this), ohmUrl, finishCallback = loadFinishCallback]() {
2062         auto jsEngine = weak.Upgrade();
2063         CHECK_NULL_VOID(jsEngine);
2064         bool loadSuccess = true;
2065         jsEngine->LoadPageSource(ohmUrl, [ohmUrl, &loadSuccess](const std::string& errorMsg, int32_t errorCode) {
2066             TAG_LOGW(AceLogTag::ACE_ROUTER,
2067                 "Failed to load page source: %{public}s, errorCode: %{public}d, errorMsg: %{public}s", ohmUrl.c_str(),
2068                 errorCode, errorMsg.c_str());
2069             loadSuccess = false;
2070         });
2071         if (finishCallback) {
2072             finishCallback(loadSuccess);
2073         }
2074     };
2075     auto silentInstallErrorCallBack = [finishCallback = loadFinishCallback](
2076                                           int32_t errorCode, const std::string& errorMsg) {
2077         TAG_LOGW(AceLogTag::ACE_ROUTER, "Failed to preload named router, error = %{public}d, errorMsg = %{public}s",
2078             errorCode, errorMsg.c_str());
2079         if (finishCallback) {
2080             finishCallback(false);
2081         }
2082     };
2083     pageUrlCheckFunc_(ohmUrl, callback, silentInstallErrorCallBack);
2084 }
2085 
LoadCard(const std::string & url,int64_t cardId,const std::string & entryPoint)2086 bool JsiDeclarativeEngine::LoadCard(const std::string& url, int64_t cardId, const std::string& entryPoint)
2087 {
2088     ACE_SCOPED_TRACE("JsiDeclarativeEngine::LoadCard");
2089     auto container = Container::Current();
2090     CHECK_NULL_RETURN(container, false);
2091     return container->IsDynamicRender() ? ExecuteDynamicAbc(url, entryPoint) : ExecuteCardAbc(url, cardId);
2092 }
2093 
2094 #if defined(PREVIEW)
ReplaceJSContent(const std::string & url,const std::string componentName)2095 void JsiDeclarativeEngine::ReplaceJSContent(const std::string& url, const std::string componentName)
2096 {
2097     ACE_DCHECK(engineInstance_);
2098     if (engineInstance_ == nullptr) {
2099         return;
2100     }
2101     auto runtime = engineInstance_->GetJsRuntime();
2102     std::static_pointer_cast<ArkJSRuntime>(runtime)->SetPreviewFlag(true);
2103     std::static_pointer_cast<ArkJSRuntime>(runtime)->SetRequiredComponent(componentName);
2104     engineInstance_->GetDelegate()->Replace(url, "");
2105 }
2106 
GetNewComponentWithJsCode(const std::string & jsCode,const std::string & viewID)2107 RefPtr<Component> JsiDeclarativeEngine::GetNewComponentWithJsCode(const std::string& jsCode, const std::string& viewID)
2108 {
2109     std::string dest;
2110     if (!Base64Util::Decode(jsCode, dest)) {
2111         return nullptr;
2112     }
2113 
2114     ViewStackProcessor::GetInstance()->ClearStack();
2115     ViewStackProcessor::GetInstance()->PushKey(viewID);
2116     bool result = engineInstance_->InitAceModule((uint8_t*)dest.data(), dest.size());
2117     ViewStackProcessor::GetInstance()->PopKey();
2118     if (!result) {
2119         return nullptr;
2120     }
2121     auto component = ViewStackProcessor::GetInstance()->GetNewComponent();
2122     return component;
2123 }
2124 
ExecuteJsForFastPreview(const std::string & jsCode,const std::string & viewID)2125 bool JsiDeclarativeEngine::ExecuteJsForFastPreview(const std::string& jsCode, const std::string& viewID)
2126 {
2127     std::string dest;
2128     if (!Base64Util::Decode(jsCode, dest)) {
2129         return false;
2130     }
2131     NG::ViewStackProcessor::GetInstance()->ClearStack();
2132     NG::ViewStackProcessor::GetInstance()->PushKey(viewID);
2133     bool result = engineInstance_->InitAceModule((uint8_t*)dest.data(), dest.size());
2134     NG::ViewStackProcessor::GetInstance()->PopKey();
2135     return result;
2136 }
2137 
SetHspBufferTrackerCallback(std::function<bool (const std::string &,uint8_t **,size_t *,std::string &)> && callback)2138 void JsiDeclarativeEngine::SetHspBufferTrackerCallback(
2139     std::function<bool(const std::string&, uint8_t**, size_t*, std::string&)>&& callback)
2140 {
2141     CHECK_NULL_VOID(engineInstance_);
2142     auto runtime = std::static_pointer_cast<ArkJSRuntime>(engineInstance_->GetJsRuntime());
2143     CHECK_NULL_VOID(runtime);
2144     auto vm = const_cast<EcmaVM*>(runtime->GetEcmaVm());
2145     panda::JSNApi::SetHostResolveBufferTracker(vm, std::move(callback));
2146 }
2147 
SetMockModuleList(const std::map<std::string,std::string> & mockJsonInfo)2148 void JsiDeclarativeEngine::SetMockModuleList(const std::map<std::string, std::string>& mockJsonInfo)
2149 {
2150     CHECK_NULL_VOID(engineInstance_);
2151     auto runtime = std::static_pointer_cast<ArkJSRuntime>(engineInstance_->GetJsRuntime());
2152     CHECK_NULL_VOID(runtime);
2153     auto vm = const_cast<EcmaVM*>(runtime->GetEcmaVm());
2154     panda::JSNApi::SetMockModuleList(vm, mockJsonInfo);
2155 }
2156 
IsComponentPreview()2157 bool JsiDeclarativeEngine::IsComponentPreview()
2158 {
2159     auto runtime = engineInstance_->GetJsRuntime();
2160     CHECK_NULL_RETURN(runtime, false);
2161     shared_ptr<ArkJSRuntime> arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
2162     CHECK_NULL_RETURN(arkRuntime, false);
2163     return arkRuntime->GetPreviewFlag();
2164 }
2165 #endif
2166 
UpdateRunningPage(const RefPtr<JsAcePage> & page)2167 void JsiDeclarativeEngine::UpdateRunningPage(const RefPtr<JsAcePage>& page)
2168 {
2169     ACE_DCHECK(engineInstance_);
2170     engineInstance_->SetRunningPage(page);
2171 }
2172 
UpdateStagingPage(const RefPtr<JsAcePage> & page)2173 void JsiDeclarativeEngine::UpdateStagingPage(const RefPtr<JsAcePage>& page)
2174 {
2175     ACE_DCHECK(engineInstance_);
2176     engineInstance_->SetStagingPage(page);
2177 }
2178 
ResetStagingPage()2179 void JsiDeclarativeEngine::ResetStagingPage()
2180 {
2181     ACE_DCHECK(engineInstance_);
2182     auto runningPage = engineInstance_->GetRunningPage();
2183     engineInstance_->ResetStagingPage(runningPage);
2184 }
2185 
SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher> & dispatcher)2186 void JsiDeclarativeEngine::SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher)
2187 {
2188     ACE_DCHECK(engineInstance_);
2189     engineInstance_->SetJsMessageDispatcher(dispatcher);
2190 }
2191 
FireAsyncEvent(const std::string & eventId,const std::string & param)2192 void JsiDeclarativeEngine::FireAsyncEvent(const std::string& eventId, const std::string& param)
2193 {
2194     std::string callBuf = std::string("[{\"args\": [\"")
2195                               .append(eventId)
2196                               .append("\",")
2197                               .append(param)
2198                               .append("], \"method\":\"fireEvent\"}]");
2199 
2200     ACE_DCHECK(engineInstance_);
2201     engineInstance_->FireJsEvent(callBuf.c_str());
2202 }
2203 
FireSyncEvent(const std::string & eventId,const std::string & param)2204 void JsiDeclarativeEngine::FireSyncEvent(const std::string& eventId, const std::string& param)
2205 {
2206     std::string callBuf = std::string("[{\"args\": [\"")
2207                               .append(eventId)
2208                               .append("\",")
2209                               .append(param)
2210                               .append("], \"method\":\"fireEventSync\"}]");
2211 
2212     ACE_DCHECK(engineInstance_);
2213     engineInstance_->FireJsEvent(callBuf.c_str());
2214 }
2215 
InitXComponent(const std::string & componentId)2216 void JsiDeclarativeEngine::InitXComponent(const std::string& componentId)
2217 {
2218     ACE_DCHECK(engineInstance_);
2219     std::tie(nativeXComponentImpl_, nativeXComponent_) =
2220         XComponentClient::GetInstance().GetNativeXComponentFromXcomponentsMap(componentId);
2221 }
2222 
FireExternalEvent(const std::string & componentId,const uint32_t nodeId,const bool isDestroy)2223 void JsiDeclarativeEngine::FireExternalEvent(
2224     const std::string& componentId, const uint32_t nodeId, const bool isDestroy)
2225 {
2226     CHECK_RUN_ON(JS);
2227 
2228     if (Container::IsCurrentUseNewPipeline()) {
2229         ACE_DCHECK(engineInstance_);
2230         auto xcFrameNode = NG::FrameNode::GetFrameNode(V2::XCOMPONENT_ETS_TAG, static_cast<int32_t>(nodeId));
2231         if (!xcFrameNode) {
2232             return;
2233         }
2234         auto xcPattern = DynamicCast<NG::XComponentPattern>(xcFrameNode->GetPattern());
2235         CHECK_NULL_VOID(xcPattern);
2236         CHECK_EQUAL_VOID(xcPattern->GetLibraryName().has_value(), false);
2237         std::weak_ptr<OH_NativeXComponent> weakNativeXComponent;
2238         RefPtr<OHOS::Ace::NativeXComponentImpl> nativeXComponentImpl = nullptr;
2239         std::tie(nativeXComponentImpl, weakNativeXComponent) = xcPattern->GetNativeXComponent();
2240         auto nativeXComponent = weakNativeXComponent.lock();
2241         CHECK_NULL_VOID(nativeXComponent);
2242         CHECK_NULL_VOID(nativeXComponentImpl);
2243 
2244         nativeXComponentImpl->SetXComponentId(componentId);
2245 #ifdef XCOMPONENT_SUPPORTED
2246         xcPattern->SetExpectedRateRangeInit();
2247         xcPattern->OnFrameEventInit();
2248         xcPattern->UnregisterOnFrameEventInit();
2249 #endif
2250         auto* arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine_);
2251         if (arkNativeEngine == nullptr) {
2252             return;
2253         }
2254 
2255         napi_handle_scope handleScope;
2256         napi_status status = napi_open_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), &handleScope);
2257         if (status != napi_ok) {
2258             return;
2259         }
2260 
2261         std::string arguments;
2262         auto soPath = xcPattern->GetSoPath().value_or("");
2263         auto runtime = engineInstance_->GetJsRuntime();
2264         shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
2265         LocalScope scope(pandaRuntime->GetEcmaVm());
2266         auto objXComp = arkNativeEngine->LoadModuleByName(xcPattern->GetLibraryName().value(), true, arguments,
2267             OH_NATIVE_XCOMPONENT_OBJ, reinterpret_cast<void*>(nativeXComponent.get()), soPath);
2268         if (objXComp.IsEmpty() || pandaRuntime->HasPendingException()) {
2269             napi_close_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), handleScope);
2270             return;
2271         }
2272         auto objContext = JsiObject(objXComp);
2273         JSRef<JSObject> obj = JSRef<JSObject>::Make(objContext);
2274         OHOS::Ace::Framework::XComponentClient::GetInstance().AddJsValToJsValMap(componentId, obj);
2275         napi_close_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), handleScope);
2276 
2277         auto type = xcPattern->GetType();
2278         if (type == XComponentType::SURFACE || type == XComponentType::TEXTURE) {
2279             auto task = [weak = WeakClaim(this), weakPattern = AceType::WeakClaim(AceType::RawPtr(xcPattern))]() {
2280                 auto pattern = weakPattern.Upgrade();
2281                 if (!pattern) {
2282                     return;
2283                 }
2284                 auto bridge = weak.Upgrade();
2285                 if (bridge) {
2286 #ifdef XCOMPONENT_SUPPORTED
2287                     pattern->NativeXComponentInit();
2288 #endif
2289                 }
2290             };
2291 
2292             auto delegate = engineInstance_->GetDelegate();
2293             if (!delegate) {
2294                 return;
2295             }
2296             delegate->PostSyncTaskToPage(task, "ArkUINativeXComponentInit");
2297         }
2298         return;
2299     }
2300 #ifndef NG_BUILD
2301     if (isDestroy) {
2302         XComponentComponentClient::GetInstance().DeleteFromXcomponentsMapById(componentId);
2303         XComponentClient::GetInstance().DeleteControllerFromJSXComponentControllersMap(componentId);
2304         XComponentClient::GetInstance().DeleteFromNativeXcomponentsMapById(componentId);
2305         XComponentClient::GetInstance().DeleteFromJsValMapById(componentId);
2306         return;
2307     }
2308     InitXComponent(componentId);
2309     RefPtr<XComponentComponent> xcomponent =
2310         XComponentComponentClient::GetInstance().GetXComponentFromXcomponentsMap(componentId);
2311     if (!xcomponent) {
2312         return;
2313     }
2314 
2315     void* nativeWindow = nullptr;
2316 #ifdef OHOS_STANDARD_SYSTEM
2317     nativeWindow = const_cast<void*>(xcomponent->GetNativeWindow());
2318 #else
2319     auto container = Container::Current();
2320     if (!container) {
2321         return;
2322     }
2323     auto nativeView = container->GetAceView();
2324     if (!nativeView) {
2325         return;
2326     }
2327     auto textureId = static_cast<int64_t>(xcomponent->GetTextureId());
2328     nativeWindow = const_cast<void*>(nativeView->GetNativeWindowById(textureId));
2329 #endif
2330 
2331     if (!nativeWindow) {
2332         return;
2333     }
2334     nativeXComponentImpl_->SetSurface(nativeWindow);
2335     nativeXComponentImpl_->SetXComponentId(xcomponent->GetId());
2336 
2337     auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine_);
2338     if (arkNativeEngine == nullptr) {
2339         return;
2340     }
2341 
2342     napi_handle_scope handleScope;
2343     napi_status status = napi_open_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), &handleScope);
2344     if (status != napi_ok) {
2345         return;
2346     }
2347     std::string arguments;
2348     auto soPath = xcomponent->GetSoPath().value_or("");
2349     auto runtime = engineInstance_->GetJsRuntime();
2350     shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
2351     LocalScope scope(pandaRuntime->GetEcmaVm());
2352     auto objXComp = arkNativeEngine->LoadModuleByName(xcomponent->GetLibraryName(), true, arguments,
2353         OH_NATIVE_XCOMPONENT_OBJ, reinterpret_cast<void*>(nativeXComponent_), soPath);
2354     if (objXComp.IsEmpty() || pandaRuntime->HasPendingException()) {
2355         napi_close_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), handleScope);
2356         return;
2357     }
2358 
2359     auto objContext = JsiObject(objXComp);
2360     JSRef<JSObject> obj = JSRef<JSObject>::Make(objContext);
2361     XComponentClient::GetInstance().AddJsValToJsValMap(componentId, obj);
2362     napi_close_handle_scope(reinterpret_cast<napi_env>(nativeEngine_), handleScope);
2363 
2364     auto task = [weak = WeakClaim(this), xcomponent]() {
2365         auto pool = xcomponent->GetTaskPool();
2366         if (!pool) {
2367             return;
2368         }
2369         auto bridge = weak.Upgrade();
2370         if (bridge) {
2371 #ifdef XCOMPONENT_SUPPORTED
2372             pool->NativeXComponentInit(
2373                 bridge->nativeXComponent_, AceType::WeakClaim(AceType::RawPtr(bridge->nativeXComponentImpl_)));
2374 #endif
2375         }
2376     };
2377 
2378     auto delegate = engineInstance_->GetDelegate();
2379     if (!delegate) {
2380         return;
2381     }
2382     delegate->PostSyncTaskToPage(task, "ArkUINativeXComponentInit");
2383 #endif
2384 }
2385 
TimerCallback(const std::string & callbackId,const std::string & delay,bool isInterval)2386 void JsiDeclarativeEngine::TimerCallback(const std::string& callbackId, const std::string& delay, bool isInterval)
2387 {
2388     TimerCallJs(callbackId);
2389     auto runtime = JsiDeclarativeEngineInstance::GetCurrentRuntime();
2390     if (!runtime) {
2391         return;
2392     }
2393     auto instance = static_cast<JsiDeclarativeEngineInstance*>(runtime->GetEmbedderData());
2394     if (instance == nullptr) {
2395         return;
2396     }
2397     auto delegate = instance->GetDelegate();
2398     if (!delegate) {
2399         return;
2400     }
2401 
2402     if (isInterval) {
2403         delegate->WaitTimer(callbackId, delay, isInterval, false);
2404     } else {
2405         JsiTimerModule::GetInstance()->RemoveCallBack(StringUtils::StringToInt(callbackId));
2406         delegate->ClearTimer(callbackId);
2407     }
2408 }
2409 
TimerCallJs(const std::string & callbackId) const2410 void JsiDeclarativeEngine::TimerCallJs(const std::string& callbackId) const
2411 {
2412     shared_ptr<JsValue> func;
2413     std::vector<shared_ptr<JsValue>> params;
2414     if (!JsiTimerModule::GetInstance()->GetCallBack(StringUtils::StringToInt(callbackId), func, params)) {
2415         return;
2416     }
2417     auto runtime = JsiDeclarativeEngineInstance::GetCurrentRuntime();
2418     if (func) {
2419         func->Call(runtime, runtime->GetGlobal(), params, params.size());
2420     }
2421 }
2422 
DestroyPageInstance(int32_t pageId)2423 void JsiDeclarativeEngine::DestroyPageInstance(int32_t pageId)
2424 {
2425     ACE_DCHECK(engineInstance_);
2426 
2427     engineInstance_->DestroyRootViewHandle(pageId);
2428 }
2429 
DestroyApplication(const std::string & packageName)2430 void JsiDeclarativeEngine::DestroyApplication(const std::string& packageName)
2431 {
2432     if (engineInstance_) {
2433         shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2434         CallAppFunc("onDestroy");
2435     }
2436 }
2437 
UpdateApplicationState(const std::string & packageName,Frontend::State state)2438 void JsiDeclarativeEngine::UpdateApplicationState(const std::string& packageName, Frontend::State state)
2439 {
2440     LOGI("Update application state %{public}s, state: %{public}s", packageName.c_str(),
2441         Frontend::stateToString(state).c_str());
2442     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2443     if (!runtime) {
2444         return;
2445     }
2446     switch (state) {
2447         case Frontend::State::ON_SHOW:
2448             if (isFirstCallShow_) {
2449                 isFirstCallShow_ = false;
2450                 break;
2451             }
2452             CallAppFunc("onShow");
2453             break;
2454         case Frontend::State::ON_HIDE:
2455             CallAppFunc("onHide");
2456             break;
2457         case Frontend::State::ON_ACTIVE:
2458             CallAppFunc("onActive");
2459             break;
2460         case Frontend::State::ON_INACTIVE:
2461             CallAppFunc("onInactive");
2462             break;
2463         case Frontend::State::ON_DESTROY:
2464             CallAppFunc("onDestroy");
2465             break;
2466         default:
2467             return;
2468     }
2469 }
2470 
OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)2471 void JsiDeclarativeEngine::OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data)
2472 {
2473     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2474     std::vector<shared_ptr<JsValue>> argv = { runtime->NewBoolean(isShownInMultiWindow), runtime->NewString(data) };
2475     CallAppFunc("onWindowDisplayModeChanged", argv);
2476 }
2477 
CallAppFunc(const std::string & appFuncName)2478 bool JsiDeclarativeEngine::CallAppFunc(const std::string& appFuncName)
2479 {
2480     std::vector<shared_ptr<JsValue>> argv = {};
2481     return CallAppFunc(appFuncName, argv);
2482 }
2483 
CallAppFunc(const std::string & appFuncName,std::vector<shared_ptr<JsValue>> & argv)2484 bool JsiDeclarativeEngine::CallAppFunc(const std::string& appFuncName, std::vector<shared_ptr<JsValue>>& argv)
2485 {
2486     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2487     ACE_DCHECK(runtime);
2488     shared_ptr<JsValue> global = runtime->GetGlobal();
2489     shared_ptr<JsValue> exportsObject = global->GetProperty(runtime, "exports");
2490     if (!exportsObject->IsObject(runtime)) {
2491         return false;
2492     }
2493     shared_ptr<JsValue> defaultObject = exportsObject->GetProperty(runtime, "default");
2494     if (!defaultObject->IsObject(runtime)) {
2495         return false;
2496     }
2497     shared_ptr<JsValue> func = defaultObject->GetProperty(runtime, appFuncName);
2498     if (!func || !func->IsFunction(runtime)) {
2499         return false;
2500     }
2501     shared_ptr<JsValue> result;
2502     result = func->Call(runtime, defaultObject, argv, argv.size());
2503     return (result->ToString(runtime) == "true");
2504 }
2505 
MediaQueryCallback(const std::string & callbackId,const std::string & args)2506 void JsiDeclarativeEngine::MediaQueryCallback(const std::string& callbackId, const std::string& args)
2507 {
2508     JsEngine::MediaQueryCallback(callbackId, args);
2509 }
2510 
RequestAnimationCallback(const std::string & callbackId,uint64_t timeStamp)2511 void JsiDeclarativeEngine::RequestAnimationCallback(const std::string& callbackId, uint64_t timeStamp) {}
2512 
JsCallback(const std::string & callbackId,const std::string & args)2513 void JsiDeclarativeEngine::JsCallback(const std::string& callbackId, const std::string& args) {}
2514 
RunGarbageCollection()2515 void JsiDeclarativeEngine::RunGarbageCollection()
2516 {
2517     if (engineInstance_ && engineInstance_->GetJsRuntime()) {
2518         engineInstance_->GetJsRuntime()->RunGC();
2519     }
2520 }
2521 
RunFullGarbageCollection()2522 void JsiDeclarativeEngine::RunFullGarbageCollection()
2523 {
2524     if (engineInstance_ && engineInstance_->GetJsRuntime()) {
2525         engineInstance_->GetJsRuntime()->RunFullGC();
2526     }
2527 }
2528 
DumpHeapSnapshot(bool isPrivate)2529 void JsiDeclarativeEngine::DumpHeapSnapshot(bool isPrivate)
2530 {
2531     if (engineInstance_ && engineInstance_->GetJsRuntime()) {
2532         engineInstance_->GetJsRuntime()->DumpHeapSnapshot(isPrivate);
2533     }
2534 }
2535 
NotifyUIIdle()2536 void JsiDeclarativeEngine::NotifyUIIdle()
2537 {
2538     if (engineInstance_ && engineInstance_->GetJsRuntime()) {
2539         engineInstance_->GetJsRuntime()->NotifyUIIdle();
2540     }
2541 }
2542 
GetStacktraceMessage()2543 std::string JsiDeclarativeEngine::GetStacktraceMessage()
2544 {
2545     auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine_);
2546     if (!arkNativeEngine) {
2547         return "";
2548     }
2549     std::string stack;
2550     arkNativeEngine->SuspendVM();
2551     bool getStackSuccess = arkNativeEngine->BuildJsStackTrace(stack);
2552     arkNativeEngine->ResumeVM();
2553     if (!getStackSuccess) {
2554         return "JS stacktrace is empty";
2555     }
2556 
2557     auto runningPage = engineInstance_ ? engineInstance_->GetRunningPage() : nullptr;
2558     return JsiBaseUtils::TransSourceStack(runningPage, stack);
2559 }
2560 
GetStackTrace(std::string & trace)2561 void JsiDeclarativeEngine::GetStackTrace(std::string& trace)
2562 {
2563     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
2564     if (!arkRuntime) {
2565         return;
2566     }
2567     auto vm = arkRuntime->GetEcmaVm();
2568     if (!vm) {
2569         return;
2570     }
2571     panda::DFXJSNApi::BuildJsStackTrace(vm, trace);
2572 }
2573 
GetPagePath(const std::string & url)2574 std::string JsiDeclarativeEngine::GetPagePath(const std::string& url)
2575 {
2576     auto iter = namedRouterRegisterMap_.find(url);
2577     if (iter != namedRouterRegisterMap_.end()) {
2578         return iter->second.pagePath;
2579     }
2580     return "";
2581 }
2582 
ResetNamedRouterRegisterMap()2583 void JsiDeclarativeEngine::ResetNamedRouterRegisterMap()
2584 {
2585     namedRouterRegisterMap_.clear();
2586 }
2587 
GetFullPathInfo(const std::string & url)2588 std::string JsiDeclarativeEngine::GetFullPathInfo(const std::string& url)
2589 {
2590     auto iter = routerPathInfoMap_.find(url);
2591     if (iter != routerPathInfoMap_.end()) {
2592         return iter->second;
2593     }
2594     return "";
2595 }
2596 
GetRouteNameByUrl(const std::string & url,const std::string & bundleName,const std::string & moduleName)2597 std::optional<std::string> JsiDeclarativeEngine::GetRouteNameByUrl(
2598     const std::string& url, const std::string& bundleName, const std::string& moduleName)
2599 {
2600     auto iter = std::find_if(namedRouterRegisterMap_.begin(), namedRouterRegisterMap_.end(),
2601         [&bundleName, &moduleName, &url](const auto& item) {
2602             return item.second.bundleName == bundleName && item.second.moduleName == moduleName &&
2603                     item.second.pagePath == url;
2604         });
2605     if (iter != namedRouterRegisterMap_.end()) {
2606         return iter->first;
2607     }
2608     return std::nullopt;
2609 }
2610 
SetLocalStorage(int32_t instanceId,NativeReference * nativeValue)2611 void JsiDeclarativeEngine::SetLocalStorage(int32_t instanceId, NativeReference* nativeValue)
2612 {
2613 #ifdef USE_ARK_ENGINE
2614     auto jsValue = JsConverter::ConvertNapiValueToJsVal(nativeValue->GetNapiValue());
2615     if (jsValue->IsObject()) {
2616         auto storage = JSRef<JSObject>::Cast(jsValue);
2617         JSLocalStorage::AddStorage(instanceId, storage);
2618     }
2619     delete nativeValue;
2620     nativeValue = nullptr;
2621 #endif
2622 }
2623 
GetJsContext()2624 std::shared_ptr<Framework::JsValue> JsiDeclarativeEngine::GetJsContext()
2625 {
2626     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(
2627         JsiDeclarativeEngineInstance::GetCurrentRuntime());
2628     if (!arkRuntime || !arkRuntime->GetEcmaVm()) {
2629         LOGW("arkRuntime or vm is null.");
2630         return nullptr;
2631     }
2632 
2633     return JsiContextModule::GetContext(arkRuntime, nullptr, {}, 0);
2634 }
2635 
SetJsContext(const std::shared_ptr<Framework::JsValue> & jsContext)2636 void JsiDeclarativeEngine::SetJsContext(const std::shared_ptr<Framework::JsValue>& jsContext)
2637 {
2638     JsiContextModule::AddContext(instanceId_, jsContext);
2639 }
2640 
SetContext(int32_t instanceId,NativeReference * nativeValue)2641 void JsiDeclarativeEngine::SetContext(int32_t instanceId, NativeReference* nativeValue)
2642 {
2643 #ifdef USE_ARK_ENGINE
2644     napi_handle_scope scope;
2645     napi_status status = napi_open_handle_scope(reinterpret_cast<napi_env>(GetNativeEngine()), &scope);
2646     if (status != napi_ok) {
2647         return;
2648     }
2649     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime());
2650     if (!arkRuntime || !arkRuntime->GetEcmaVm()) {
2651         napi_close_handle_scope(reinterpret_cast<napi_env>(GetNativeEngine()), scope);
2652         return;
2653     }
2654     JAVASCRIPT_EXECUTION_SCOPE_STATIC;
2655     auto localRef = NapiValueToLocalValue(nativeValue->GetNapiValue());
2656     std::shared_ptr<JsValue> jsValue = std::make_shared<ArkJSValue>(arkRuntime, localRef);
2657     if (jsValue->IsObject(arkRuntime)) {
2658         JsiContextModule::AddContext(instanceId_, jsValue);
2659     }
2660     napi_close_handle_scope(reinterpret_cast<napi_env>(GetNativeEngine()), scope);
2661 #endif
2662 }
2663 
GetGroupJsBridge()2664 RefPtr<GroupJsBridge> JsiDeclarativeEngine::GetGroupJsBridge()
2665 {
2666     return AceType::MakeRefPtr<JsiDeclarativeGroupJsBridge>();
2667 }
2668 
OnActive()2669 void JsiDeclarativeEngine::OnActive()
2670 {
2671     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2672     if (!runtime) {
2673         return;
2674     }
2675     CallAppFunc("onActive");
2676 }
2677 
OnInactive()2678 void JsiDeclarativeEngine::OnInactive()
2679 {
2680     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2681     if (!runtime) {
2682         return;
2683     }
2684     CallAppFunc("onInactive");
2685 }
2686 
OnNewWant(const std::string & data)2687 void JsiDeclarativeEngine::OnNewWant(const std::string& data)
2688 {
2689     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2690     if (!runtime) {
2691         return;
2692     }
2693 
2694     shared_ptr<JsValue> object = runtime->ParseJson(data);
2695     std::vector<shared_ptr<JsValue>> argv = { object };
2696     CallAppFunc("onNewWant", argv);
2697 }
2698 
OnStartContinuation()2699 bool JsiDeclarativeEngine::OnStartContinuation()
2700 {
2701     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2702     if (!runtime) {
2703         return false;
2704     }
2705 
2706     return CallAppFunc("onStartContinuation");
2707 }
2708 
OnCompleteContinuation(int32_t code)2709 void JsiDeclarativeEngine::OnCompleteContinuation(int32_t code)
2710 {
2711     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2712     if (!runtime) {
2713         return;
2714     }
2715 
2716     std::vector<shared_ptr<JsValue>> argv = { runtime->NewNumber(code) };
2717     CallAppFunc("onCompleteContinuation", argv);
2718 }
2719 
OnRemoteTerminated()2720 void JsiDeclarativeEngine::OnRemoteTerminated()
2721 {
2722     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2723     if (!runtime) {
2724         return;
2725     }
2726 
2727     CallAppFunc("onRemoteTerminated");
2728 }
2729 
OnSaveData(std::string & data)2730 void JsiDeclarativeEngine::OnSaveData(std::string& data)
2731 {
2732     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2733     if (!runtime) {
2734         return;
2735     }
2736 
2737     shared_ptr<JsValue> object = runtime->NewObject();
2738     std::vector<shared_ptr<JsValue>> argv = { object };
2739     if (CallAppFunc("onSaveData", argv)) {
2740         data = object->GetJsonString(runtime);
2741     }
2742 }
2743 
SetErrorEventHandler(std::function<void (const std::string &,const std::string &)> && errorCallback)2744 void JsiDeclarativeEngine::SetErrorEventHandler(
2745     std::function<void(const std::string&, const std::string&)>&& errorCallback)
2746 {
2747     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2748     if (!runtime) {
2749         return;
2750     }
2751 
2752     runtime->SetErrorEventHandler(std::move(errorCallback));
2753 }
2754 
OnRestoreData(const std::string & data)2755 bool JsiDeclarativeEngine::OnRestoreData(const std::string& data)
2756 {
2757     shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
2758     if (!runtime) {
2759         return false;
2760     }
2761     shared_ptr<JsValue> result;
2762     shared_ptr<JsValue> jsonObj = runtime->ParseJson(data);
2763     if (jsonObj->IsUndefined(runtime) || jsonObj->IsException(runtime)) {
2764         return false;
2765     }
2766     std::vector<shared_ptr<JsValue>> argv = { jsonObj };
2767     return CallAppFunc("onRestoreData", argv);
2768 }
2769 
AddToNavigationBuilderMap(std::string name,panda::Global<panda::ObjectRef> builderFunc)2770 void JsiDeclarativeEngine::AddToNavigationBuilderMap(std::string name,
2771     panda::Global<panda::ObjectRef> builderFunc)
2772 {
2773     auto ret = builderMap_.insert(std::pair<std::string, panda::Global<panda::ObjectRef>>(name, builderFunc));
2774     if (!ret.second) {
2775         TAG_LOGW(AceLogTag::ACE_NAVIGATION, "insert builder failed, update builder: %{public}s", name.c_str());
2776         builderMap_[name] = builderFunc;
2777     }
2778 }
2779 
GetNavigationBuilder(std::string name)2780 panda::Global<panda::ObjectRef> JsiDeclarativeEngine::GetNavigationBuilder(std::string name)
2781 {
2782     auto targetBuilder = builderMap_.find(name);
2783     if (targetBuilder == builderMap_.end()) {
2784         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "get navDestination builder failed: %{public}s", name.c_str());
2785         return panda::Global<panda::ObjectRef>();
2786     }
2787     return targetBuilder->second;
2788 }
2789 
JsStateProfilerResgiter()2790 void JsiDeclarativeEngine::JsStateProfilerResgiter()
2791 {
2792 #if defined(PREVIEW)
2793     return;
2794 #else
2795     CHECK_NULL_VOID(runtime_);
2796     auto engine = reinterpret_cast<NativeEngine*>(runtime_);
2797     CHECK_NULL_VOID(engine);
2798     auto vm = engine->GetEcmaVm();
2799     CHECK_NULL_VOID(vm);
2800     auto globalObj = JSNApi::GetGlobalObject(vm);
2801     const auto globalObject = JSRef<JSObject>::Make(globalObj);
2802 
2803     const JSRef<JSVal> setProfilerStatus = globalObject->GetProperty("setProfilerStatus");
2804     if (!setProfilerStatus->IsFunction()) {
2805         return;
2806     }
2807 
2808     const auto globalFunc = JSRef<JSFunc>::Cast(setProfilerStatus);
2809     std::function<void(bool)> callback = [globalFunc, globalObject, instanceId = instanceId_](
2810                                              bool enableStateProfiler) {
2811         ContainerScope scope(instanceId);
2812 
2813         const std::function<void()> task = [globalFunc, globalObject, enableStateProfiler]() {
2814             auto isInStateProfiler = JSRef<JSVal>::Make(ToJSValue(enableStateProfiler));
2815             globalFunc->Call(globalObject, 1, &isInStateProfiler);
2816         };
2817 
2818         auto executor = Container::CurrentTaskExecutor();
2819         CHECK_NULL_VOID(executor);
2820         executor->PostSyncTask(task, TaskExecutor::TaskType::UI, "setProfilerStatus");
2821     };
2822 
2823     LayoutInspector::SetJsStateProfilerStatusCallback(std::move(callback));
2824 #endif
2825 }
2826 
JsSetAceDebugMode()2827 void JsiDeclarativeEngine::JsSetAceDebugMode()
2828 {
2829 #if defined(PREVIEW)
2830     return;
2831 #else
2832     if (!SystemProperties::GetDebugEnabled()) {
2833         return;
2834     }
2835     CHECK_NULL_VOID(runtime_);
2836     auto engine = reinterpret_cast<NativeEngine*>(runtime_);
2837     CHECK_NULL_VOID(engine);
2838     auto vm = engine->GetEcmaVm();
2839     CHECK_NULL_VOID(vm);
2840     auto globalObj = JSNApi::GetGlobalObject(vm);
2841     const auto globalObject = JSRef<JSObject>::Make(globalObj);
2842     const JSRef<JSVal> setAceDebugMode = globalObject->GetProperty("setAceDebugMode");
2843     if (!setAceDebugMode->IsFunction()) {
2844         return;
2845     }
2846     const auto func = JSRef<JSFunc>::Cast(setAceDebugMode);
2847     ContainerScope scope(instanceId_);
2848     func->Call(globalObject);
2849 #endif
2850 }
2851 
2852 // ArkTsCard start
2853 #ifdef FORM_SUPPORTED
PreloadAceModuleCard(void * runtime,const std::unordered_set<std::string> & formModuleList)2854 void JsiDeclarativeEngineInstance::PreloadAceModuleCard(
2855     void* runtime, const std::unordered_set<std::string>& formModuleList)
2856 {
2857     isUnique_ = true;
2858     if (isModulePreloaded_ && !IsPlugin() && !isUnique_) {
2859         return;
2860     }
2861     auto sharedRuntime = reinterpret_cast<NativeEngine*>(runtime);
2862 
2863     if (!sharedRuntime) {
2864         return;
2865     }
2866     std::shared_ptr<ArkJSRuntime> arkRuntime = std::make_shared<ArkJSRuntime>();
2867     localRuntime_ = arkRuntime;
2868     auto nativeArkEngine = static_cast<ArkNativeEngine*>(sharedRuntime);
2869     EcmaVM* vm = const_cast<EcmaVM*>(nativeArkEngine->GetEcmaVm());
2870     if (vm == nullptr) {
2871         return;
2872     }
2873     if (arkRuntime->InitializeFromExistVM(vm)) {
2874         arkRuntime->SetThreadVm(vm);
2875     } else {
2876         return;
2877     }
2878     LocalScope scope(vm);
2879     {
2880         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
2881         globalRuntime_ = arkRuntime;
2882     }
2883 
2884     RegisterStringCacheTable(vm, MAX_STRING_CACHE_SIZE);
2885     // preload js views
2886     JsRegisterFormViews(JSNApi::GetGlobalObject(vm), formModuleList, false, runtime);
2887     // preload aceConsole
2888     shared_ptr<JsValue> global = arkRuntime->GetGlobal();
2889     PreloadAceConsole(arkRuntime, global);
2890     // preload aceTrace
2891     PreloadAceTrace(arkRuntime, global);
2892     // preload getContext
2893     JsiContextModule::GetInstance()->InitContextModule(arkRuntime, global);
2894     // preload exports
2895     PreloadExports(arkRuntime, global);
2896 
2897     // preload js enums
2898     bool jsEnumStyleResult = PreloadJsEnums(arkRuntime);
2899     if (!jsEnumStyleResult) {
2900         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
2901         globalRuntime_ = nullptr;
2902         return;
2903     }
2904 
2905     // preload ark component
2906     bool arkComponentResult = PreloadArkComponent(arkRuntime);
2907     if (!arkComponentResult) {
2908         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
2909         globalRuntime_ = nullptr;
2910         return;
2911     }
2912 
2913     // preload state management
2914     isModulePreloaded_ = PreloadStateManagement(arkRuntime);
2915 
2916     // preload ark styles
2917     bool arkThemeResult = PreloadArkTheme(arkRuntime);
2918     if (!arkThemeResult) {
2919         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
2920         globalRuntime_ = nullptr;
2921         return;
2922     }
2923 
2924     {
2925         std::unique_lock<std::shared_mutex> lock(globalRuntimeMutex_);
2926         globalRuntime_ = nullptr;
2927     }
2928     cardRuntime_ = runtime;
2929     TAG_LOGI(AceLogTag::ACE_FORM, "Card model is preloaded successfully.");
2930 }
2931 
ReloadAceModuleCard(void * runtime,const std::unordered_set<std::string> & formModuleList)2932 void JsiDeclarativeEngineInstance::ReloadAceModuleCard(
2933     void* runtime, const std::unordered_set<std::string>& formModuleList)
2934 {
2935     auto sharedRuntime = reinterpret_cast<NativeEngine*>(runtime);
2936 
2937     if (!sharedRuntime) {
2938         return;
2939     }
2940     auto nativeArkEngine = static_cast<ArkNativeEngine*>(sharedRuntime);
2941     EcmaVM* vm = const_cast<EcmaVM*>(nativeArkEngine->GetEcmaVm());
2942     if (vm == nullptr) {
2943         return;
2944     }
2945     LocalScope scope(vm);
2946     RegisterStringCacheTable(vm, MAX_STRING_CACHE_SIZE);
2947     // reload js views
2948     JsRegisterFormViews(JSNApi::GetGlobalObject(vm), formModuleList, true);
2949     JSNApi::HintGC(vm, JSNApi::MemoryReduceDegree::MIDDLE, panda::ecmascript::GCReason::TRIGGER_BY_ARKUI);
2950     TAG_LOGI(AceLogTag::ACE_FORM, "Card model was reloaded successfully.");
2951 }
2952 #endif
2953 
GetCachedString(const EcmaVM * vm,int32_t propertyIndex)2954 panda::Local<panda::StringRef> JsiDeclarativeEngineInstance::GetCachedString(const EcmaVM *vm, int32_t propertyIndex)
2955 {
2956     return panda::ExternalStringCache::GetCachedString(vm, propertyIndex);
2957 }
2958 
SetCachedString(const EcmaVM * vm)2959 void JsiDeclarativeEngineInstance::SetCachedString(const EcmaVM* vm)
2960 {
2961     #define REGISTER_ALL_CACHE_STRING(name, index)              \
2962         panda::ExternalStringCache::SetCachedString(vm, name, static_cast<int32_t>(ArkUIIndex::index));
2963     ARK_UI_KEY(REGISTER_ALL_CACHE_STRING)
2964     #undef REGISTER_ALL_CACHE_STRING
2965 }
2966 
RegisterStringCacheTable(const EcmaVM * vm,int32_t size)2967 bool JsiDeclarativeEngineInstance::RegisterStringCacheTable(const EcmaVM* vm, int32_t size)
2968 {
2969     if (vm == nullptr) {
2970         return false;
2971     }
2972     if (static_cast<uint32_t>(size) > MAX_STRING_CACHE_SIZE) {
2973         return false;
2974     }
2975 
2976     bool res = panda::ExternalStringCache::RegisterStringCacheTable(vm, size);
2977     if (!res) {
2978         return false;
2979     }
2980     SetCachedString(vm);
2981     return true;
2982 }
2983 
2984 // ArkTsCard end
2985 } // namespace OHOS::Ace::Framework
2986