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