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