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