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