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