1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <cstdint>
16
17 #include "hilog_wrapper.h"
18 #include "ipc_skeleton.h"
19 #include "js_plugin_callback.h"
20 #include "js_plugin_callback_mgr.h"
21 #include "js_plugin_util.h"
22 #include "js_plugin_want.h"
23 #include "napi/native_api.h"
24 #include "napi/native_node_api.h"
25
26 #include "core/components/plugin/plugin_component_manager.h"
27
28 namespace OHOS::Ace::Napi {
29 constexpr int ACE_ARGS_MAX_COUNT = 10;
30 constexpr int ACE_ARGS_TWO = 2;
31 constexpr int ACE_ARGS_THREE = 3;
32 constexpr int ACE_PARAM0 = 0;
33 constexpr int ACE_PARAM1 = 1;
34 constexpr int ACE_PARAM2 = 2;
35 constexpr int NAPI_ACE_ERR_ERROR = 1;
36
UnwrapStageWantFromJS(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)37 bool UnwrapStageWantFromJS(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
38 {
39 if (!AceUnwrapWant(env, param, asyncCallbackInfo->wantStage)) {
40 HILOG_INFO("%{public}s called, Params(want stage) is invalid.", __func__);
41 return false;
42 }
43 return true;
44 }
45
UnwrapOwnerWantFromJS(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)46 bool UnwrapOwnerWantFromJS(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
47 {
48 napi_value jsValue = AceGetPropertyValueByPropertyName(env, param, "owner", napi_object);
49 if (jsValue == nullptr) {
50 HILOG_INFO("%{public}s called, Params(want) is not object.", __func__);
51 return false;
52 }
53
54 if (!AceUnwrapWant(env, jsValue, asyncCallbackInfo->wantStage)) {
55 HILOG_INFO("%{public}s called, Params(want) is invalid.", __func__);
56 return false;
57 }
58 return true;
59 }
60
UnwrapWantFromJS(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)61 bool UnwrapWantFromJS(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
62 {
63 napi_value jsValue = AceGetPropertyValueByPropertyName(env, param, "want", napi_object);
64 if (jsValue == nullptr) {
65 HILOG_INFO("%{public}s called, Params(want) is not object.", __func__);
66 return false;
67 }
68
69 if (!AceUnwrapWant(env, jsValue, asyncCallbackInfo->jsParamList.want)) {
70 HILOG_INFO("%{public}s called, Params(want) is invalid.", __func__);
71 return false;
72 }
73 return true;
74 }
75
UnwrapTargetFromJS(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)76 bool UnwrapTargetFromJS(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
77 {
78 napi_value jsValue = AceGetPropertyValueByPropertyName(env, param, "target", napi_object);
79 if (jsValue == nullptr) {
80 HILOG_INFO("%{public}s called, Params(Target) is not object.", __func__);
81 return false;
82 }
83
84 if (!AceUnwrapWant(env, jsValue, asyncCallbackInfo->jsParamList.want)) {
85 HILOG_INFO("%{public}s called, Params(Target) is invalid.", __func__);
86 return false;
87 }
88 return true;
89 }
90
UnwrapNameFromJS(napi_env env,napi_value param,const std::string & key,ACEAsyncJSCallbackInfo * asyncCallbackInfo)91 bool UnwrapNameFromJS(napi_env env, napi_value param, const std::string& key, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
92 {
93 napi_value jsValue = AceGetPropertyValueByPropertyName(env, param, key.c_str(), napi_string);
94 if (jsValue == nullptr) {
95 HILOG_INFO("%{public}s called, Params(%{public}s) is not string.", __func__, key.c_str());
96 return false;
97 }
98
99 std::string strValue = AceUnwrapStringFromJS(env, jsValue);
100 asyncCallbackInfo->jsParamList.paramList.PutStringValue(key, strValue);
101 return true;
102 }
103
UnwrapKVObjectFromJS(napi_env env,napi_value param,const std::string & key,ACEAsyncJSCallbackInfo * asyncCallbackInfo)104 bool UnwrapKVObjectFromJS(napi_env env, napi_value param, const std::string& key,
105 ACEAsyncJSCallbackInfo* asyncCallbackInfo)
106 {
107 napi_value jsValue = AceGetPropertyValueByPropertyName(env, param, key.c_str(), napi_object);
108 if (jsValue == nullptr) {
109 HILOG_INFO("%{public}s called, Params(%{public}s) is not object.", __func__, key.c_str());
110 return false;
111 }
112
113 std::string jsonString("{}");
114 bool ret = AceKVObjectToString(env, jsValue, jsonString);
115 if (ret) {
116 asyncCallbackInfo->jsParamList.paramList.PutStringValue(key, jsonString);
117 }
118 return ret;
119 }
120
UnwrapPushParameters(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)121 bool UnwrapPushParameters(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
122 {
123 if (!AceIsTypeForNapiValue(env, param, napi_object)) {
124 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
125 return false;
126 }
127
128 bool isStageModelAPI = (asyncCallbackInfo->ability == nullptr);
129 if (isStageModelAPI) {
130 if (!UnwrapOwnerWantFromJS(env, param, asyncCallbackInfo)) {
131 HILOG_INFO("%{public}s called, Params(ownerWant) is invalid.", __func__);
132 return false;
133 }
134 }
135
136 if (!UnwrapWantFromJS(env, param, asyncCallbackInfo) && !UnwrapTargetFromJS(env, param, asyncCallbackInfo)) {
137 HILOG_INFO("%{public}s called, Params(want) is invalid.", __func__);
138 return false;
139 }
140 if (!UnwrapNameFromJS(env, param, "name", asyncCallbackInfo)) {
141 HILOG_INFO("%{public}s called, Params(name) is invalid.", __func__);
142 return false;
143 }
144 if (!UnwrapKVObjectFromJS(env, param, "data", asyncCallbackInfo)) {
145 HILOG_INFO("%{public}s called, Params(data) is invalid.", __func__);
146 return false;
147 }
148 if (!UnwrapKVObjectFromJS(env, param, "extraData", asyncCallbackInfo)) {
149 HILOG_INFO("%{public}s called, Params(data) is invalid.", __func__);
150 return false;
151 }
152
153 UnwrapNameFromJS(env, param, "jsonPath", asyncCallbackInfo);
154 return true;
155 }
156
UnwrapParamForPush(napi_env env,size_t argc,napi_value * argv,ACEAsyncJSCallbackInfo * asyncCallbackInfo)157 bool UnwrapParamForPush(napi_env env, size_t argc, napi_value* argv, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
158 {
159 HILOG_INFO("%{public}s called, argc=%{public}zu", __func__, argc);
160 const size_t argcMax = ACE_ARGS_TWO;
161 if (argc <= 0 || argc > argcMax) {
162 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
163 return false;
164 }
165
166 if (!UnwrapPushParameters(env, argv[ACE_PARAM0], asyncCallbackInfo)) {
167 HILOG_INFO("%{public}s called, the first parameter is invalid.", __func__);
168 return false;
169 }
170
171 if (argc == argcMax) {
172 if (!AceCreateAsyncCallback(env, argv[ACE_PARAM1], asyncCallbackInfo)) {
173 HILOG_INFO("%{public}s called, the last parameter is invalid.", __func__);
174 return false;
175 }
176 }
177 return true;
178 }
179
JSPushWork(napi_env env,void * data)180 void JSPushWork(napi_env env, void* data)
181 {
182 HILOG_INFO("%{public}s called.", __func__);
183 }
184
JSPushCompleteAsyncCallbackWork(napi_env env,napi_status status,void * data)185 void JSPushCompleteAsyncCallbackWork(napi_env env, napi_status status, void* data)
186 {
187 HILOG_INFO("%{public}s called.", __func__);
188 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
189 if (asyncCallbackInfo == nullptr) {
190 HILOG_INFO("%{public}s called. asyncCallbackInfo is null", __func__);
191 return;
192 }
193 PluginComponentManager::GetInstance()->Push(asyncCallbackInfo->jsParamList.want,
194 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
195 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath"),
196 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"),
197 asyncCallbackInfo->jsParamList.paramList.GetStringValue("extraData"));
198
199 asyncCallbackInfo->error_code = 0;
200 AceCompleteAsyncCallbackWork(env, status, data);
201 }
202
JSPushCompletePromiseCallbackWork(napi_env env,napi_status status,void * data)203 void JSPushCompletePromiseCallbackWork(napi_env env, napi_status status, void* data)
204 {
205 HILOG_INFO("%{public}s called.", __func__);
206
207 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
208 if (asyncCallbackInfo == nullptr) {
209 HILOG_INFO("%{public}s called, asyncCallbackInfo is null", __func__);
210 return;
211 }
212
213 PluginComponentManager::GetInstance()->Push(asyncCallbackInfo->jsParamList.want,
214 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
215 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath"),
216 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"),
217 asyncCallbackInfo->jsParamList.paramList.GetStringValue("extraData"));
218
219 asyncCallbackInfo->error_code = 0;
220 AceCompletePromiseCallbackWork(env, status, data);
221 }
222
NAPI_JSPushWrap(napi_env env,napi_callback_info info,ACEAsyncJSCallbackInfo * asyncCallbackInfo)223 napi_value NAPI_JSPushWrap(napi_env env, napi_callback_info info, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
224 {
225 HILOG_INFO("%{public}s called.", __func__);
226 size_t argc = ACE_ARGS_MAX_COUNT;
227 napi_value args[ACE_ARGS_MAX_COUNT] = {nullptr};
228 napi_value jsthis = 0;
229 void* data = nullptr;
230
231 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &jsthis, &data));
232 if (!UnwrapParamForPush(env, argc, args, asyncCallbackInfo)) {
233 HILOG_INFO("%{public}s called. Invoke UnwrapParamForPush fail", __func__);
234 return nullptr;
235 }
236 ACEAsyncParamEx asyncParamEx;
237 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
238 HILOG_INFO("%{public}s called. asyncCallback.", __func__);
239 asyncParamEx.resource = "NAPI_JSPushCallback";
240 asyncParamEx.execute = JSPushWork;
241 asyncParamEx.complete = JSPushCompleteAsyncCallbackWork;
242
243 return AceExecuteAsyncCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
244 } else {
245 HILOG_INFO("%{public}s called. promise.", __func__);
246 asyncParamEx.resource = "NAPI_JSPushPromise";
247 asyncParamEx.execute = JSPushWork;
248 asyncParamEx.complete = JSPushCompletePromiseCallbackWork;
249 return AceExecutePromiseCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
250 }
251 }
252
JSPush(napi_env env,napi_callback_info info)253 static napi_value JSPush(napi_env env, napi_callback_info info)
254 {
255 HILOG_INFO("%{public}s called.", __func__);
256
257 ACEAsyncJSCallbackInfo* asyncCallbackInfo = AceCreateAsyncJSCallbackInfo(env);
258 if (asyncCallbackInfo == nullptr) {
259 return AceWrapVoidToJS(env);
260 }
261
262 napi_value rev = NAPI_JSPushWrap(env, info, asyncCallbackInfo);
263 if (rev == nullptr) {
264 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
265 rev = AceWrapVoidToJS(env);
266 }
267 return rev;
268 }
269
UnwrapRequestParameters(napi_env env,napi_value param,ACEAsyncJSCallbackInfo * asyncCallbackInfo)270 bool UnwrapRequestParameters(napi_env env, napi_value param, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
271 {
272 if (!AceIsTypeForNapiValue(env, param, napi_object)) {
273 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
274 return false;
275 }
276
277 bool isStageModelAPI = (asyncCallbackInfo->ability == nullptr);
278 if (isStageModelAPI) {
279 if (!UnwrapOwnerWantFromJS(env, param, asyncCallbackInfo)) {
280 HILOG_INFO("%{public}s called, Params(ownerWant) is invalid.", __func__);
281 return false;
282 }
283 }
284
285 if (!UnwrapWantFromJS(env, param, asyncCallbackInfo) && !UnwrapTargetFromJS(env, param, asyncCallbackInfo)) {
286 HILOG_INFO("%{public}s called, Params(want) is invalid.", __func__);
287 return false;
288 }
289 if (!UnwrapNameFromJS(env, param, "name", asyncCallbackInfo)) {
290 HILOG_INFO("%{public}s called, Params(name) is invalid.", __func__);
291 return false;
292 }
293 if (!UnwrapKVObjectFromJS(env, param, "data", asyncCallbackInfo)) {
294 HILOG_INFO("%{public}s called, Params(data) is invalid.", __func__);
295 return false;
296 }
297
298 UnwrapNameFromJS(env, param, "jsonPath", asyncCallbackInfo);
299 return true;
300 }
301
UnwrapParamForRequest(napi_env env,size_t argc,napi_value * argv,ACEAsyncJSCallbackInfo * asyncCallbackInfo)302 bool UnwrapParamForRequest(napi_env env, size_t argc, napi_value* argv,
303 ACEAsyncJSCallbackInfo* asyncCallbackInfo)
304 {
305 HILOG_INFO("%{public}s called, argc=%{public}zu", __func__, argc);
306 if (argc <= 0 || argc > ACE_ARGS_TWO) {
307 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
308 return false;
309 }
310
311 if (!UnwrapRequestParameters(env, argv[ACE_PARAM0], asyncCallbackInfo)) {
312 HILOG_INFO("%{public}s called, the first parameter is invalid.", __func__);
313 return false;
314 }
315
316 if (argc == ACE_ARGS_TWO) {
317 if (!AceCreateAsyncCallback(env, argv[ACE_PARAM1], asyncCallbackInfo)) {
318 HILOG_INFO("%{public}s called, the last parameter is invalid.", __func__);
319 return false;
320 }
321 }
322 return true;
323 }
324
JSRequestWork(napi_env env,void * data)325 void JSRequestWork(napi_env env, void* data)
326 {
327 HILOG_INFO("%{public}s called.", __func__);
328 }
329
JSRequestPromiseWork(napi_env env,void * data)330 void JSRequestPromiseWork(napi_env env, void* data)
331 {
332 HILOG_INFO("%{public}s called.", __func__);
333 }
334
AceRequestCompleteAsyncCallbackWork(napi_env env,napi_status status,void * data)335 void AceRequestCompleteAsyncCallbackWork(napi_env env, napi_status status, void* data)
336 {
337 HILOG_INFO("%{public}s called.", __func__);
338
339 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
340 if (asyncCallbackInfo == nullptr) {
341 HILOG_INFO("%{public}s called, asyncCallbackInfo is null", __func__);
342 return;
343 }
344
345 if (asyncCallbackInfo->ability != nullptr) {
346 std::shared_ptr<AAFwk::Want> pWant = asyncCallbackInfo->ability->GetWant();
347 asyncCallbackInfo->wantStage = *pWant;
348 } else {
349 int32_t pid = IPCSkeleton::GetCallingPid();
350 asyncCallbackInfo->wantStage.SetBundle("plugin" + std::to_string(pid));
351 }
352
353 std::shared_ptr<AceJSPluginRequestParam> param = std::make_shared<AceJSPluginRequestParam>(
354 asyncCallbackInfo->jsParamList.want,
355 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
356 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"),
357 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath")
358 );
359 if (param != nullptr) {
360 HILOG_INFO("%{public}s called, pWant = %{public}s:%{public}s",
361 __func__, asyncCallbackInfo->wantStage.GetElement().GetBundleName().c_str(),
362 asyncCallbackInfo->wantStage.GetElement().GetAbilityName().c_str());
363 bool ret = JSPluginCallbackMgr::Instance().RegisterRequestEvent(env, asyncCallbackInfo->wantStage,
364 asyncCallbackInfo->cbInfo, param);
365 if (ret) {
366 asyncCallbackInfo->cbInfo.callback = nullptr;
367 }
368 }
369
370 PluginComponentManager::GetInstance()->Request(asyncCallbackInfo->jsParamList.want,
371 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
372 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath"),
373 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"));
374
375 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
376 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
377 }
378
MakePluginTemplateObject(napi_env env,const PluginComponentTemplate & pluginTemplate)379 napi_value MakePluginTemplateObject(napi_env env, const PluginComponentTemplate& pluginTemplate)
380 {
381 HILOG_INFO("%{public}s called.", __func__);
382 napi_value jsPluginTemplate = AceCreateJSObject(env);
383 if (jsPluginTemplate != nullptr) {
384 napi_value jsSource = AceWrapStringToJS(env, pluginTemplate.GetSource());
385 napi_value jsAbility = AceWrapStringToJS(env, pluginTemplate.GetAbility());
386
387 AceSetPropertyValueByPropertyName(env, jsPluginTemplate, "source", jsSource);
388 AceSetPropertyValueByPropertyName(env, jsPluginTemplate, "ability", jsAbility);
389 }
390 return jsPluginTemplate;
391 }
392
MakeCallbackParamForRequest(napi_env env,const PluginComponentTemplate & pluginTemplate,const ACEAsyncJSCallbackInfo * asyncCallbackInfo)393 napi_value MakeCallbackParamForRequest(napi_env env, const PluginComponentTemplate& pluginTemplate,
394 const ACEAsyncJSCallbackInfo* asyncCallbackInfo)
395 {
396 HILOG_INFO("%{public}s called.", __func__);
397 napi_value jsObject = AceCreateJSObject(env);
398 if (jsObject == nullptr) {
399 return nullptr;
400 }
401 HILOG_INFO("%{public}s called. 1111", __func__);
402 std::string dataTmp("{}");
403 std::string extraDataTmp("{}");
404 if (!asyncCallbackInfo->requestCallbackData.data.empty()) {
405 dataTmp = asyncCallbackInfo->requestCallbackData.data;
406 }
407 if (!asyncCallbackInfo->requestCallbackData.extraData.empty()) {
408 extraDataTmp = asyncCallbackInfo->requestCallbackData.extraData;
409 }
410
411 napi_value jsPluginTemplate = MakePluginTemplateObject(env, pluginTemplate);
412 napi_value jsData = AceStringToKVObject(env, dataTmp);
413 napi_value jsExtraData = AceStringToKVObject(env, extraDataTmp);
414
415 if (jsData != nullptr) {
416 HILOG_INFO("%{public}s called. componentTemplate", __func__);
417 AceSetPropertyValueByPropertyName(env, jsObject, "componentTemplate", jsPluginTemplate);
418 }
419 if (jsData != nullptr) {
420 HILOG_INFO("%{public}s called. data", __func__);
421 AceSetPropertyValueByPropertyName(env, jsObject, "data", jsData);
422 }
423 if (jsExtraData != nullptr) {
424 HILOG_INFO("%{public}s called. extraData", __func__);
425 AceSetPropertyValueByPropertyName(env, jsObject, "extraData", jsExtraData);
426 }
427 return jsObject;
428 }
429
TransferRequestCallBackData(napi_env env,ACEAsyncJSCallbackInfo * asyncCallbackInfo)430 napi_value TransferRequestCallBackData(napi_env env, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
431 {
432 HILOG_INFO("%{public}s called.", __func__);
433 PluginComponentTemplate componentTemplate;
434 componentTemplate.SetSource(asyncCallbackInfo->requestCallbackData.sourceName);
435 componentTemplate.SetAbility(asyncCallbackInfo->requestCallbackData.abilityName);
436 napi_value jsResult = MakeCallbackParamForRequest(env, componentTemplate, asyncCallbackInfo);
437 return jsResult;
438 }
439
AceRequestPromiseAsyncCallbackWork(napi_env env,napi_status status,void * data)440 void AceRequestPromiseAsyncCallbackWork(napi_env env, napi_status status, void* data)
441 {
442 HILOG_INFO("%{public}s called.", __func__);
443 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
444 if (asyncCallbackInfo == nullptr) {
445 HILOG_INFO("%{public}s called, asyncCallbackInfo is null", __func__);
446 return;
447 }
448
449 if (asyncCallbackInfo->ability != nullptr) {
450 std::shared_ptr<AAFwk::Want> pWant = asyncCallbackInfo->ability->GetWant();
451 asyncCallbackInfo->wantStage = *pWant;
452 } else {
453 int32_t pid = IPCSkeleton::GetCallingPid();
454 asyncCallbackInfo->wantStage.SetBundle("plugin" + std::to_string(pid));
455 }
456
457 std::shared_ptr<AceJSPluginRequestParam> param = std::make_shared<AceJSPluginRequestParam>(
458 asyncCallbackInfo->jsParamList.want,
459 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
460 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"),
461 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath")
462 );
463 asyncCallbackInfo->onRequestCallbackOK = false;
464
465 if (param != nullptr) {
466 HILOG_INFO("%{public}s called, pWant = %{public}s:%{public}s",
467 __func__, asyncCallbackInfo->wantStage.GetElement().GetBundleName().c_str(),
468 asyncCallbackInfo->wantStage.GetElement().GetAbilityName().c_str());
469 JSPluginCallbackMgr::Instance().RegisterRequestEvent(env, asyncCallbackInfo->wantStage,
470 asyncCallbackInfo, param);
471 }
472
473 PluginComponentManager::GetInstance()->Request(asyncCallbackInfo->jsParamList.want,
474 asyncCallbackInfo->jsParamList.paramList.GetStringValue("name"),
475 asyncCallbackInfo->jsParamList.paramList.GetStringValue("jsonPath"),
476 asyncCallbackInfo->jsParamList.paramList.GetStringValue("data"));
477
478 if (asyncCallbackInfo->onRequestCallbackOK) {
479 asyncCallbackInfo->error_code = 0;
480 napi_resolve_deferred(env, asyncCallbackInfo->deferred, TransferRequestCallBackData(env, asyncCallbackInfo));
481 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
482 } else {
483 asyncCallbackInfo->error_code = NAPI_ACE_ERR_ERROR;
484 AceCompletePromiseCallbackWork(env, status, data);
485 }
486 }
487
NAPI_JSRequestWrap(napi_env env,napi_callback_info info,ACEAsyncJSCallbackInfo * asyncCallbackInfo)488 napi_value NAPI_JSRequestWrap(napi_env env, napi_callback_info info, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
489 {
490 HILOG_INFO("%{public}s called.", __func__);
491 size_t argc = ACE_ARGS_MAX_COUNT;
492 napi_value args[ACE_ARGS_MAX_COUNT] = {nullptr};
493 napi_value jsthis = 0;
494 void* data = nullptr;
495
496 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &jsthis, &data));
497
498 if (!UnwrapParamForRequest(env, argc, args, asyncCallbackInfo)) {
499 HILOG_INFO("%{public}s called. Invoke UnwrapParamForRequest fail", __func__);
500 return nullptr;
501 }
502
503 ACEAsyncParamEx asyncParamEx;
504 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
505 HILOG_INFO("%{public}s called. asyncCallback.", __func__);
506 asyncParamEx.resource = "NAPI_JSRequestCallback";
507 asyncParamEx.execute = JSRequestWork;
508 asyncParamEx.complete = AceRequestCompleteAsyncCallbackWork;
509 return AceExecuteAsyncCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
510 } else {
511 HILOG_INFO("%{public}s called. promise.", __func__);
512 asyncParamEx.resource = "NAPI_JSRequestPromise";
513 asyncParamEx.execute = JSRequestPromiseWork;
514 asyncParamEx.complete = AceRequestPromiseAsyncCallbackWork;
515 return AceExecutePromiseCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
516 }
517 }
518
JSRequest(napi_env env,napi_callback_info info)519 static napi_value JSRequest(napi_env env, napi_callback_info info)
520 {
521 HILOG_INFO("%{public}s called.", __func__);
522
523 ACEAsyncJSCallbackInfo* asyncCallbackInfo = AceCreateAsyncJSCallbackInfo(env);
524 if (asyncCallbackInfo == nullptr) {
525 return AceWrapVoidToJS(env);
526 }
527
528 napi_value rev = NAPI_JSRequestWrap(env, info, asyncCallbackInfo);
529 if (rev == nullptr) {
530 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
531 rev = AceWrapVoidToJS(env);
532 }
533 return rev;
534 }
535
UnwrapParamForOn(napi_env env,size_t argc,napi_value * argv,ACEAsyncJSCallbackInfo * asyncCallbackInfo)536 bool UnwrapParamForOn(napi_env env, size_t argc, napi_value* argv,
537 ACEAsyncJSCallbackInfo* asyncCallbackInfo)
538 {
539 HILOG_INFO("%{public}s called, argc=%{public}zu", __func__, argc);
540
541 const size_t argcMax = ACE_ARGS_THREE;
542 if (argc > argcMax || argc < ACE_ARGS_TWO) {
543 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
544 return false;
545 }
546
547 if (argc == ACE_ARGS_THREE) {
548 if (!UnwrapStageWantFromJS(env, argv[ACE_PARAM0], asyncCallbackInfo)) {
549 HILOG_INFO("%{public}s called, the owner want parameter is invalid.", __func__);
550 return false;
551 }
552
553 std::string eventName = AceUnwrapStringFromJS(env, argv[ACE_PARAM1]);
554 if (eventName == "push" || eventName == "request") {
555 asyncCallbackInfo->jsParamList.paramList.PutStringValue("eventName", eventName);
556 } else {
557 HILOG_INFO("%{public}s called, the first parameter is invalid.", __func__);
558 return false;
559 }
560
561 if (!AceCreateAsyncCallback(env, argv[ACE_PARAM2], asyncCallbackInfo)) {
562 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
563 return false;
564 }
565 } else {
566 std::string eventName = AceUnwrapStringFromJS(env, argv[ACE_PARAM0]);
567 if (eventName == "push" || eventName == "request") {
568 asyncCallbackInfo->jsParamList.paramList.PutStringValue("eventName", eventName);
569 } else {
570 HILOG_INFO("%{public}s called, the first parameter is invalid.", __func__);
571 return false;
572 }
573
574 if (!AceCreateAsyncCallback(env, argv[ACE_PARAM1], asyncCallbackInfo)) {
575 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
576 return false;
577 }
578 }
579 return true;
580 }
581
JSOnWork(napi_env env,void * data)582 void JSOnWork(napi_env env, void* data)
583 {
584 HILOG_INFO("%{public}s called.", __func__);
585 }
586
AceOnCompleteAsyncCallbackWork(napi_env env,napi_status status,void * data)587 void AceOnCompleteAsyncCallbackWork(napi_env env, napi_status status, void* data)
588 {
589 HILOG_INFO("%{public}s called.", __func__);
590
591 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
592 if (asyncCallbackInfo == nullptr) {
593 HILOG_INFO("%{public}s called, asyncCallbackInfo is null", __func__);
594 return;
595 }
596
597 std::string eventName = asyncCallbackInfo->jsParamList.paramList.GetStringValue("eventName");
598 CallBackType eventCallbackType = CallBackType::PushEvent;
599 if (eventName == "request") {
600 eventCallbackType = CallBackType::RequestEvent;
601 }
602
603 if (asyncCallbackInfo->ability != nullptr) {
604 std::shared_ptr<AAFwk::Want> pWant = asyncCallbackInfo->ability->GetWant();
605 asyncCallbackInfo->wantStage = *pWant;
606 } else {
607 int32_t pid = IPCSkeleton::GetCallingPid();
608 asyncCallbackInfo->wantStage.SetBundle("plugin" + std::to_string(pid));
609 }
610
611 bool ret = JSPluginCallbackMgr::Instance().RegisterOnEvent(env, eventCallbackType,
612 asyncCallbackInfo->wantStage, asyncCallbackInfo->cbInfo);
613 if (ret) {
614 asyncCallbackInfo->cbInfo.callback = nullptr;
615 }
616 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
617 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
618 }
619
NAPI_JSOnWrap(napi_env env,napi_callback_info info,ACEAsyncJSCallbackInfo * asyncCallbackInfo)620 napi_value NAPI_JSOnWrap(napi_env env, napi_callback_info info, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
621 {
622 HILOG_INFO("%{public}s called.", __func__);
623 size_t argc = ACE_ARGS_MAX_COUNT;
624 napi_value args[ACE_ARGS_MAX_COUNT] = {nullptr};
625 napi_value jsthis = 0;
626 void* data = nullptr;
627
628 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &jsthis, &data));
629
630 if (!UnwrapParamForOn(env, argc, args, asyncCallbackInfo)) {
631 HILOG_INFO("%{public}s called. Invoke UnwrapParamForOn fail", __func__);
632 return nullptr;
633 }
634
635 ACEAsyncParamEx asyncParamEx;
636 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
637 HILOG_INFO("%{public}s called. asyncCallback.", __func__);
638 asyncParamEx.resource = "NAPI_JSOCallback";
639 asyncParamEx.execute = JSOnWork;
640 asyncParamEx.complete = AceOnCompleteAsyncCallbackWork;
641
642 return AceExecuteAsyncCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
643 } else {
644 HILOG_INFO("%{public}s called. promise.", __func__);
645 asyncParamEx.resource = "NAPI_JSOnPromise";
646 return nullptr;
647 }
648 }
649
JSOn(napi_env env,napi_callback_info info)650 static napi_value JSOn(napi_env env, napi_callback_info info)
651 {
652 HILOG_INFO("%{public}s called.", __func__);
653
654 ACEAsyncJSCallbackInfo* asyncCallbackInfo = AceCreateAsyncJSCallbackInfo(env);
655 if (asyncCallbackInfo == nullptr) {
656 return AceWrapVoidToJS(env);
657 }
658
659 napi_value rev = NAPI_JSOnWrap(env, info, asyncCallbackInfo);
660 if (rev == nullptr) {
661 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
662 rev = AceWrapVoidToJS(env);
663 }
664 return rev;
665 }
666
667
UnwrapParamForOff(napi_env env,size_t argc,napi_value * argv,ACEAsyncJSCallbackInfo * asyncCallbackInfo)668 bool UnwrapParamForOff(napi_env env, size_t argc, napi_value* argv,
669 ACEAsyncJSCallbackInfo* asyncCallbackInfo)
670 {
671 HILOG_INFO("%{public}s called, argc=%{public}zu", __func__, argc);
672
673 if (argc != ACE_ARGS_TWO) {
674 HILOG_INFO("%{public}s called, Params is invalid.", __func__);
675 return false;
676 }
677
678 if (!UnwrapStageWantFromJS(env, argv[ACE_PARAM0], asyncCallbackInfo)) {
679 HILOG_INFO("%{public}s called, the owner want parameter is invalid.", __func__);
680 return false;
681 }
682
683 if (!AceCreateAsyncCallback(env, argv[ACE_PARAM1], asyncCallbackInfo)) {
684 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
685 return false;
686 }
687
688 return true;
689 }
690
JSOffWork(napi_env env,void * data)691 void JSOffWork(napi_env env, void* data)
692 {
693 HILOG_INFO("%{public}s called.", __func__);
694 }
695
AceOffCompleteAsyncCallbackWork(napi_env env,napi_status status,void * data)696 void AceOffCompleteAsyncCallbackWork(napi_env env, napi_status status, void* data)
697 {
698 HILOG_INFO("%{public}s called.", __func__);
699
700 ACEAsyncJSCallbackInfo* asyncCallbackInfo = (ACEAsyncJSCallbackInfo*)data;
701 if (asyncCallbackInfo == nullptr) {
702 HILOG_INFO("%{public}s called, asyncCallbackInfo is null", __func__);
703 return;
704 }
705
706 JSPluginCallbackMgr::Instance().UnregisterCallBack(env, asyncCallbackInfo->wantStage);
707 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
708 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
709 }
710
NAPI_JSOffWrap(napi_env env,napi_callback_info info,ACEAsyncJSCallbackInfo * asyncCallbackInfo)711 napi_value NAPI_JSOffWrap(napi_env env, napi_callback_info info, ACEAsyncJSCallbackInfo* asyncCallbackInfo)
712 {
713 HILOG_INFO("%{public}s called.", __func__);
714 size_t argc = ACE_ARGS_MAX_COUNT;
715 napi_value args[ACE_ARGS_MAX_COUNT] = {nullptr};
716 napi_value jsthis = 0;
717 void* data = nullptr;
718
719 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &jsthis, &data));
720
721 if (!UnwrapParamForOff(env, argc, args, asyncCallbackInfo)) {
722 HILOG_INFO("%{public}s called. Invoke UnwrapParamForOff fail", __func__);
723 return nullptr;
724 }
725
726 ACEAsyncParamEx asyncParamEx;
727 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
728 HILOG_INFO("%{public}s called. asyncCallback.", __func__);
729 asyncParamEx.resource = "NAPI_JSOffCallback";
730 asyncParamEx.execute = JSOffWork;
731 asyncParamEx.complete = AceOffCompleteAsyncCallbackWork;
732
733 return AceExecuteAsyncCallbackWork(env, asyncCallbackInfo, &asyncParamEx);
734 } else {
735 HILOG_INFO("%{public}s called. promise.", __func__);
736 asyncParamEx.resource = "NAPI_JSOffPromise";
737 return nullptr;
738 }
739 }
740
JSOff(napi_env env,napi_callback_info info)741 static napi_value JSOff(napi_env env, napi_callback_info info)
742 {
743 HILOG_INFO("%{public}s called.", __func__);
744
745 ACEAsyncJSCallbackInfo* asyncCallbackInfo = AceCreateAsyncJSCallbackInfo(env);
746 if (asyncCallbackInfo == nullptr) {
747 return AceWrapVoidToJS(env);
748 }
749
750 napi_value rev = NAPI_JSOffWrap(env, info, asyncCallbackInfo);
751 if (rev == nullptr) {
752 AceFreeAsyncJSCallbackInfo(&asyncCallbackInfo);
753 rev = AceWrapVoidToJS(env);
754 }
755 return rev;
756 }
757
PluginComponentEventTypeInit(napi_env env,napi_value exports)758 napi_value PluginComponentEventTypeInit(napi_env env, napi_value exports)
759 {
760 HILOG_INFO("%{public}s, called", __func__);
761
762 napi_value obj = nullptr;
763 napi_create_object(env, &obj);
764
765 AceSetNamedPropertyByString(env, obj, "push", "EVENT_TYPE_PUSH");
766 AceSetNamedPropertyByString(env, obj, "request", "EVENT_TYPE_REQUEST");
767
768 napi_property_descriptor properties[] = {
769 DECLARE_NAPI_PROPERTY("EventType", obj),
770 };
771
772 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
773 return exports;
774 }
775
PluginComponentInit(napi_env env,napi_value exports)776 napi_value PluginComponentInit(napi_env env, napi_value exports)
777 {
778 HILOG_INFO("%{public}s, called", __func__);
779
780 napi_property_descriptor properties[] = {
781 DECLARE_NAPI_FUNCTION("push", JSPush),
782 DECLARE_NAPI_FUNCTION("request", JSRequest),
783 DECLARE_NAPI_FUNCTION("on", JSOn),
784 DECLARE_NAPI_FUNCTION("off", JSOff),
785 };
786
787 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
788 return exports;
789 }
790
PluginComponentExport(napi_env env,napi_value exports)791 static napi_value PluginComponentExport(napi_env env, napi_value exports)
792 {
793 HILOG_INFO("%{public}s, called", __func__);
794
795 PluginComponentEventTypeInit(env, exports);
796 PluginComponentInit(env, exports);
797 return exports;
798 }
799
800 static napi_module PlugInComonentModule = {
801 .nm_version = 1,
802 .nm_flags = 0,
803 .nm_filename = nullptr,
804 .nm_register_func = PluginComponentExport,
805 .nm_modname = "pluginComponent",
806 .nm_priv = ((void*)0),
807 .reserved = { 0 },
808 };
809
RegisterPluginComponent()810 extern "C" __attribute__((constructor)) void RegisterPluginComponent()
811 {
812 napi_module_register(&PlugInComonentModule);
813 }
814 } // namespace OHOS::Ace::Napi
815