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