1 /*
2  * Copyright (c) 2021-2022 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 "adapter/ohos/entrance/pa_engine/engine/jsi/jsi_pa_engine.h"
17 
18 #include <dlfcn.h>
19 
20 #include "form_provider_info.h"
21 #include "hisysevent.h"
22 #include "js_backend_timer_module.h"
23 #include "js_environment.h"
24 #include "napi/native_node_api.h"
25 #include "napi_common_ability.h"
26 #include "napi_common_want.h"
27 #include "napi_remote_object.h"
28 #include "native_engine/impl/ark/ark_native_engine.h"
29 
30 #include "base/log/ace_trace.h"
31 #include "base/log/event_report.h"
32 #include "base/log/exception_handler.h"
33 #include "base/log/log.h"
34 #include "base/utils/utils.h"
35 #include "frameworks/bridge/js_frontend/engine/common/runtime_constants.h"
36 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_value.h"
37 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_base_utils.h"
38 
39 extern const char _binary_paMgmt_abc_start[];
40 extern const char _binary_paMgmt_abc_end[];
41 
42 namespace OHOS::Ace {
43 namespace {
44 #ifdef APP_USE_ARM
45 const std::string ARK_DEBUGGER_LIB_PATH = "/system/lib/platformsdk/libark_inspector.z.so";
46 #else
47 const std::string ARK_DEBUGGER_LIB_PATH = "/system/lib64/platformsdk/libark_inspector.z.so";
48 #endif
49 const char TASK_RUNNER[] = "PaEngineRunner";
50 
UnwrapRawImageDataMap(napi_env env,napi_value argv,std::map<std::string,int> & rawImageDataMap)51 bool UnwrapRawImageDataMap(napi_env env, napi_value argv, std::map<std::string, int>& rawImageDataMap)
52 {
53     if (!AppExecFwk::IsTypeForNapiValue(env, argv, napi_object)) {
54         LOGW("%{public}s failed, param is not napi_object.", __func__);
55         return false;
56     }
57 
58     napi_valuetype jsValueType = napi_undefined;
59     napi_value jsProNameList = nullptr;
60     uint32_t jsProCount = 0;
61 
62     NAPI_CALL_BASE(env, napi_get_property_names(env, argv, &jsProNameList), false);
63     NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false);
64     LOGI("%{public}s called. Property size=%{public}d.", __func__, jsProCount);
65 
66     napi_value jsProName = nullptr;
67     napi_value jsProValue = nullptr;
68     for (uint32_t index = 0; index < jsProCount; index++) {
69         NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false);
70         std::string strProName = AppExecFwk::UnwrapStringFromJS(env, jsProName);
71         NAPI_CALL_BASE(env, napi_get_named_property(env, argv, strProName.c_str(), &jsProValue), false);
72         NAPI_CALL_BASE(env, napi_typeof(env, jsProValue, &jsValueType), false);
73         int natValue = AppExecFwk::UnwrapInt32FromJS(env, jsProValue);
74         rawImageDataMap.emplace(strProName, natValue);
75     }
76     return true;
77 }
78 
79 // native implementation for js function: Particle.onCreateFinish()
JsOnCreateFinish(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)80 shared_ptr<JsValue> JsOnCreateFinish(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
81     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
82 {
83     return runtime->NewUndefined();
84 }
85 
86 // native implementation for js function: Particle.JsHandleCallback()
JsHandleCallback(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)87 shared_ptr<JsValue> JsHandleCallback(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
88     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
89 {
90     LOGI("JsHandleCallback");
91     return runtime->NewUndefined();
92 }
93 
94 // native implementation for js function: Particle.JsRunLoopOnce()
JsRunLoopOnce(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)95 shared_ptr<JsValue> JsRunLoopOnce(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
96     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
97 {
98     auto engineInstance = static_cast<JsiPaEngine*>(runtime->GetEmbedderData());
99     if (engineInstance == nullptr) {
100         LOGE("engineInstance is nullptr");
101         return runtime->NewUndefined();
102     }
103     auto nativeEngine = engineInstance->GetNativeEngine();
104     if (nativeEngine == nullptr) {
105         LOGE("nativeEngine is nullptr");
106         return runtime->NewUndefined();
107     }
108 
109     nativeEngine->Loop(LOOP_ONCE);
110     runtime->ExecutePendingJob();
111     return runtime->NewUndefined();
112 }
113 
114 // native implementation for js function: Particle.JsRunMicrotasks()
JsRunMicrotasks(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)115 shared_ptr<JsValue> JsRunMicrotasks(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
116     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
117 {
118     runtime->ExecutePendingJob();
119     return runtime->NewUndefined();
120 }
121 
AsyncFuncCallBack(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)122 shared_ptr<JsValue> AsyncFuncCallBack(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
123     const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
124 {
125     LOGI("AsyncFuncCallBack");
126     auto engineInstance = static_cast<JsiPaEngine*>(runtime->GetEmbedderData());
127     if (engineInstance == nullptr) {
128         LOGE("engineInstance is nullptr");
129         return runtime->NewUndefined();
130     }
131     if (argc != 2) {
132         LOGE("args length is error");
133         engineInstance->SetBlockWaiting(true);
134         engineInstance->SetAsyncResult(runtime->NewUndefined());
135         return runtime->NewUndefined();
136     }
137     int32_t code = argv[0]->ToInt32(runtime);
138     if (code != 0) {
139         LOGE("AsyncFuncCallBack error code: %{public}d", code);
140     }
141     engineInstance->SetBlockWaiting(true);
142     engineInstance->SetAsyncResult(argv[1]);
143     return runtime->NewUndefined();
144 }
145 
ToJSONStringInt(std::string sKey,std::string sValue)146 inline std::string ToJSONStringInt(std::string sKey, std::string sValue)
147 {
148     char szDoubleQuotes[] = "\"";
149     char szColon[] = ":";
150     std::string strResult;
151     strResult.append(szDoubleQuotes);
152     strResult.append(sKey);
153     strResult.append(szDoubleQuotes);
154 
155     strResult.append(szColon);
156     strResult.append(sValue);
157     return strResult;
158 }
159 } // namespace
160 
RegisterUncaughtExceptionHandler()161 void JsiPaEngine::RegisterUncaughtExceptionHandler()
162 {
163     ACE_SCOPED_TRACE("JsiPaEngine::RegisterUncaughtExceptionHandler");
164     JsEnv::UncaughtExceptionInfo uncaughtExceptionInfo;
165     uncaughtExceptionInfo.uncaughtTask = [](std::string summary, const JsEnv::ErrorObject errorObj) {
166         std::string packageName = AceApplicationInfo::GetInstance().GetPackageName();
167         JsErrorObject errorInfo = {
168             .name = errorObj.name,
169             .message = errorObj.message,
170             .stack = errorObj.stack,
171         };
172         EventReport::JsErrReport(packageName, "", summary);
173         ExceptionHandler::HandleJsException(summary, errorInfo);
174     };
175 
176     jsAbilityRuntime_->RegisterUncaughtExceptionHandler(uncaughtExceptionInfo);
177 }
178 
RegisterConsoleModule(ArkNativeEngine * engine)179 void JsiPaEngine::RegisterConsoleModule(ArkNativeEngine* engine)
180 {
181     ACE_SCOPED_TRACE("JsiPaEngine::RegisterConsoleModule");
182     CHECK_NULL_VOID(engine);
183 
184     napi_env env = reinterpret_cast<napi_env>(engine);
185     napi_value globalObj;
186     napi_get_global(env, &globalObj);
187     napi_valuetype valueType = napi_undefined;
188     napi_typeof(env, globalObj, &valueType);
189     if (valueType != napi_object) {
190         LOGE("global is not NativeObject");
191         return;
192     }
193 
194     napi_value logValue;
195     napi_create_function(env, "log", strlen("log"), AppInfoLogPrint, nullptr, &logValue);
196     napi_value debugValue;
197     napi_create_function(env, "debug", strlen("debug"), AppDebugLogPrint, nullptr, &debugValue);
198     napi_value infoValue;
199     napi_create_function(env, "info", strlen("info"), AppInfoLogPrint, nullptr, &infoValue);
200     napi_value warnValue;
201     napi_create_function(env, "warn", strlen("warn"), AppWarnLogPrint, nullptr, &warnValue);
202     napi_value errorValue;
203     napi_create_function(env, "error", strlen("error"), AppErrorLogPrint, nullptr, &errorValue);
204     napi_value consoleObj = nullptr;
205     napi_create_object(env, &consoleObj);
206     napi_set_named_property(env, consoleObj, "log", logValue);
207     napi_set_named_property(env, consoleObj, "debug", debugValue);
208     napi_set_named_property(env, consoleObj, "info", infoValue);
209     napi_set_named_property(env, consoleObj, "warn", warnValue);
210     napi_set_named_property(env, consoleObj, "error", errorValue);
211     napi_set_named_property(env, globalObj, "console", consoleObj);
212 }
213 
RegisterPaModule()214 void JsiPaEngine::RegisterPaModule()
215 {
216     ACE_SCOPED_TRACE("JsiPaEngine::RegisterAceModule");
217 
218     shared_ptr<JsValue> aceObj = runtime_->NewObject();
219     if (!aceObj) {
220         LOGE("RegisterPaModule failed. aceObj is null");
221         return;
222     }
223     if (!aceObj->SetProperty(runtime_, "onCreateFinish", runtime_->NewFunction(JsOnCreateFinish))) {
224         LOGE("RegisterPaModule onCreateFinish failed.");
225     }
226     if (!aceObj->SetProperty(runtime_, "handleCallback", runtime_->NewFunction(JsHandleCallback))) {
227         LOGE("RegisterPaModule handleCallback failed.");
228     }
229     if (!aceObj->SetProperty(runtime_, "runLoopOnce", runtime_->NewFunction(JsRunLoopOnce))) {
230         LOGE("RegisterPaModule runLoopOnce failed.");
231     }
232     if (!aceObj->SetProperty(runtime_, "runMicrotasks", runtime_->NewFunction(JsRunMicrotasks))) {
233         LOGE("RegisterPaModule runMicrotasks failed.");
234     }
235 
236     shared_ptr<JsValue> global = runtime_->GetGlobal();
237     if (!global->SetProperty(runtime_, "Particle", aceObj)) {
238         LOGE("RegisterPaModule ace failed.");
239     }
240 }
241 
EvaluateJsCode()242 void JsiPaEngine::EvaluateJsCode()
243 {
244     ACE_SCOPED_TRACE("JsiPaEngine::EvaluateJsCode");
245     CHECK_NULL_VOID(jsAbilityRuntime_);
246     // load jsfwk
247     if (language_ == SrcLanguage::JS && !jsAbilityRuntime_->LoadScript("/system/etc/strip.native.min.abc")) {
248         LOGE("Failed to load js framework!");
249     }
250     // load paMgmt.js
251     std::vector<uint8_t> paMgmt(_binary_paMgmt_abc_start, _binary_paMgmt_abc_end);
252     if (!jsAbilityRuntime_->LoadScript("", &paMgmt, true)) {
253         LOGE("EvaluateJsCode paMgmt abc failed");
254     }
255 }
256 
InitJsRuntimeOptions(AbilityRuntime::Runtime::Options & options)257 void JsiPaEngine::InitJsRuntimeOptions(AbilityRuntime::Runtime::Options& options)
258 {
259     options.lang = AbilityRuntime::Runtime::Language::JS;
260     options.eventRunner = eventRunner_;
261     options.loadAce = false;
262     options.preload = false;
263     options.isStageModel = false;
264     options.hapPath = GetHapPath();
265     options.isDebugVersion = GetDebugMode();
266     options.packagePathStr = GetWorkerPath()->packagePathStr;
267     options.assetBasePathStr = GetWorkerPath()->assetBasePathStr;
268     options.isJsFramework = language_ == SrcLanguage::JS;
269 }
270 
CreateJsRuntime()271 bool JsiPaEngine::CreateJsRuntime()
272 {
273     AbilityRuntime::Runtime::Options options;
274     InitJsRuntimeOptions(options);
275     jsAbilityRuntime_ = AbilityRuntime::JsRuntime::Create(options);
276     if (jsAbilityRuntime_ == nullptr) {
277         LOGE("Create js runtime failed.");
278         return false;
279     }
280 
281     return true;
282 }
283 
InitJsEnv(bool debuggerMode,const std::unordered_map<std::string,void * > & extraNativeObject)284 bool JsiPaEngine::InitJsEnv(bool debuggerMode, const std::unordered_map<std::string, void*>& extraNativeObject)
285 {
286     ACE_SCOPED_TRACE("JsiPaEngine::InitJsEnv");
287     runtime_.reset(new ArkJSRuntime());
288     if (runtime_ == nullptr) {
289         LOGE("Can't allocate JSI JSRuntime");
290         EventReport::SendJsException(JsExcepType::JS_ENGINE_INIT_ERR);
291         return false;
292     }
293 
294     runtime_->SetLogPrint(PrintLog);
295     StartDebugMode(debuggerMode);
296 
297     auto ecmaVm = GetEcmaVm();
298     CHECK_NULL_RETURN(ecmaVm, false);
299     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
300     if (!arkJSRuntime->InitializeFromExistVM(ecmaVm)) {
301         LOGE("Initialize runtime from exist vm failed.");
302         return false;
303     }
304     arkJSRuntime->SetDebugMode(isDebugMode_);
305     arkJSRuntime->SetInstanceId(instanceId_);
306 
307 #if !defined(PREVIEW)
308     for (const auto& [key, value] : extraNativeObject) {
309         shared_ptr<JsValue> nativeValue = runtime_->NewNativePointer(value);
310         runtime_->GetGlobal()->SetProperty(runtime_, key, nativeValue);
311     }
312 #endif
313 
314     // Register pa native functions
315     RegisterPaModule();
316 
317     // load abc file
318     EvaluateJsCode();
319 
320     runtime_->SetEmbedderData(this);
321 
322     RegisterUncaughtExceptionHandler();
323     LOGI("InitJsEnv success");
324     return true;
325 }
326 
GetJsRuntime() const327 std::shared_ptr<JsRuntime> JsiPaEngine::GetJsRuntime() const
328 {
329     return runtime_;
330 }
331 
GetNativeEngine() const332 inline NativeEngine* JsiPaEngine::GetNativeEngine() const
333 {
334     CHECK_NULL_RETURN(jsAbilityRuntime_, nullptr);
335     return jsAbilityRuntime_->GetNativeEnginePointer();
336 }
337 
GetEcmaVm() const338 inline panda::ecmascript::EcmaVM* JsiPaEngine::GetEcmaVm() const
339 {
340     CHECK_NULL_RETURN(jsAbilityRuntime_, nullptr);
341     return jsAbilityRuntime_->GetEcmaVm();
342 }
343 
StartDebugMode(bool debuggerMode)344 void JsiPaEngine::StartDebugMode(bool debuggerMode)
345 {
346     if (debuggerMode && jsAbilityRuntime_ != nullptr) {
347 #ifdef OHOS_PLATFORM
348         jsAbilityRuntime_->StartDebugger(debuggerMode, instanceId_);
349 #endif
350     }
351 }
352 
353 // -----------------------
354 // Start JsiPaEngine
355 // -----------------------
~JsiPaEngine()356 JsiPaEngine::~JsiPaEngine()
357 {
358     LOGI("JsiPaEngine destructor");
359     UnloadLibrary();
360 
361     if (runtime_) {
362         runtime_->Reset();
363     }
364     runtime_.reset();
365     runtime_ = nullptr;
366 
367     // To guarantee the jsruntime released in js thread
368     auto jsRuntime = std::move(jsAbilityRuntime_);
369     if (!eventHandler_->PostSyncTask([&jsRuntime] { auto runtime = std::move(jsRuntime); })) {
370         LOGE("Post sync task failed.");
371     }
372 }
373 
Initialize(BackendType type,SrcLanguage language)374 bool JsiPaEngine::Initialize(BackendType type, SrcLanguage language)
375 {
376     ACE_SCOPED_TRACE("JsiPaEngine::Initialize");
377     LOGI("JsiPaEngine initialize");
378     SetDebugMode(NeedDebugBreakPoint());
379     type_ = type;
380     language_ = language;
381 
382     eventRunner_ = EventRunner::Create(TASK_RUNNER + std::to_string(instanceId_));
383     if (eventRunner_ == nullptr) {
384         LOGE("Create runner failed.");
385         return false;
386     }
387 
388     eventHandler_ = std::make_shared<EventHandler>(eventRunner_);
389     if (eventHandler_ == nullptr) {
390         LOGE("Create handler failed.");
391         return false;
392     }
393 
394     bool ret = false;
395     eventHandler_->PostSyncTask([weakEngine = AceType::WeakClaim(this), &ret] {
396         auto paEngine = weakEngine.Upgrade();
397         if (paEngine != nullptr) {
398             ret = paEngine->CreateJsRuntime();
399         }
400     });
401     if (!ret) {
402         return false;
403     }
404 
405     PostTask([weakEngine = AceType::WeakClaim(this), type, language] {
406         auto paEngine = weakEngine.Upgrade();
407         if (paEngine == nullptr) {
408             LOGE("Pa engine is invalid.");
409             return;
410         }
411         paEngine->InitializeInner(type, language);
412     }, "ArkUIPaEngineInit");
413     return true;
414 }
415 
InitializeInner(BackendType type,SrcLanguage language)416 bool JsiPaEngine::InitializeInner(BackendType type, SrcLanguage language)
417 {
418     bool result = InitJsEnv(GetDebugMode(), GetExtraNativeObject());
419     if (!result) {
420         LOGE("Init js env failed");
421         return false;
422     }
423 
424     LoadLibrary();
425 
426     auto nativeEngine = GetNativeEngine();
427     CHECK_NULL_RETURN(nativeEngine, false);
428     if (language_ == SrcLanguage::JS) {
429         InitTimerModule(reinterpret_cast<napi_env>(nativeEngine));
430     }
431 
432     if (jsBackendAssetManager_) {
433         std::vector<std::string> packagePath = jsBackendAssetManager_->GetLibPath();
434         auto appLibPathKey = jsBackendAssetManager_->GetAppLibPathKey();
435         if (!packagePath.empty()) {
436             auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
437             arkNativeEngine->SetPackagePath(appLibPathKey, packagePath);
438         }
439     }
440     return true;
441 }
442 
SetAssetManager(const RefPtr<AssetManager> & assetManager)443 void JsiPaEngine::SetAssetManager(const RefPtr<AssetManager>& assetManager)
444 {
445     jsBackendAssetManager_ = Referenced::MakeRefPtr<JsBackendAssetManager>(assetManager);
446 }
447 
LoadJs(const std::string & url,const OHOS::AAFwk::Want & want)448 void JsiPaEngine::LoadJs(const std::string& url, const OHOS::AAFwk::Want& want)
449 {
450     ACE_SCOPED_TRACE("JsiPaEngine::LoadJs");
451     LOGI("JsiPaEngine LoadJs: %{private}s", url.c_str());
452 
453     auto runtime = GetJsRuntime();
454 
455     // js file to abc file and execute abc file
456     const char js_ext[] = ".js";
457     const char bin_ext[] = ".abc";
458     auto pos = url.rfind(js_ext);
459     if (pos != std::string::npos && pos == url.length() - (sizeof(js_ext) - 1)) {
460         std::string urlName = url.substr(0, pos) + bin_ext;
461         LOGI("GetAssetContent: %{public}s", urlName.c_str());
462         std::vector<uint8_t> content;
463         if (jsBackendAssetManager_ == nullptr || !jsBackendAssetManager_->GetAssetContent(urlName, content)) {
464             LOGE("GetAssetContent \"%{public}s\" failed.", urlName.c_str());
465             return;
466         }
467         std::string abcPath = jsBackendAssetManager_->GetAssetPath(urlName).append(urlName);
468         CHECK_NULL_VOID(jsAbilityRuntime_);
469         if (!jsAbilityRuntime_->LoadScript(abcPath, &content, true)) {
470             LOGE("LoadScript \"%{public}s\" failed.", urlName.c_str());
471             return;
472         }
473 
474         // only ace1.0 need
475         shared_ptr<JsValue> mainEntryFunc = runtime->GetGlobal()->GetProperty(runtime, "___mainEntry___");
476         if (mainEntryFunc->IsFunction(runtime)) {
477             LOGI("JsiPaEngine call mainEntryFunc");
478             runtime->GetGlobal()->SetProperty(runtime, "___mainEntry___", runtime->NewUndefined());
479             const std::vector<shared_ptr<JsValue>>& argv = { runtime->GetGlobal() };
480             shared_ptr<JsValue> retVal = CallFunc(mainEntryFunc, argv);
481             auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
482             if (arkJSRuntime->HasPendingException()) {
483                 LOGE("JsiPaEngine call mainEntryFunc FAILED!");
484             }
485         }
486     }
487 
488     // call start pa func
489     if (type_ == BackendType::SERVICE) {
490         StartService();
491     } else if (type_ == BackendType::DATA) {
492         StartData();
493     } else if (type_ == BackendType::FORM) {
494         LOGI("Form Ability LoadJS finish.");
495     } else {
496         LOGE("backend type not support");
497     }
498 }
499 
LoadLibrary()500 void JsiPaEngine::LoadLibrary()
501 {
502 #ifdef APP_USE_ARM
503     const char* rdbPath = "/system/lib/module/data/librdb.z.so";
504 #else
505     const char* rdbPath = "/system/lib64/module/data/librdb.z.so";
506 #endif
507     if (strlen(rdbPath) == 0) {
508         LOGE("module path is empty");
509         return;
510     }
511 
512     libRdb_ = dlopen(rdbPath, RTLD_LAZY);
513     if (libRdb_ == nullptr) {
514         LOGE("dlopen failed: %{public}s", dlerror());
515     }
516 
517     rdbValueBucketNewInstance_ = reinterpret_cast<RdbValueBucketNewInstance>(
518         dlsym(libRdb_, "NAPI_OHOS_Data_RdbJsKit_ValuesBucketProxy_NewInstance"));
519     if (rdbValueBucketNewInstance_ == nullptr) {
520         LOGE("symbol not found: %{public}s", dlerror());
521     }
522 
523     rdbValueBucketGetNativeObject_ = reinterpret_cast<RdbValueBucketGetNativeObject>(
524         dlsym(libRdb_, "NAPI_OHOS_Data_RdbJsKit_ValuesBucketProxy_GetNativeObject"));
525     if (rdbValueBucketGetNativeObject_ == nullptr) {
526         LOGE("symbol not found: %{public}s", dlerror());
527     }
528 
529     rdbResultSetProxyNewInstance_ = reinterpret_cast<RdbResultSetProxyNewInstance>(
530         dlsym(libRdb_, "NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_NewInstance"));
531     if (rdbResultSetProxyNewInstance_ == nullptr) {
532         LOGE("symbol not found: %{public}s", dlerror());
533     }
534 
535     rdbResultSetProxyGetNativeObject_ = reinterpret_cast<RdbResultSetProxyGetNativeObject>(
536         dlsym(libRdb_, "NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_GetNativeObject"));
537     if (rdbResultSetProxyGetNativeObject_ == nullptr) {
538         LOGE("symbol not found: %{public}s", dlerror());
539     }
540 
541 #ifdef APP_USE_ARM
542     const char* dataAbilityPath = "/system/lib/module/data/libdataability.z.so";
543 #else
544     const char* dataAbilityPath = "/system/lib64/module/data/libdataability.z.so";
545 #endif
546     if (strlen(dataAbilityPath) == 0) {
547         LOGE("module path is empty");
548         return;
549     }
550 
551     libDataAbility_ = dlopen(dataAbilityPath, RTLD_LAZY);
552     if (libDataAbility_ == nullptr) {
553         LOGE("dlopen failed: %{public}s", dlerror());
554     }
555 
556     dataAbilityPredicatesNewInstance_ = reinterpret_cast<DataAbilityPredicatesNewInstance>(
557         dlsym(libDataAbility_, "NAPI_OHOS_Data_DataAbilityJsKit_DataAbilityPredicatesProxy_NewInstance"));
558     if (dataAbilityPredicatesNewInstance_ == nullptr) {
559         LOGE("symbol not found: %{public}s", dlerror());
560     }
561 
562     dataAbilityPredicatesGetNativeObject_ = reinterpret_cast<DataAbilityPredicatesGetNativeObject>(
563         dlsym(libDataAbility_, "NAPI_OHOS_Data_DataAbilityJsKit_DataAbilityPredicatesProxy_GetNativeObject"));
564     if (dataAbilityPredicatesGetNativeObject_ == nullptr) {
565         LOGE("symbol not found: %{public}s", dlerror());
566     }
567 }
568 
UnloadLibrary()569 void JsiPaEngine::UnloadLibrary()
570 {
571     dlclose(libRdb_);
572     dlclose(libDataAbility_);
573 }
574 
GetPaFunc(const std::string & funcName)575 shared_ptr<JsValue> JsiPaEngine::GetPaFunc(const std::string& funcName)
576 {
577     LOGI("JsiPaEngine GetPaFunc funcName: %{public}s", funcName.c_str());
578     shared_ptr<JsRuntime> runtime = GetJsRuntime();
579     ACE_DCHECK(runtime);
580     shared_ptr<JsValue> global = runtime->GetGlobal();
581     shared_ptr<JsValue> exportsObject = global->GetProperty(runtime, "exports");
582     if (!exportsObject->IsObject(runtime)) {
583         LOGE("property \"exports\" is not a object");
584         return nullptr;
585     }
586     shared_ptr<JsValue> defaultObject = exportsObject->GetProperty(runtime, "default");
587     if (!defaultObject->IsObject(runtime)) {
588         LOGE("property \"default\" is not a object");
589         return nullptr;
590     }
591 
592     shared_ptr<JsValue> func = defaultObject->GetProperty(runtime, funcName);
593     if (!func->IsFunction(runtime)) {
594         LOGE("%{public}s not found or is not a function!", funcName.c_str());
595         return nullptr;
596     }
597     return func;
598 }
599 
CallFunc(const shared_ptr<JsValue> & func)600 shared_ptr<JsValue> JsiPaEngine::CallFunc(const shared_ptr<JsValue>& func)
601 {
602     const std::vector<shared_ptr<JsValue>>& argv = {};
603     return CallFunc(func, argv);
604 }
605 
CallFunc(const shared_ptr<JsValue> & func,const std::vector<shared_ptr<JsValue>> & argv)606 shared_ptr<JsValue> JsiPaEngine::CallFunc(const shared_ptr<JsValue>& func, const std::vector<shared_ptr<JsValue>>& argv)
607 {
608     shared_ptr<JsRuntime> runtime = GetJsRuntime();
609     ACE_DCHECK(runtime);
610     if (func == nullptr) {
611         LOGE("func is nullptr!");
612         return runtime->NewUndefined();
613     }
614     if (!func->IsFunction(runtime)) {
615         LOGE("func is not a function!");
616         return runtime->NewUndefined();
617     }
618 
619     auto nativeEngine = GetNativeEngine();
620     CHECK_NULL_RETURN(nativeEngine, runtime->NewUndefined());
621     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
622     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
623     if (arkJSRuntime->HasPendingException()) {
624         LOGE("JsiPaEngine CallFunc FAILED!");
625         return runtime->NewUndefined();
626     }
627 
628     auto arkJSFunc = std::static_pointer_cast<ArkJSValue>(func);
629     if (arkJSFunc->IsUndefined(runtime)) {
630         LOGE("JsiPaEngine CallFunc return value is und efined!");
631         return runtime->NewUndefined();
632     }
633 
634     std::vector<napi_value> nativeArgv;
635     int32_t length = 0;
636     for (auto item : argv) {
637         auto value = std::static_pointer_cast<ArkJSValue>(item);
638         auto napiValue = ArkNativeEngine::ArkValueToNapiValue(env, value->GetValue(arkJSRuntime));
639         nativeArgv.emplace_back(napiValue);
640         length++;
641     }
642 
643     napi_value nativeFunc = ArkNativeEngine::ArkValueToNapiValue(env, arkJSFunc->GetValue(arkJSRuntime));
644     CHECK_NULL_RETURN(nativeFunc, nullptr);
645     napi_value globalObj;
646     napi_get_global(env, &globalObj);
647     napi_valuetype valueType = napi_undefined;
648     napi_typeof(env, globalObj, &valueType);
649     if (valueType != napi_object) {
650         LOGE("global is not NativeObject");
651         return runtime->NewUndefined();
652     }
653     napi_value ret;
654     napi_call_function(env, globalObj, nativeFunc, length, nativeArgv.data(), &ret);
655     return NapiValueToJsValue(ret);
656 }
657 
CallFuncWithDefaultThis(const shared_ptr<JsValue> & func,const std::vector<shared_ptr<JsValue>> & argv)658 shared_ptr<JsValue> JsiPaEngine::CallFuncWithDefaultThis(
659     const shared_ptr<JsValue>& func, const std::vector<shared_ptr<JsValue>>& argv)
660 {
661     shared_ptr<JsRuntime> runtime = GetJsRuntime();
662     ACE_DCHECK(runtime);
663     if (func == nullptr) {
664         LOGE("func is nullptr!");
665         return runtime->NewUndefined();
666     }
667     if (!func->IsFunction(runtime)) {
668         LOGE("func is not a function!");
669         return runtime->NewUndefined();
670     }
671 
672     shared_ptr<JsValue> global = runtime->GetGlobal();
673     shared_ptr<JsValue> thisObject = global;
674     do {
675         shared_ptr<JsValue> exportsObject = global->GetProperty(runtime, "exports");
676         if (!exportsObject->IsObject(runtime)) {
677             LOGW("property \"exports\" is not a object");
678             break;
679         }
680         shared_ptr<JsValue> defaultObject = exportsObject->GetProperty(runtime, "default");
681         if (!defaultObject->IsObject(runtime)) {
682             LOGE("property \"default\" is not a object");
683             break;
684         }
685         thisObject = defaultObject;
686     } while (false);
687 
688     auto nativeEngine = GetNativeEngine();
689     CHECK_NULL_RETURN(nativeEngine, runtime->NewUndefined());
690     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
691     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
692     if (arkJSRuntime->HasPendingException()) {
693         LOGE("JsiPaEngine CallFunc FAILED!");
694         return runtime->NewUndefined();
695     }
696 
697     auto arkJSThis = std::static_pointer_cast<ArkJSValue>(thisObject);
698     if (arkJSThis->IsUndefined(runtime)) {
699         LOGE("JsiPaEngine CallFunc return value is undefined!");
700         return runtime->NewUndefined();
701     }
702 
703     auto arkJSFunc = std::static_pointer_cast<ArkJSValue>(func);
704     if (arkJSFunc->IsUndefined(runtime)) {
705         LOGE("JsiPaEngine CallFunc return value is und efined!");
706         return runtime->NewUndefined();
707     }
708 
709     std::vector<napi_value> nativeArgv;
710     int32_t length = 0;
711     for (auto item : argv) {
712         auto value = std::static_pointer_cast<ArkJSValue>(item);
713         auto nativeVal = ArkNativeEngine::ArkValueToNapiValue(env, value->GetValue(arkJSRuntime));
714         nativeArgv.emplace_back(nativeVal);
715         length++;
716     }
717 
718     napi_value nativeFunc = ArkNativeEngine::ArkValueToNapiValue(env, arkJSFunc->GetValue(arkJSRuntime));
719     CHECK_NULL_RETURN(nativeFunc, nullptr);
720 
721     napi_value nativeThis = ArkNativeEngine::ArkValueToNapiValue(env, arkJSThis->GetValue(arkJSRuntime));
722     CHECK_NULL_RETURN(nativeThis, nullptr);
723 
724     napi_value ret;
725     napi_call_function(env, nativeThis, nativeFunc, length, nativeArgv.data(), &ret);
726 
727     return NapiValueToJsValue(ret);
728 }
729 
CallFunc(const shared_ptr<JsValue> & func,const std::vector<shared_ptr<JsValue>> & argv,const CallingInfo & callingInfo)730 shared_ptr<JsValue> JsiPaEngine::CallFunc(
731     const shared_ptr<JsValue>& func, const std::vector<shared_ptr<JsValue>>& argv, const CallingInfo& callingInfo)
732 {
733     shared_ptr<JsRuntime> runtime = GetJsRuntime();
734     ACE_DCHECK(runtime);
735     if (func == nullptr) {
736         LOGE("func is nullptr!");
737         return runtime->NewUndefined();
738     }
739     if (!func->IsFunction(runtime)) {
740         LOGE("func is not a function!");
741         return runtime->NewUndefined();
742     }
743     shared_ptr<JsValue> global = runtime->GetGlobal();
744 
745     auto nativeEngine = GetNativeEngine();
746     CHECK_NULL_RETURN(nativeEngine, runtime->NewUndefined());
747     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
748     NAPI_CallingInfo oldCallingInfo;
749     NAPI_RemoteObject_saveOldCallingInfo(env, oldCallingInfo);
750     NAPI_RemoteObject_setNewCallingInfo(env, callingInfo);
751     NAPI_RemoteObject_resetOldCallingInfo(env, oldCallingInfo);
752 
753     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
754     if (arkJSRuntime->HasPendingException()) {
755         LOGE("JsiPaEngine CallFunc FAILED!");
756         return runtime->NewUndefined();
757     }
758 
759     auto arkJSFunc = std::static_pointer_cast<ArkJSValue>(func);
760     if (arkJSFunc->IsUndefined(runtime)) {
761         LOGE("JsiPaEngine CallFunc return value is und efined!");
762         return runtime->NewUndefined();
763     }
764 
765     std::vector<napi_value> nativeArgv;
766     int32_t length = 0;
767 
768     for (auto item : argv) {
769         auto value = std::static_pointer_cast<ArkJSValue>(item);
770         auto napiValue = ArkNativeEngine::ArkValueToNapiValue(env, value->GetValue(arkJSRuntime));
771         nativeArgv.emplace_back(napiValue);
772         length++;
773     }
774 
775     napi_value nativeFunc = ArkNativeEngine::ArkValueToNapiValue(env, arkJSFunc->GetValue(arkJSRuntime));
776     CHECK_NULL_RETURN(nativeFunc, nullptr);
777 
778     napi_value globalObj;
779     napi_get_global(env, &globalObj);
780     napi_valuetype valueType = napi_undefined;
781     napi_typeof(env, globalObj, &valueType);
782     if (valueType != napi_object) {
783         LOGE("global is not NativeObject");
784         return runtime->NewUndefined();
785     }
786     napi_value ret;
787     napi_call_function(env, globalObj, nativeFunc, length, nativeArgv.data(), &ret);
788     return NapiValueToJsValue(ret);
789 }
790 
CallAsyncFunc(const shared_ptr<JsValue> & func,std::vector<shared_ptr<JsValue>> & argv,const CallingInfo & callingInfo)791 shared_ptr<JsValue> JsiPaEngine::CallAsyncFunc(
792     const shared_ptr<JsValue>& func, std::vector<shared_ptr<JsValue>>& argv, const CallingInfo& callingInfo)
793 {
794     shared_ptr<JsRuntime> runtime = GetJsRuntime();
795     ACE_DCHECK(runtime);
796     if (func == nullptr) {
797         LOGE("func is nullptr!");
798         return runtime->NewUndefined();
799     }
800     if (!func->IsFunction(runtime)) {
801         LOGE("func is not a function!");
802         return runtime->NewUndefined();
803     }
804     shared_ptr<JsValue> global = runtime->GetGlobal();
805 
806     auto nativeEngine = GetNativeEngine();
807     CHECK_NULL_RETURN(nativeEngine, runtime->NewUndefined());
808     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
809     NAPI_CallingInfo oldCallingInfo;
810     NAPI_RemoteObject_saveOldCallingInfo(env, oldCallingInfo);
811     NAPI_RemoteObject_setNewCallingInfo(env, callingInfo);
812 
813     argv.push_back(runtime->NewFunction(AsyncFuncCallBack));
814 
815     SetBlockWaiting(false);
816 
817     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
818     if (arkJSRuntime->HasPendingException()) {
819         LOGE("JsiPaEngine CallFunc FAILED!");
820         return runtime->NewUndefined();
821     }
822 
823     auto arkJSFunc = std::static_pointer_cast<ArkJSValue>(func);
824     if (arkJSFunc->IsUndefined(runtime)) {
825         LOGE("JsiPaEngine CallFunc return value is und efined!");
826         return runtime->NewUndefined();
827     }
828 
829     std::vector<napi_value> nativeArgv;
830     int32_t length = 0;
831     for (auto item : argv) {
832         auto value = std::static_pointer_cast<ArkJSValue>(item);
833         auto napiValue = ArkNativeEngine::ArkValueToNapiValue(env, value->GetValue(arkJSRuntime));
834         nativeArgv.emplace_back(napiValue);
835         length++;
836     }
837 
838     napi_value nativeFunc = ArkNativeEngine::ArkValueToNapiValue(env, arkJSFunc->GetValue(arkJSRuntime));
839     CHECK_NULL_RETURN(nativeFunc, nullptr);
840     napi_value globalObj;
841     napi_get_global(env, &globalObj);
842     napi_valuetype valueType = napi_undefined;
843     napi_typeof(env, globalObj, &valueType);
844     if (valueType != napi_object) {
845         LOGE("global is not NativeObject");
846         return runtime->NewUndefined();
847     }
848     napi_value ret;
849     napi_call_function(env, globalObj, nativeFunc, length, nativeArgv.data(), &ret);
850 
851     runtime->ExecutePendingJob();
852     while (!GetBlockWaiting()) {
853         nativeEngine->Loop(LOOP_ONCE);
854         runtime->ExecutePendingJob();
855     }
856     NAPI_RemoteObject_resetOldCallingInfo(env, oldCallingInfo);
857     return GetAsyncResult();
858 }
859 
NapiValueToJsValue(napi_value napiValue)860 shared_ptr<JsValue> JsiPaEngine::NapiValueToJsValue(napi_value napiValue)
861 {
862     if (napiValue == nullptr) {
863         LOGE("napiValue is nullptr!");
864         return GetJsRuntime()->NewUndefined();
865     }
866     auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(GetJsRuntime());
867     return std::make_shared<ArkJSValue>(arkRuntime, NapiValueToLocalValue(napiValue));
868 }
869 
WantToJsValue(const OHOS::AAFwk::Want & want)870 shared_ptr<JsValue> JsiPaEngine::WantToJsValue(const OHOS::AAFwk::Want& want)
871 {
872     napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(GetNativeEngine()), want);
873     return NapiValueToJsValue(napiWant);
874 }
875 
StartService()876 void JsiPaEngine::StartService()
877 {
878     LOGI("JsiPaEngine StartService");
879     auto func = GetPaFunc("onStart");
880     CallFunc(func);
881 }
882 
StartData()883 void JsiPaEngine::StartData()
884 {
885     LOGI("JsiPaEngine StartData");
886 
887     const auto& nativeObjects = GetExtraNativeObject();
888     auto it = nativeObjects.find("ability");
889     if (it == nativeObjects.end() || it->second == nullptr) {
890         LOGE("Can't find ability object");
891         return;
892     }
893 
894     shared_ptr<JsRuntime> runtime = GetJsRuntime();
895     auto nativeEngine = GetNativeEngine();
896     CHECK_NULL_VOID(nativeEngine);
897     const std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo =
898         reinterpret_cast<Ability*>(it->second)->GetAbilityInfo();
899     const AppExecFwk::AbilityInfo abilityInfoInstance = *(abilityInfo.get());
900     napi_value abilityInfoNapi =
901         AppExecFwk::ConvertAbilityInfo(reinterpret_cast<napi_env>(nativeEngine), abilityInfoInstance);
902     const std::vector<shared_ptr<JsValue>>& argv = { NapiValueToJsValue(abilityInfoNapi) };
903 
904     auto func = GetPaFunc("onInitialized");
905     CallFunc(func, argv);
906 }
907 
DestroyApplication(const std::string & packageName)908 void JsiPaEngine::DestroyApplication(const std::string& packageName)
909 {
910     LOGI("JsiPaEngine DestroyApplication");
911     shared_ptr<JsRuntime> runtime = GetJsRuntime();
912     const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(packageName) };
913     auto func = GetPaFunc("onStop");
914     CallFunc(func, argv);
915 }
916 
Insert(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value,const CallingInfo & callingInfo)917 int32_t JsiPaEngine::Insert(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value, const CallingInfo& callingInfo)
918 {
919     LOGI("JsiPaEngine Insert");
920     shared_ptr<JsRuntime> runtime = GetJsRuntime();
921     auto nativeEngine = GetNativeEngine();
922     CHECK_NULL_RETURN(nativeEngine, 0);
923     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
924     napi_value argNapiValue = rdbValueBucketNewInstance_(env, const_cast<OHOS::NativeRdb::ValuesBucket&>(value));
925     std::vector<shared_ptr<JsValue>> argv;
926     argv.push_back(runtime->NewString(uri.ToString()));
927     argv.push_back(NapiValueToJsValue(argNapiValue));
928     auto func = GetPaFunc("insert");
929     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
930 
931     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
932     if (arkJSRuntime->HasPendingException()) {
933         LOGE("JsiPaEngine Insert FAILED!");
934         return 0;
935     }
936     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
937     return arkJSValue->ToInt32(runtime);
938 }
939 
ExcludeTag(const std::string & jsonString,const std::string & tagString)940 std::string JsiPaEngine::ExcludeTag(const std::string& jsonString, const std::string& tagString)
941 {
942     size_t pos = jsonString.find(tagString);
943     if (pos == std::string::npos) {
944         return jsonString;
945     }
946     std::string valueString = jsonString.substr(pos);
947     pos = valueString.find(":");
948     if (pos == std::string::npos) {
949         return "";
950     }
951     size_t valuePos = pos + 1;
952     while (valuePos < valueString.size()) {
953         if (valueString.at(valuePos) != ' ' && valueString.at(valuePos) != '\t') {
954             break;
955         }
956         valuePos++;
957     }
958     if (valuePos >= valueString.size()) {
959         return "";
960     }
961     valueString = valueString.substr(valuePos);
962     return valueString.substr(0, valueString.size() - 1);
963 }
964 
IncludeTag(const std::string & jsonString,const std::string & tagString)965 std::string JsiPaEngine::IncludeTag(const std::string& jsonString, const std::string& tagString)
966 {
967     std::string result = "{\"" + tagString + "\":";
968     result += jsonString;
969     result += "}";
970     return result;
971 }
972 
Call(const std::string & method,const std::string & arg,const AppExecFwk::PacMap & pacMap,const CallingInfo & callingInfo)973 std::shared_ptr<AppExecFwk::PacMap> JsiPaEngine::Call(
974     const std::string& method, const std::string& arg, const AppExecFwk::PacMap& pacMap, const CallingInfo& callingInfo)
975 {
976     std::string pacString = const_cast<AppExecFwk::PacMap&>(pacMap).ToString();
977     std::string params = ExcludeTag(pacString, "pacmap");
978     shared_ptr<JsRuntime> runtime = GetJsRuntime();
979     std::vector<shared_ptr<JsValue>> argv;
980     argv.push_back(runtime->NewString(method));
981     argv.push_back(runtime->NewString(arg));
982     argv.push_back(runtime->NewString(params));
983     auto func = GetPaFunc("call");
984     if (func == nullptr) {
985         return nullptr;
986     }
987     shared_ptr<JsValue> retVal = CallFunc(func, argv, callingInfo);
988     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
989     if (arkJSRuntime->HasPendingException()) {
990         LOGE("JsiPaEngine Query FAILED!");
991         return nullptr;
992     }
993     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
994     if (arkJSValue->IsUndefined(runtime)) {
995         LOGE("JsiPaEngine Query return value is undefined!");
996         return nullptr;
997     }
998     std::string retStr = IncludeTag(arkJSValue->ToString(runtime), "pacmap");
999     auto result = std::make_shared<AppExecFwk::PacMap>();
1000     if (result == nullptr) {
1001         LOGE("fail to create PacMap");
1002         return nullptr;
1003     }
1004     result->FromString(retStr);
1005     return result;
1006 }
1007 
BatchInsert(const Uri & uri,const std::vector<OHOS::NativeRdb::ValuesBucket> & values,const CallingInfo & callingInfo)1008 int32_t JsiPaEngine::BatchInsert(
1009     const Uri& uri, const std::vector<OHOS::NativeRdb::ValuesBucket>& values, const CallingInfo& callingInfo)
1010 {
1011     LOGI("JsiPaEngine BatchInsert");
1012     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1013     auto nativeEngine = GetNativeEngine();
1014     CHECK_NULL_RETURN(nativeEngine, 0);
1015     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1016     napi_value argColumnsNapiValue = nullptr;
1017     napi_create_array(env, &argColumnsNapiValue);
1018     bool isArray = false;
1019     if (napi_is_array(env, argColumnsNapiValue, &isArray) != napi_ok || !isArray) {
1020         LOGE("JsiPaEngine create array failed");
1021         return 0;
1022     }
1023     int32_t index = 0;
1024     for (auto value : values) {
1025         napi_value result = rdbValueBucketNewInstance_(env, const_cast<OHOS::NativeRdb::ValuesBucket&>(value));
1026         napi_set_element(env, argColumnsNapiValue, index++, result);
1027     }
1028 
1029     std::vector<shared_ptr<JsValue>> argv;
1030     argv.push_back(runtime->NewString(uri.ToString()));
1031     argv.push_back(NapiValueToJsValue(argColumnsNapiValue));
1032     auto func = GetPaFunc("batchInsert");
1033     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1034     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1035     if (arkJSRuntime->HasPendingException()) {
1036         LOGE("JsiPaEngine BatchInsert FAILED!");
1037         return 0;
1038     }
1039     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1040     return arkJSValue->ToInt32(runtime);
1041 }
1042 
Query(const Uri & uri,const std::vector<std::string> & columns,const OHOS::NativeRdb::DataAbilityPredicates & predicates,const CallingInfo & callingInfo)1043 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> JsiPaEngine::Query(const Uri& uri,
1044     const std::vector<std::string>& columns, const OHOS::NativeRdb::DataAbilityPredicates& predicates,
1045     const CallingInfo& callingInfo)
1046 {
1047     LOGI("JsiPaEngine Query");
1048     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> resultSet = nullptr;
1049     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1050     auto nativeEngine = GetNativeEngine();
1051     CHECK_NULL_RETURN(nativeEngine, resultSet);
1052     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1053     napi_value argColumnsNapiValue = nullptr;
1054     napi_create_array(env, &argColumnsNapiValue);
1055     bool isArray = false;
1056     if (napi_is_array(env, argColumnsNapiValue, &isArray) != napi_ok || !isArray) {
1057         LOGE("JsiPaEngine create array failed");
1058         return resultSet;
1059     }
1060     int32_t index = 0;
1061     for (auto column : columns) {
1062         napi_value result = nullptr;
1063         napi_create_string_utf8(env, column.c_str(), column.length(), &result);
1064         napi_set_element(env, argColumnsNapiValue, index++, result);
1065     }
1066 
1067     OHOS::NativeRdb::DataAbilityPredicates* predicatesPtr = new OHOS::NativeRdb::DataAbilityPredicates();
1068     *predicatesPtr = predicates;
1069     napi_value argPredicatesNapiValue = dataAbilityPredicatesNewInstance_(env, predicatesPtr);
1070     if (argPredicatesNapiValue == nullptr) {
1071         LOGE("JsiPaEngine Query argPredicatesNapiValue is nullptr");
1072         return resultSet;
1073     }
1074 
1075     std::vector<shared_ptr<JsValue>> argv;
1076     argv.push_back(runtime->NewString(uri.ToString()));
1077     argv.push_back(NapiValueToJsValue(argColumnsNapiValue));
1078     argv.push_back(NapiValueToJsValue(argPredicatesNapiValue));
1079     auto func = GetPaFunc("query");
1080     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1081 
1082     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1083     if (arkJSRuntime->HasPendingException()) {
1084         LOGE("JsiPaEngine Query FAILED!");
1085         return resultSet;
1086     }
1087     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1088     if (arkJSValue->IsUndefined(runtime)) {
1089         LOGE("JsiPaEngine Query return value is undefined!");
1090         return resultSet;
1091     }
1092 
1093     napi_value napiValue = ArkNativeEngine::ArkValueToNapiValue(env, arkJSValue->GetValue(arkJSRuntime));
1094     if (napiValue == nullptr) {
1095         LOGE("JsiPaEngine nativeValue is nullptr");
1096         return resultSet;
1097     }
1098     resultSet = rdbResultSetProxyGetNativeObject_(env, napiValue);
1099     if (resultSet == nullptr) {
1100         LOGE("JsiPaEngine AbsSharedResultSet from JS to Native failed");
1101     }
1102     return resultSet;
1103 }
1104 
Update(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value,const OHOS::NativeRdb::DataAbilityPredicates & predicates,const CallingInfo & callingInfo)1105 int32_t JsiPaEngine::Update(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value,
1106     const OHOS::NativeRdb::DataAbilityPredicates& predicates, const CallingInfo& callingInfo)
1107 {
1108     LOGI("JsiPaEngine Update");
1109     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1110     auto nativeEngine = GetNativeEngine();
1111     CHECK_NULL_RETURN(nativeEngine, 0);
1112     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1113     napi_value argNapiValue = rdbValueBucketNewInstance_(env, const_cast<OHOS::NativeRdb::ValuesBucket&>(value));
1114 
1115     OHOS::NativeRdb::DataAbilityPredicates* predicatesPtr = new OHOS::NativeRdb::DataAbilityPredicates();
1116     *predicatesPtr = predicates;
1117     napi_value argPredicatesNapiValue = dataAbilityPredicatesNewInstance_(env, predicatesPtr);
1118     if (argPredicatesNapiValue == nullptr) {
1119         LOGE("JsiPaEngine Update argPredicatesNativeValue is nullptr");
1120         return 0;
1121     }
1122 
1123     std::vector<shared_ptr<JsValue>> argv;
1124     argv.push_back(runtime->NewString(uri.ToString()));
1125     argv.push_back(NapiValueToJsValue(argNapiValue));
1126     argv.push_back(NapiValueToJsValue(argPredicatesNapiValue));
1127     auto func = GetPaFunc("update");
1128     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1129 
1130     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1131     if (arkJSRuntime->HasPendingException()) {
1132         LOGE("JsiPaEngine Update FAILED!");
1133         return 0;
1134     }
1135     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1136     return arkJSValue->ToInt32(runtime);
1137 }
1138 
Delete(const Uri & uri,const OHOS::NativeRdb::DataAbilityPredicates & predicates,const CallingInfo & callingInfo)1139 int32_t JsiPaEngine::Delete(
1140     const Uri& uri, const OHOS::NativeRdb::DataAbilityPredicates& predicates, const CallingInfo& callingInfo)
1141 {
1142     LOGI("JsiPaEngine Delete");
1143     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1144     auto nativeEngine = GetNativeEngine();
1145     CHECK_NULL_RETURN(nativeEngine, 0);
1146     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1147     OHOS::NativeRdb::DataAbilityPredicates* predicatesPtr = new OHOS::NativeRdb::DataAbilityPredicates();
1148     *predicatesPtr = predicates;
1149     napi_value argPredicatesNapiValue = dataAbilityPredicatesNewInstance_(env, predicatesPtr);
1150     if (argPredicatesNapiValue == nullptr) {
1151         LOGE("JsiPaEngine Delete argPredicatesNativeValue is nullptr");
1152         return 0;
1153     }
1154 
1155     std::vector<shared_ptr<JsValue>> argv;
1156     argv.push_back(runtime->NewString(uri.ToString()));
1157     argv.push_back(NapiValueToJsValue(argPredicatesNapiValue));
1158     auto func = GetPaFunc("delete");
1159     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1160 
1161     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1162     if (arkJSRuntime->HasPendingException()) {
1163         LOGE("JsiPaEngine Delete FAILED!");
1164         return 0;
1165     }
1166     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1167     return arkJSValue->ToInt32(runtime);
1168 }
1169 
GetType(const Uri & uri,const CallingInfo & callingInfo)1170 std::string JsiPaEngine::GetType(const Uri& uri, const CallingInfo& callingInfo)
1171 {
1172     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1173     std::vector<shared_ptr<JsValue>> argv;
1174     argv.push_back(runtime->NewString(uri.ToString()));
1175     auto func = GetPaFunc("getType");
1176     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1177 
1178     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1179     if (arkJSRuntime->HasPendingException()) {
1180         LOGE("JsiPaEngine GetType FAILED!");
1181         return std::string();
1182     }
1183     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1184     return arkJSValue->ToString(runtime);
1185 }
1186 
GetFileTypes(const Uri & uri,const std::string & mimeTypeFilter,const CallingInfo & callingInfo)1187 std::vector<std::string> JsiPaEngine::GetFileTypes(
1188     const Uri& uri, const std::string& mimeTypeFilter, const CallingInfo& callingInfo)
1189 {
1190     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1191     std::vector<shared_ptr<JsValue>> argv;
1192     argv.push_back(runtime->NewString(uri.ToString()));
1193     argv.push_back(runtime->NewString(mimeTypeFilter));
1194     auto func = GetPaFunc("getFileTypes");
1195     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1196 
1197     std::vector<std::string> ret;
1198     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1199     if (arkJSRuntime->HasPendingException()) {
1200         LOGE("JsiPaEngine GetFileTypes FAILED!");
1201         return ret;
1202     }
1203     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1204     if (!arkJSValue->IsArray(runtime)) {
1205         LOGE("JsiPaEngine GetFileTypes return not array!");
1206         return ret;
1207     }
1208     int32_t length = arkJSValue->GetArrayLength(runtime);
1209     LOGI("JsiPaEngine GetFileTypes array length %{public}d", length);
1210     for (int i = 0; i < length; i++) {
1211         auto itemVal = arkJSValue->GetProperty(runtime, i);
1212         ret.push_back(itemVal->ToString(runtime));
1213     }
1214     return ret;
1215 }
1216 
OpenFile(const Uri & uri,const std::string & mode,const CallingInfo & callingInfo)1217 int32_t JsiPaEngine::OpenFile(const Uri& uri, const std::string& mode, const CallingInfo& callingInfo)
1218 {
1219     LOGI("JsiPaEngine OpenFile");
1220     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1221     std::vector<shared_ptr<JsValue>> argv;
1222     argv.push_back(runtime->NewString(uri.ToString()));
1223     argv.push_back(runtime->NewString(mode));
1224     auto func = GetPaFunc("openFile");
1225     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1226 
1227     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1228     if (arkJSRuntime->HasPendingException()) {
1229         LOGE("JsiPaEngine OpenFile FAILED!");
1230         return 0;
1231     }
1232     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1233     return arkJSValue->ToInt32(runtime);
1234 }
1235 
OpenRawFile(const Uri & uri,const std::string & mode,const CallingInfo & callingInfo)1236 int32_t JsiPaEngine::OpenRawFile(const Uri& uri, const std::string& mode, const CallingInfo& callingInfo)
1237 {
1238     LOGI("JsiPaEngine OpenRawFile");
1239     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1240     std::vector<shared_ptr<JsValue>> argv;
1241     argv.push_back(runtime->NewString(uri.ToString()));
1242     argv.push_back(runtime->NewString(mode));
1243     auto func = GetPaFunc("openRawFile");
1244     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1245 
1246     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1247     if (arkJSRuntime->HasPendingException()) {
1248         LOGE("JsiPaEngine OpenRawFile FAILED!");
1249         return 0;
1250     }
1251     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1252     return arkJSValue->ToInt32(runtime);
1253 }
1254 
NormalizeUri(const Uri & uri,const CallingInfo & callingInfo)1255 Uri JsiPaEngine::NormalizeUri(const Uri& uri, const CallingInfo& callingInfo)
1256 {
1257     LOGI("JsiPaEngine NormalizeUri");
1258     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1259     std::vector<shared_ptr<JsValue>> argv;
1260     argv.push_back(runtime->NewString(uri.ToString()));
1261     auto func = GetPaFunc("normalizeUri");
1262     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1263 
1264     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1265     if (arkJSRuntime->HasPendingException()) {
1266         LOGE("JsiPaEngine NormalizeUri FAILED!");
1267         return Uri("");
1268     }
1269     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1270     return Uri(arkJSValue->ToString(runtime));
1271 }
1272 
DenormalizeUri(const Uri & uri,const CallingInfo & callingInfo)1273 Uri JsiPaEngine::DenormalizeUri(const Uri& uri, const CallingInfo& callingInfo)
1274 {
1275     LOGI("JsiPaEngine DenormalizeUri");
1276     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1277     std::vector<shared_ptr<JsValue>> argv;
1278     argv.push_back(runtime->NewString(uri.ToString()));
1279     auto func = GetPaFunc("denormalizeUri");
1280     shared_ptr<JsValue> retVal = CallAsyncFunc(func, argv, callingInfo);
1281 
1282     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1283     if (arkJSRuntime->HasPendingException()) {
1284         LOGE("JsiPaEngine DenormalizeUri FAILED!");
1285         return Uri("");
1286     }
1287     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1288     return Uri(arkJSValue->ToString(runtime));
1289 }
1290 
OnConnectService(const OHOS::AAFwk::Want & want)1291 sptr<IRemoteObject> JsiPaEngine::OnConnectService(const OHOS::AAFwk::Want& want)
1292 {
1293     ContainerScope scope(instanceId_);
1294     LOGI("JsiPaEngine OnConnectService");
1295     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(GetJsRuntime());
1296     const std::vector<shared_ptr<JsValue>>& argv = { WantToJsValue(want) };
1297     auto func = GetPaFunc("onConnect");
1298     shared_ptr<JsValue> retVal = CallFunc(func, argv);
1299 
1300     if (arkJSRuntime->HasPendingException()) {
1301         LOGE("JsiPaEngine onConnectService FAILED!");
1302         return nullptr;
1303     }
1304 
1305     auto nativeEngine = GetNativeEngine();
1306     CHECK_NULL_RETURN(nativeEngine, nullptr);
1307     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1308     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(retVal);
1309     napi_value nativeValue = ArkNativeEngine::ArkValueToNapiValue(env, arkJSValue->GetValue(arkJSRuntime));
1310     if (nativeValue == nullptr) {
1311         LOGE("JsiPaEngine nativeValue is nullptr");
1312         return nullptr;
1313     }
1314     auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, nativeValue);
1315     return remoteObj;
1316 }
1317 
OnDisconnectService(const OHOS::AAFwk::Want & want)1318 void JsiPaEngine::OnDisconnectService(const OHOS::AAFwk::Want& want)
1319 {
1320     ContainerScope scope(instanceId_);
1321     LOGI("JsiPaEngine OnDisconnectService");
1322     const std::vector<shared_ptr<JsValue>>& argv = { WantToJsValue(want) };
1323     auto func = GetPaFunc("onDisconnect");
1324     CallFunc(func, argv);
1325 }
1326 
OnCommand(const OHOS::AAFwk::Want & want,int startId)1327 void JsiPaEngine::OnCommand(const OHOS::AAFwk::Want& want, int startId)
1328 {
1329     ContainerScope scope(instanceId_);
1330     LOGI("JsiPaEngine OnCommand");
1331     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1332     const std::vector<shared_ptr<JsValue>>& argv = { WantToJsValue(want), runtime->NewInt32(startId) };
1333     auto func = GetPaFunc("onCommand");
1334     CallFunc(func, argv);
1335 }
1336 
OnCreate(const OHOS::AAFwk::Want & want)1337 void JsiPaEngine::OnCreate(const OHOS::AAFwk::Want& want)
1338 {
1339     ContainerScope scope(instanceId_);
1340     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1341 
1342     const std::vector<shared_ptr<JsValue>>& argv = { WantToJsValue(want) };
1343     auto func = GetPaFunc("onCreate");
1344     auto result = CallFuncWithDefaultThis(func, argv);
1345     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1346     if (arkJSRuntime->HasPendingException() || result->IsUndefined(runtime)) {
1347         LOGE("JsiPaEngine CallFunc FAILED!");
1348         return;
1349     }
1350 
1351     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(result);
1352     shared_ptr<JsValue> propertyNames;
1353     int32_t len = 0;
1354     if (!arkJSValue->GetPropertyNames(runtime, propertyNames, len)) {
1355         LOGE("JsiPaEngine StartForm GetPropertyNames error");
1356         return;
1357     }
1358     LOGI("JsiPaEngine onCreate return property num %{public}d", len);
1359 
1360     std::string jsonStr;
1361     shared_ptr<JsValue> formJsonData = arkJSValue->GetProperty(runtime, "data");
1362     if (formJsonData != nullptr) {
1363         jsonStr = formJsonData->ToString(runtime);
1364         LOGI("Add FormBindingData json:%{public}s", jsonStr.c_str());
1365     }
1366     AppExecFwk::FormProviderData formData = AppExecFwk::FormProviderData(jsonStr);
1367     shared_ptr<JsValue> formImageData = arkJSValue->GetProperty(runtime, "image");
1368     if (formImageData != nullptr) {
1369         std::map<std::string, int> rawImageDataMap;
1370         auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1371         auto nativeEngine = GetNativeEngine();
1372         CHECK_NULL_VOID(nativeEngine);
1373         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1374         napi_value napiValue = ArkNativeEngine::ArkValueToNapiValue(
1375             env, std::static_pointer_cast<ArkJSValue>(formImageData)->GetValue(arkJSRuntime));
1376         UnwrapRawImageDataMap(env, napiValue, rawImageDataMap);
1377         for (const auto& data : rawImageDataMap) {
1378             formData.AddImageData(data.first, data.second);
1379         }
1380     }
1381     SetFormData(formData);
1382 }
1383 
OnDelete(const int64_t formId)1384 void JsiPaEngine::OnDelete(const int64_t formId)
1385 {
1386     LOGI("JsiPaEngine OnDelete");
1387     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1388     const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(std::to_string(formId)) };
1389     auto func = GetPaFunc("onDestroy");
1390     CallFuncWithDefaultThis(func, argv);
1391 }
1392 
OnTriggerEvent(const int64_t formId,const std::string & message)1393 void JsiPaEngine::OnTriggerEvent(const int64_t formId, const std::string& message)
1394 {
1395     LOGI("JsiPaEngine OnTriggerEvent");
1396     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1397     const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(std::to_string(formId)),
1398         runtime->NewString(message) };
1399     auto func = GetPaFunc("onEvent");
1400     CallFuncWithDefaultThis(func, argv);
1401 }
1402 
OnUpdate(const int64_t formId)1403 void JsiPaEngine::OnUpdate(const int64_t formId)
1404 {
1405     LOGI("JsiPaEngine OnUpdate");
1406     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1407     const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(std::to_string(formId)) };
1408     auto func = GetPaFunc("onUpdate");
1409     CallFuncWithDefaultThis(func, argv);
1410 }
1411 
OnCastTemptoNormal(const int64_t formId)1412 void JsiPaEngine::OnCastTemptoNormal(const int64_t formId)
1413 {
1414     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1415     const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(std::to_string(formId)) };
1416     auto func = GetPaFunc("onCastToNormal");
1417     CallFuncWithDefaultThis(func, argv);
1418 }
1419 
OnVisibilityChanged(const std::map<int64_t,int32_t> & formEventsMap)1420 void JsiPaEngine::OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap)
1421 {
1422     std::string strJsonResult("{");
1423     for (auto item = formEventsMap.begin(); item != formEventsMap.end(); item++) {
1424         strJsonResult.append(ToJSONStringInt(std::to_string(item->first), std::to_string(item->second)));
1425         strJsonResult.append(",");
1426     }
1427     strJsonResult = strJsonResult.substr(0, strJsonResult.size() - 1);
1428     strJsonResult.append("}");
1429     LOGI("JsiPaEngine strJsonResult = %{public}s", strJsonResult.c_str());
1430 
1431     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1432     const std::vector<shared_ptr<JsValue>>& argv = { runtime->ParseJson(strJsonResult) };
1433     auto func = GetPaFunc("onVisibilityChange");
1434     CallFuncWithDefaultThis(func, argv);
1435 }
1436 
OnAcquireFormState(const OHOS::AAFwk::Want & want)1437 int32_t JsiPaEngine::OnAcquireFormState(const OHOS::AAFwk::Want& want)
1438 {
1439     shared_ptr<JsRuntime> runtime = GetJsRuntime();
1440     const std::vector<shared_ptr<JsValue>>& argv = { WantToJsValue(want) };
1441     auto func = GetPaFunc("onAcquireFormState");
1442     if (func == nullptr) {
1443         LOGW("no OnAcquireFormState!");
1444         return (int32_t)AppExecFwk::FormState::DEFAULT;
1445     }
1446 
1447     auto result = CallFuncWithDefaultThis(func, argv);
1448     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1449     if (arkJSRuntime->HasPendingException()) {
1450         LOGE("JsiPaEngine CallFunc FAILED!");
1451         return (int32_t)AppExecFwk::FormState::DEFAULT;
1452     }
1453 
1454     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(result);
1455     if (!arkJSValue->IsInt32(runtime)) {
1456         LOGE("invalid return value!");
1457         return (int32_t)AppExecFwk::FormState::DEFAULT;
1458     }
1459 
1460     int32_t formState = arkJSValue->ToInt32(runtime);
1461     LOGI("JsiPaEngine OnAcquireFormState, formState: %{public}d", formState);
1462     return formState;
1463 }
1464 
OnShare(int64_t formId,OHOS::AAFwk::WantParams & wantParams)1465 bool JsiPaEngine::OnShare(int64_t formId, OHOS::AAFwk::WantParams& wantParams)
1466 {
1467     auto runtime = GetJsRuntime();
1468     if (runtime == nullptr) {
1469         LOGE("JsiPaEngine JsRuntime Get nullptr!");
1470         return false;
1471     }
1472 
1473     const std::vector<shared_ptr<JsValue>> argv = { runtime->NewString(std::to_string(formId)) };
1474     auto func = GetPaFunc("onShareForm");
1475     if (func == nullptr) {
1476         func = GetPaFunc("onShare");
1477     }
1478     auto result = CallFuncWithDefaultThis(func, argv);
1479     if (result == nullptr) {
1480         LOGE("JsiPaEngine Call function result is nullptr!");
1481         return false;
1482     }
1483 
1484     auto arkJSValue = std::static_pointer_cast<ArkJSValue>(result);
1485     if (arkJSValue == nullptr) {
1486         LOGE("JsiPaEngine JsValue convert failed!");
1487         return false;
1488     }
1489 
1490     auto arkJSRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
1491     if (arkJSRuntime == nullptr) {
1492         LOGE("JsiPaEngine JSRuntime convert failed!");
1493         return false;
1494     }
1495 
1496     if (arkJSRuntime->HasPendingException()) {
1497         LOGE("JsiPaEngine CallFunc FAILED!");
1498         return false;
1499     }
1500 
1501     auto nativeEngine = GetNativeEngine();
1502     CHECK_NULL_RETURN(nativeEngine, false);
1503     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1504     auto napiValue = ArkNativeEngine::ArkValueToNapiValue(env, arkJSValue->GetValue(arkJSRuntime));
1505     if (napiValue == nullptr) {
1506         LOGE("JsiPaEngine nativeValue convert failed!");
1507         return false;
1508     }
1509     napi_valuetype valueType = napi_undefined;
1510     napi_typeof(env, napiValue, &valueType);
1511     if (valueType != napi_object) {
1512         LOGE("napiValue is not napiObject");
1513         return false;
1514     }
1515 
1516     if (!OHOS::AppExecFwk::UnwrapWantParams(env, napiValue, wantParams)) {
1517         LOGE("%{public}s OnShare UnwrapWantParams failed, return false", __func__);
1518         return false;
1519     }
1520     return true;
1521 }
1522 
PostTask(const std::function<void ()> & task,const std::string & name,int64_t delayTime)1523 void JsiPaEngine::PostTask(const std::function<void()>& task, const std::string& name, int64_t delayTime)
1524 {
1525     if (!jsAbilityRuntime_) {
1526         LOGE("Ability runtime is invalid.");
1527         return;
1528     }
1529 
1530     jsAbilityRuntime_->PostTask(task, name, delayTime);
1531 }
1532 
PostSyncTask(const std::function<void ()> & task,const std::string & name)1533 void JsiPaEngine::PostSyncTask(const std::function<void()>& task, const std::string& name)
1534 {
1535     if (!jsAbilityRuntime_) {
1536         LOGE("Ability runtime is invalid.");
1537         return;
1538     }
1539 
1540     jsAbilityRuntime_->PostSyncTask(task, name);
1541 }
1542 
RemoveTask(const std::string & name)1543 void JsiPaEngine::RemoveTask(const std::string& name)
1544 {
1545     if (!jsAbilityRuntime_) {
1546         LOGE("Ability runtime is invalid.");
1547         return;
1548     }
1549 
1550     jsAbilityRuntime_->RemoveTask(name);
1551 }
1552 } // namespace OHOS::Ace
1553