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