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