• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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