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