• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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