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