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