• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include <string>
17 
18 #include "distributed_mission_manager.h"
19 
20 #include "ability_manager_client.h"
21 #include "dms_sa_client.h"
22 #include "hilog_wrapper.h"
23 #include "ipc_skeleton.h"
24 #include "napi_common_data.h"
25 #include "napi_common_util.h"
26 #include "napi_common_want.h"
27 #include "napi_remote_object.h"
28 
29 using namespace OHOS::AppExecFwk;
30 
31 namespace OHOS {
32 namespace AAFwk {
33 using AbilityManagerClient = AAFwk::AbilityManagerClient;
34 const std::string TAG = "NAPIMissionRegistration";
35 constexpr size_t VALUE_BUFFER_SIZE = 128;
36 const std::string CODE_KEY_NAME = "code";
37 
GenerateBusinessError(const napi_env & env,int32_t errCode,const std::string & errMsg)38 napi_value GenerateBusinessError(const napi_env &env, int32_t errCode, const std::string &errMsg)
39 {
40     napi_value code = nullptr;
41     napi_create_int32(env, errCode, &code);
42     napi_value msg = nullptr;
43     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msg);
44     napi_value businessError = nullptr;
45     napi_create_error(env, nullptr, msg, &businessError);
46     napi_set_named_property(env, businessError, CODE_KEY_NAME.c_str(), code);
47     return businessError;
48 }
49 
ErrorCodeReturn(int32_t code)50 static int32_t ErrorCodeReturn(int32_t code)
51 {
52     switch (code) {
53         case NO_ERROR:
54             return NO_ERROR;
55         case CHECK_PERMISSION_FAILED:
56             return PERMISSION_DENIED;
57         case DMS_PERMISSION_DENIED:
58             return PERMISSION_DENIED;
59         case ERR_INVALID_VALUE:
60             return PARAMETER_CHECK_FAILED;
61         case INVALID_PARAMETERS_ERR:
62             return PARAMETER_CHECK_FAILED;
63         case REGISTER_REMOTE_MISSION_LISTENER_FAIL:
64             return PARAMETER_CHECK_FAILED;
65         case ABILITY_SERVICE_NOT_CONNECTED:
66             return SYSTEM_WORK_ABNORMALLY;
67         case ERR_NULL_OBJECT:
68             return SYSTEM_WORK_ABNORMALLY;
69         case ERR_FLATTEN_OBJECT:
70             return SYSTEM_WORK_ABNORMALLY;
71         case GET_LOCAL_DEVICE_ERR:
72             return SYSTEM_WORK_ABNORMALLY;
73         case GET_REMOTE_DMS_FAIL:
74             return SYSTEM_WORK_ABNORMALLY;
75         case INNER_ERR:
76             return SYSTEM_WORK_ABNORMALLY;
77         case INVALID_REMOTE_PARAMETERS_ERR:
78             return SYSTEM_WORK_ABNORMALLY;
79         case NO_MISSION_INFO_FOR_MISSION_ID:
80             return NO_MISSION_INFO_FOR_MISSION_ID;
81         case CONTINUE_REMOTE_UNINSTALLED_UNSUPPORT_FREEINSTALL:
82             return REMOTE_UNINSTALLED_AND_UNSUPPORT_FREEINSTALL_FOR_CONTINUE;
83         case CONTINUE_REMOTE_UNINSTALLED_SUPPORT_FREEINSTALL:
84             return CONTINUE_WITHOUT_FREEINSTALL_FLAG;
85         case OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET:
86             return OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET;
87         case CONTINUE_ALREADY_IN_PROGRESS:
88             return CONTINUE_ALREADY_IN_PROGRESS;
89         case MISSION_FOR_CONTINUING_IS_NOT_ALIVE:
90             return MISSION_FOR_CONTINUING_IS_NOT_ALIVE;
91         default:
92             return SYSTEM_WORK_ABNORMALLY;
93     };
94 }
95 
ErrorMessageReturn(int32_t code)96 static std::string ErrorMessageReturn(int32_t code)
97 {
98     switch (code) {
99         case NO_ERROR:
100             return std::string();
101         case PERMISSION_DENIED:
102             return std::string("permission denied");
103         case PARAMETER_CHECK_FAILED:
104             return std::string("parameter check failed.");
105         case SYSTEM_WORK_ABNORMALLY:
106             return std::string("the system ability work abnormally.");
107         case NO_MISSION_INFO_FOR_MISSION_ID:
108             return std::string("failed to get the missionInfo of the specified missionId.");
109         case REMOTE_UNINSTALLED_AND_UNSUPPORT_FREEINSTALL_FOR_CONTINUE:
110             return std::string("the application is not installed on the "
111                 "remote end and installation-free is not supported.");
112         case CONTINUE_WITHOUT_FREEINSTALL_FLAG:
113             return std::string("The application is not installed on the remote end and "
114                 "installation-free is supported. Try again with the freeInstall flag.");
115         case OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET:
116             return std::string("The operation device must be the device where the "
117                 "application to be continued is currently located or the target device.");
118         case CONTINUE_ALREADY_IN_PROGRESS:
119             return std::string("the local continuation task is already in progress.");
120         case MISSION_FOR_CONTINUING_IS_NOT_ALIVE:
121             return std::string("the mission for continuing is not alive, "
122                 "try again after restart this mission.");
123         default:
124             return std::string("the system ability work abnormally.");
125     };
126 }
127 
GetUndefined(const napi_env & env)128 napi_value GetUndefined(const napi_env &env)
129 {
130     napi_value nullResult = nullptr;
131     napi_get_undefined(env, &nullResult);
132     return nullResult;
133 }
134 
SetStartSyncMissionsContext(const napi_env & env,const napi_value & value,SyncRemoteMissionsContext * context,std::string & errInfo)135 bool SetStartSyncMissionsContext(const napi_env &env, const napi_value &value,
136     SyncRemoteMissionsContext* context, std::string &errInfo)
137 {
138     HILOG_INFO("%{public}s call.", __func__);
139     bool isFixConflict = false;
140     napi_has_named_property(env, value, "fixConflict", &isFixConflict);
141     if (!isFixConflict) {
142         HILOG_ERROR("%{public}s, Wrong argument name for fixConflict.", __func__);
143         errInfo = "Parameter error. The key of \"MissionParameter\" must be fixConflict";
144         return false;
145     }
146     napi_value fixConflictValue = nullptr;
147     napi_get_named_property(env, value, "fixConflict", &fixConflictValue);
148     if (fixConflictValue == nullptr) {
149         HILOG_ERROR("%{public}s, not find fixConflict.", __func__);
150         errInfo = "Parameter error. The value of \"fixConflict\" must not be undefined";
151         return false;
152     }
153     napi_valuetype valueType = napi_undefined;
154     napi_typeof(env, fixConflictValue, &valueType);
155     if (valueType != napi_boolean) {
156         HILOG_ERROR("%{public}s, fixConflict error type.", __func__);
157         errInfo = "Parameter error. The type of \"fixConflict\" must be boolean";
158         return false;
159     }
160     napi_get_value_bool(env, fixConflictValue, &context->fixConflict);
161     bool isTag = false;
162     napi_has_named_property(env, value, "tag", &isTag);
163     if (!isTag) {
164         HILOG_ERROR("%{public}s, Wrong argument name for tag.", __func__);
165         errInfo = "Parameter error. The key of \"MissionParameter\" must be tag";
166         return false;
167     }
168     napi_value tagValue = nullptr;
169     napi_get_named_property(env, value, "tag", &tagValue);
170     if (tagValue == nullptr) {
171         HILOG_ERROR("%{public}s, not find tag.", __func__);
172         errInfo = "Parameter error. The value of \"tag\" must not be undefined";
173         return false;
174     }
175     napi_typeof(env, tagValue, &valueType);
176     if (valueType != napi_number) {
177         HILOG_ERROR("%{public}s, tag error type.", __func__);
178         errInfo = "Parameter error. The type of \"tag\" must be number";
179         return false;
180     }
181     napi_get_value_int64(env, tagValue, &context->tag);
182     HILOG_INFO("%{public}s end.", __func__);
183     return true;
184 }
185 
SetSyncRemoteMissionsContext(const napi_env & env,const napi_value & value,bool isStart,SyncRemoteMissionsContext * context,std::string & errInfo)186 bool SetSyncRemoteMissionsContext(const napi_env &env, const napi_value &value,
187     bool isStart, SyncRemoteMissionsContext* context, std::string &errInfo)
188 {
189     HILOG_INFO("%{public}s call.", __func__);
190     napi_valuetype valueType = napi_undefined;
191     napi_typeof(env, value, &valueType);
192     if (valueType != napi_object) {
193         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
194         errInfo = "Parameter error. The type of \"parameter\" must be MissionParameter";
195         return false;
196     }
197     napi_value deviceIdValue = nullptr;
198     bool isDeviceId = false;
199     napi_has_named_property(env, value, "deviceId", &isDeviceId);
200     if (!isDeviceId) {
201         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
202         errInfo = "Parameter error. The key of \"parameter\" must be deviceId";
203         return false;
204     }
205     napi_get_named_property(env, value, "deviceId", &deviceIdValue);
206     if (deviceIdValue == nullptr) {
207         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
208         errInfo = "Parameter error. The value of \"deviceId\" must not be undefined";
209         return false;
210     }
211     napi_typeof(env, deviceIdValue, &valueType);
212     if (valueType != napi_string) {
213         HILOG_ERROR("%{public}s, deviceId error type.", __func__);
214         errInfo = "Parameter error. The type of \"deviceId\" must be string";
215         return false;
216     }
217 
218     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
219     napi_get_value_string_utf8(env, deviceIdValue, deviceId, VALUE_BUFFER_SIZE + 1, &context->valueLen);
220     if (context->valueLen > VALUE_BUFFER_SIZE) {
221         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
222         errInfo = "Parameter error. The length of \"deviceId\" must be less than " +
223             std::to_string(VALUE_BUFFER_SIZE);
224         return false;
225     }
226     context->deviceId = deviceId;
227 
228     if (isStart) {
229         if (!SetStartSyncMissionsContext (env, value, context, errInfo)) {
230             HILOG_ERROR("%{public}s, Wrong argument for start sync.", __func__);
231             return false;
232         }
233     }
234     HILOG_INFO("%{public}s end.", __func__);
235     return true;
236 }
237 
ProcessSyncInput(napi_env & env,napi_callback_info info,bool isStart,SyncRemoteMissionsContext * syncContext,std::string & errInfo)238 bool ProcessSyncInput(napi_env &env, napi_callback_info info, bool isStart,
239     SyncRemoteMissionsContext* syncContext, std::string &errInfo)
240 {
241     HILOG_INFO("%{public}s,called.", __func__);
242     size_t argc = 2;
243     napi_value argv[2] = { nullptr };
244     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
245     if (argc != ARGS_ONE && argc != ARGS_TWO) {
246         HILOG_ERROR("%{public}s, argument size error.", __func__);
247         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2";
248         return false;
249     }
250     syncContext->env = env;
251     if (!SetSyncRemoteMissionsContext(env, argv[0], isStart, syncContext, errInfo)) {
252         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
253         return false;
254     }
255     if (argc == ARGS_TWO) {
256         napi_valuetype valueType = napi_undefined;
257         napi_typeof(env, argv[1], &valueType);
258         if (valueType != napi_function) {
259             HILOG_ERROR("%{public}s, callback error type.", __func__);
260             errInfo = "Parameter error. The type of \"callback\" must be AsynCallback<void>: void";
261             return false;
262         }
263         napi_create_reference(env, argv[1], 1, &syncContext->callbackRef);
264     }
265     HILOG_INFO("%{public}s, end.", __func__);
266     return true;
267 }
268 
StartSyncRemoteMissionsAsyncWork(napi_env & env,const napi_value resourceName,SyncRemoteMissionsContext * syncContext)269 void StartSyncRemoteMissionsAsyncWork(napi_env &env, const napi_value resourceName,
270     SyncRemoteMissionsContext* syncContext)
271 {
272     HILOG_INFO("%{public}s, called.", __func__);
273     napi_create_async_work(env, nullptr, resourceName,
274         [](napi_env env, void* data) {
275             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
276             syncContext->result = AbilityManagerClient::GetInstance()->
277                 StartSyncRemoteMissions(syncContext->deviceId,
278                 syncContext->fixConflict, syncContext->tag);
279         },
280         [](napi_env env, napi_status status, void* data) {
281             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
282             // set result
283             napi_value result[2] = { nullptr };
284             napi_get_undefined(env, &result[1]);
285             if (syncContext->result == 0) {
286                 napi_get_undefined(env, &result[0]);
287             } else {
288                 int32_t errCode = ErrorCodeReturn(syncContext->result);
289                 result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
290             }
291 
292             if (syncContext->callbackRef == nullptr) { // promise
293                 if (syncContext->result == 0) {
294                     napi_resolve_deferred(env, syncContext->deferred, result[1]);
295                 } else {
296                     napi_reject_deferred(env, syncContext->deferred, result[0]);
297                 }
298             } else { // AsyncCallback
299                 napi_value callback = nullptr;
300                 napi_get_reference_value(env, syncContext->callbackRef, &callback);
301                 napi_value callResult;
302                 napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
303                 napi_delete_reference(env, syncContext->callbackRef);
304             }
305             napi_delete_async_work(env, syncContext->work);
306             delete syncContext;
307             syncContext = nullptr;
308         },
309         static_cast<void *>(syncContext),
310         &syncContext->work);
311         napi_queue_async_work_with_qos(env, syncContext->work, napi_qos_user_initiated);
312     HILOG_INFO("%{public}s, end.", __func__);
313 }
314 
NAPI_StartSyncRemoteMissions(napi_env env,napi_callback_info info)315 napi_value NAPI_StartSyncRemoteMissions(napi_env env, napi_callback_info info)
316 {
317     HILOG_INFO("%{public}s, called.", __func__);
318     std::string errInfo = "Parameter error";
319     auto syncContext = new SyncRemoteMissionsContext();
320     if (!ProcessSyncInput(env, info, true, syncContext, errInfo)) {
321         delete syncContext;
322         syncContext = nullptr;
323         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
324         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
325         return GetUndefined(env);
326     }
327     napi_value result = nullptr;
328     if (syncContext->callbackRef == nullptr) {
329         napi_create_promise(env, &syncContext->deferred, &result);
330     } else {
331         napi_get_undefined(env, &result);
332     }
333 
334     napi_value resourceName = nullptr;
335     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
336 
337     StartSyncRemoteMissionsAsyncWork(env, resourceName, syncContext);
338     HILOG_INFO("%{public}s, end.", __func__);
339     return result;
340 }
341 
StopSyncRemoteMissionsAsyncWork(napi_env & env,napi_value resourceName,SyncRemoteMissionsContext * syncContext)342 void StopSyncRemoteMissionsAsyncWork(napi_env &env, napi_value resourceName,
343     SyncRemoteMissionsContext* syncContext)
344 {
345     HILOG_INFO("%{public}s, called.", __func__);
346     napi_create_async_work(env, nullptr, resourceName,
347         [](napi_env env, void* data) {
348             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
349             syncContext->result = AbilityManagerClient::GetInstance()->
350                 StopSyncRemoteMissions(syncContext->deviceId);
351         },
352         [](napi_env env, napi_status status, void* data) {
353             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
354             // set result
355             napi_value result[2] = { nullptr };
356             napi_get_undefined(env, &result[1]);
357             if (syncContext->result == 0) {
358                 napi_get_undefined(env, &result[0]);
359             } else {
360                 int32_t errCode = ErrorCodeReturn(syncContext->result);
361                 result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
362             }
363 
364             if (syncContext->callbackRef == nullptr) { // promise
365                 if (syncContext->result == 0) {
366                     napi_resolve_deferred(env, syncContext->deferred, result[1]);
367                 } else {
368                     napi_reject_deferred(env, syncContext->deferred, result[0]);
369                 }
370             } else { // AsyncCallback
371                 napi_value callback = nullptr;
372                 napi_get_reference_value(env, syncContext->callbackRef, &callback);
373                 napi_value callResult;
374                 napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
375                 napi_delete_reference(env, syncContext->callbackRef);
376             }
377             napi_delete_async_work(env, syncContext->work);
378             delete syncContext;
379             syncContext = nullptr;
380         },
381         static_cast<void *>(syncContext),
382         &syncContext->work);
383         napi_queue_async_work_with_qos(env, syncContext->work, napi_qos_user_initiated);
384     HILOG_INFO("%{public}s, end.", __func__);
385 }
386 
NAPI_StopSyncRemoteMissions(napi_env env,napi_callback_info info)387 napi_value NAPI_StopSyncRemoteMissions(napi_env env, napi_callback_info info)
388 {
389     HILOG_INFO("%{public}s, called.", __func__);
390     std::string errInfo = "Parameter error";
391     auto syncContext = new SyncRemoteMissionsContext();
392     if (!ProcessSyncInput(env, info, false, syncContext, errInfo)) {
393         delete syncContext;
394         syncContext = nullptr;
395         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
396         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
397         return GetUndefined(env);
398     }
399     napi_value result = nullptr;
400     if (syncContext->callbackRef == nullptr) {
401         napi_create_promise(env, &syncContext->deferred, &result);
402     } else {
403         napi_get_undefined(env, &result);
404     }
405 
406     napi_value resourceName = nullptr;
407     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
408 
409     StopSyncRemoteMissionsAsyncWork(env, resourceName, syncContext);
410     HILOG_INFO("%{public}s, end.", __func__);
411     return result;
412 }
413 
CreateRegisterMissionCBCBInfo(napi_env & env)414 RegisterMissionCB *CreateRegisterMissionCBCBInfo(napi_env &env)
415 {
416     HILOG_INFO("%{public}s called.", __func__);
417     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
418     if (registerMissionCB == nullptr) {
419         HILOG_ERROR("%{public}s registerMissionCB == nullptr", __func__);
420         return nullptr;
421     }
422     registerMissionCB->cbBase.cbInfo.env = env;
423     registerMissionCB->cbBase.asyncWork = nullptr;
424     registerMissionCB->cbBase.deferred = nullptr;
425     registerMissionCB->callbackRef = nullptr;
426     HILOG_INFO("%{public}s end.", __func__);
427     return registerMissionCB;
428 }
429 
CreateOnCBCBInfo(napi_env & env)430 OnCB *CreateOnCBCBInfo(napi_env &env)
431 {
432     HILOG_INFO("%{public}s called.", __func__);
433     auto onCB = new (std::nothrow) OnCB;
434     if (onCB == nullptr) {
435         HILOG_ERROR("%{public}s onCB == nullptr", __func__);
436         return nullptr;
437     }
438     onCB->cbBase.cbInfo.env = env;
439     onCB->cbBase.asyncWork = nullptr;
440     onCB->cbBase.deferred = nullptr;
441     onCB->callbackRef = nullptr;
442     HILOG_INFO("%{public}s end.", __func__);
443     return onCB;
444 }
445 
RegisterMissionExecuteCB(napi_env env,void * data)446 void RegisterMissionExecuteCB(napi_env env, void *data)
447 {
448     HILOG_INFO("%{public}s called.", __func__);
449     auto registerMissionCB = (RegisterMissionCB*)data;
450 
451     std::lock_guard<std::mutex> autoLock(registrationLock_);
452     sptr<NAPIRemoteMissionListener> registration;
453     auto item = registration_.find(registerMissionCB->deviceId);
454     if (item != registration_.end()) {
455         HILOG_INFO("registration exits.");
456         registration = registration_[registerMissionCB->deviceId];
457     } else {
458         HILOG_INFO("registration not exits.");
459         registration = new (std::nothrow) NAPIRemoteMissionListener();
460     }
461     registerMissionCB->missionRegistration = registration;
462     if (registerMissionCB->missionRegistration == nullptr) {
463         HILOG_ERROR("%{public}s missionRegistration == nullptr.", __func__);
464         registerMissionCB->result = -1;
465         return;
466     }
467     registerMissionCB->missionRegistration->SetEnv(env);
468     registerMissionCB->missionRegistration->
469         SetNotifyMissionsChangedCBRef(registerMissionCB->missionRegistrationCB.callback[0]);
470     registerMissionCB->missionRegistration->
471         SetNotifySnapshotCBRef(registerMissionCB->missionRegistrationCB.callback[1]);
472     registerMissionCB->missionRegistration->
473         SetNotifyNetDisconnectCBRef(registerMissionCB->
474             missionRegistrationCB.callback[2]); // 2 refers the second argument
475     HILOG_INFO("set callback success.");
476 
477     registerMissionCB->result =
478         AbilityManagerClient::GetInstance()->
479         RegisterMissionListener(registerMissionCB->deviceId,
480         registerMissionCB->missionRegistration);
481     if (registerMissionCB->result == NO_ERROR) {
482         HILOG_INFO("add registration.");
483         registration_[registerMissionCB->deviceId] = registration;
484     }
485     HILOG_DEBUG("%{public}s end.deviceId:%{public}d ", __func__, registerMissionCB->result);
486 }
487 
RegisterMissionCallbackCompletedCB(napi_env env,napi_status status,void * data)488 void RegisterMissionCallbackCompletedCB(napi_env env, napi_status status, void *data)
489 {
490     HILOG_INFO("%{public}s called.", __func__);
491     auto registerMissionCB = static_cast<RegisterMissionCB *>(data);
492     // set result
493     napi_value result[2] = { nullptr };
494     napi_get_undefined(env, &result[1]);
495     if (registerMissionCB->result == 0) {
496         napi_get_undefined(env, &result[0]);
497     } else {
498         int32_t errCode = ErrorCodeReturn(registerMissionCB->result);
499         result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
500     }
501 
502     ReturnValueToApplication(env, &result[0], registerMissionCB);
503     delete registerMissionCB;
504     registerMissionCB = nullptr;
505     HILOG_INFO("%{public}s end.", __func__);
506 }
507 
ReturnValueToApplication(napi_env & env,napi_value * result,RegisterMissionCB * registerMissionCB)508 void ReturnValueToApplication(napi_env &env, napi_value *result, RegisterMissionCB *registerMissionCB)
509 {
510     if (registerMissionCB->callbackRef == nullptr) { // promise
511         if (registerMissionCB->result == 0) {
512             napi_resolve_deferred(env, registerMissionCB->cbBase.deferred, result[1]);
513         } else {
514             napi_reject_deferred(env, registerMissionCB->cbBase.deferred, result[0]);
515         }
516     } else { // AsyncCallback
517         napi_value callback = nullptr;
518         napi_get_reference_value(env, registerMissionCB->callbackRef, &callback);
519         napi_value callResult;
520         napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
521         napi_delete_reference(env, registerMissionCB->callbackRef);
522     }
523     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, registerMissionCB->cbBase.asyncWork));
524 }
525 
RegisterMissionAsync(napi_env env,RegisterMissionCB * registerMissionCB)526 napi_value RegisterMissionAsync(napi_env env, RegisterMissionCB *registerMissionCB)
527 {
528     HILOG_INFO("%{public}s asyncCallback.", __func__);
529     if (registerMissionCB == nullptr) {
530         HILOG_ERROR("%{public}s, registerMissionCB == nullptr.", __func__);
531         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
532         return nullptr;
533     }
534     napi_value result = nullptr;
535     if (registerMissionCB->callbackRef == nullptr) {
536         napi_create_promise(env, &registerMissionCB->cbBase.deferred, &result);
537     } else {
538         napi_get_undefined(env, &result);
539     }
540     napi_value resourceName = nullptr;
541     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
542 
543     napi_create_async_work(env,
544         nullptr,
545         resourceName,
546         RegisterMissionExecuteCB,
547         RegisterMissionCallbackCompletedCB,
548         static_cast<void *>(registerMissionCB),
549         &registerMissionCB->cbBase.asyncWork);
550     napi_queue_async_work(env, registerMissionCB->cbBase.asyncWork);
551     HILOG_INFO("%{public}s asyncCallback end.", __func__);
552     return result;
553 }
554 
CheckMissionCallbackProperty(napi_env & env,const napi_value & value,std::string & errInfo)555 bool CheckMissionCallbackProperty(napi_env &env, const napi_value &value, std::string &errInfo)
556 {
557     HILOG_INFO("%{public}s called.", __func__);
558     bool isFirstCallback = false;
559     napi_has_named_property(env, value, "notifyMissionsChanged", &isFirstCallback);
560     bool isSecondCallback = false;
561     napi_has_named_property(env, value, "notifySnapshot", &isSecondCallback);
562     bool isThirdCallback = false;
563     napi_has_named_property(env, value, "notifyNetDisconnect", &isThirdCallback);
564     if (!isFirstCallback || !isSecondCallback || !isThirdCallback) {
565         HILOG_ERROR("%{public}s, Wrong argument name for callback.", __func__);
566         errInfo = "Parameter error. The type of \"options\" must be MissionCallback";
567         return false;
568     }
569     HILOG_INFO("%{public}s called end.", __func__);
570     return true;
571 }
572 
SetCallbackReference(napi_env & env,const napi_value & value,RegisterMissionCB * registerMissionCB,std::string & errInfo)573 bool SetCallbackReference(napi_env &env, const napi_value &value,
574     RegisterMissionCB *registerMissionCB, std::string &errInfo)
575 {
576     HILOG_INFO("%{public}s called.", __func__);
577     if (!CheckMissionCallbackProperty(env, value, errInfo)) {
578         return false;
579     }
580     napi_value jsMethod = nullptr;
581     napi_get_named_property(env, value, "notifyMissionsChanged", &jsMethod);
582     if (jsMethod == nullptr) {
583         HILOG_ERROR("%{public}s, not find callback notifyMissionsChanged.", __func__);
584         errInfo = "Parameter error. The value of \"notifyMissionsChanged\" must not be undefined";
585         return false;
586     }
587     napi_valuetype valuetype = napi_undefined;
588     napi_typeof(env, jsMethod, &valuetype);
589     if (valuetype != napi_function) {
590         HILOG_ERROR("%{public}s, notifyMissionsChanged callback error type.", __func__);
591         errInfo = "Parameter error. The type of \"notifyMissionsChanged\" must be function";
592         return false;
593     }
594     napi_create_reference(env, jsMethod, 1, &registerMissionCB->missionRegistrationCB.callback[0]);
595     napi_get_named_property(env, value, "notifySnapshot", &jsMethod);
596     if (jsMethod == nullptr) {
597         HILOG_ERROR("%{public}s, not find callback notifySnapshot.", __func__);
598         errInfo = "Parameter error. The value of \"notifySnapshot\" must not be undefined";
599         return false;
600     }
601     napi_typeof(env, jsMethod, &valuetype);
602     if (valuetype != napi_function) {
603         HILOG_ERROR("%{public}s, notifySnapshot callback error type.", __func__);
604         errInfo = "Parameter error. The type of \"notifySnapshot\" must be function";
605         return false;
606     }
607     napi_create_reference(env, jsMethod, 1, &registerMissionCB->missionRegistrationCB.callback[1]);
608     napi_get_named_property(env, value, "notifyNetDisconnect", &jsMethod);
609     if (jsMethod == nullptr) {
610         HILOG_ERROR("%{public}s, not find callback notifyNetDisconnect.", __func__);
611         errInfo = "Parameter error. The value of \"notifyNetDisconnect\" must not be undefined";
612         return false;
613     }
614     napi_typeof(env, jsMethod, &valuetype);
615     if (valuetype != napi_function) {
616         HILOG_ERROR("%{public}s, notifyNetDisconnect callback error type.", __func__);
617         errInfo = "Parameter error. The type of \"notifyNetDisconnect\" must be function";
618         return false;
619     }
620     // 2 refers the second argument
621     napi_create_reference(env, jsMethod, 1, &registerMissionCB->missionRegistrationCB.callback[2]);
622     HILOG_INFO("%{public}s called end.", __func__);
623     return true;
624 }
625 
CreateCallbackReference(napi_env & env,const napi_value & value,RegisterMissionCB * registerMissionCB,std::string & errInfo)626 bool CreateCallbackReference(napi_env &env, const napi_value &value,
627     RegisterMissionCB *registerMissionCB, std::string &errInfo)
628 {
629     HILOG_INFO("%{public}s called.", __func__);
630     napi_valuetype valuetype = napi_undefined;
631     napi_typeof(env, value, &valuetype);
632     if (valuetype == napi_object) {
633         if (!SetCallbackReference(env, value, registerMissionCB, errInfo)) {
634             HILOG_ERROR("%{public}s, Wrong callback.", __func__);
635             return false;
636         }
637     } else {
638         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
639         errInfo = "Parameter error. The type of \"options\" must be MissionCallback";
640         return false;
641     }
642     HILOG_INFO("%{public}s called end.", __func__);
643     return true;
644 }
645 
CreateOnCallbackReference(napi_env & env,const napi_value & jsMethod,OnCB * onCB,std::string & errInfo)646 bool CreateOnCallbackReference(napi_env &env, const napi_value &jsMethod,
647     OnCB *onCB, std::string &errInfo)
648 {
649     HILOG_INFO("%{public}s called.", __func__);
650     napi_valuetype valuetype = napi_undefined;
651     napi_typeof(env, jsMethod, &valuetype);
652     if (valuetype != napi_function) {
653         HILOG_ERROR("%{public}s, onCallback error type.", __func__);
654         errInfo = "Parameter error. The type of \"onCallback\" must be function";
655         return false;
656     }
657     napi_create_reference(env, jsMethod, 1, &onCB->onCallbackCB.callback);
658     napi_create_reference(env, jsMethod, 1, &onCB->callbackRef);
659     HILOG_INFO("%{public}s called end.", __func__);
660     return true;
661 }
662 
RegisterMissionWrapDeviceId(napi_env & env,napi_value & argc,RegisterMissionCB * registerMissionCB,std::string & errInfo)663 bool RegisterMissionWrapDeviceId(napi_env &env, napi_value &argc,
664     RegisterMissionCB *registerMissionCB, std::string &errInfo)
665 {
666     napi_valuetype valueType = napi_undefined;
667     bool isDeviceId = false;
668     napi_has_named_property(env, argc, "deviceId", &isDeviceId);
669     napi_typeof(env, argc, &valueType);
670     if (!isDeviceId || valueType != napi_object) {
671         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
672         errInfo = "Parameter error. The key of \"MissionDeviceInfo\" must be deviceId";
673         return false;
674     }
675 
676     napi_value napiDeviceId = nullptr;
677     napi_get_named_property(env, argc, "deviceId", &napiDeviceId);
678     if (napiDeviceId == nullptr) {
679         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
680         errInfo = "Parameter error. The value of \"deviceId\" must not be undefined";
681         return false;
682     }
683     napi_typeof(env, napiDeviceId, &valueType);
684     if (valueType != napi_string) {
685         HILOG_ERROR("%{public}s, deviceId error type.", __func__);
686         errInfo = "Parameter error. The type of \"deviceId\" must be string";
687         return false;
688     }
689     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
690     size_t valueLen = 0;
691     napi_get_value_string_utf8(env, napiDeviceId, deviceId, VALUE_BUFFER_SIZE + 1, &valueLen);
692     if (valueLen > VALUE_BUFFER_SIZE) {
693         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
694         errInfo = "Parameter error. The length of \"deviceId\" must be less than " +
695             std::to_string(VALUE_BUFFER_SIZE);
696         return false;
697     }
698     registerMissionCB->deviceId = std::string(deviceId);
699     return true;
700 }
701 
OnWrapType(napi_env & env,napi_value & argc,OnCB * onCB,std::string & errInfo)702 bool OnWrapType(napi_env &env, napi_value &argc,
703     OnCB *onCB, std::string &errInfo)
704 {
705     napi_valuetype valueType = napi_undefined;
706     napi_typeof(env, argc, &valueType);
707     if (valueType != napi_string) {
708         HILOG_ERROR("%{public}s, Wrong argument name for type.", __func__);
709         errInfo = "Parameter error. The type of \"type\" must be string";
710         return false;
711     }
712     std::string type = AppExecFwk::UnwrapStringFromJS(env, argc, "");
713     if (type != "continueStateChange") {
714         HILOG_ERROR("%{public}s, not find type.", __func__);
715         errInfo = "Parameter error. The value of \"type\" must not be continueStateChange";
716         return false;
717     }
718     onCB->type = type;
719     return true;
720 }
721 
RegisterMissionWrap(napi_env & env,napi_callback_info info,RegisterMissionCB * registerMissionCB,std::string & errInfo)722 napi_value RegisterMissionWrap(napi_env &env, napi_callback_info info,
723     RegisterMissionCB *registerMissionCB, std::string &errInfo)
724 {
725     HILOG_INFO("%{public}s called.", __func__);
726     size_t argcAsync = 3;
727     napi_value args[ARGS_MAX_COUNT] = {nullptr};
728     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
729     if (argcAsync != ARGS_TWO && argcAsync != ARGS_THREE) {
730         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
731         errInfo = "Parameter error. The type of \"number of parameters\" must be 2 or 3";
732         return nullptr;
733     }
734 
735     if (!RegisterMissionWrapDeviceId(env, args[0], registerMissionCB, errInfo)) {
736         HILOG_INFO("%{public}s, RegisterMissionWrapDeviceId failed.", __func__);
737         return nullptr;
738     }
739     if (argcAsync > 1 && !CreateCallbackReference(env, args[1], registerMissionCB, errInfo)) {
740         return nullptr;
741     }
742     napi_valuetype valueType = napi_undefined;
743     if (argcAsync == ARGS_THREE) {
744         napi_typeof(env, args[ARGS_TWO], &valueType);
745         if (valueType != napi_function) {
746             HILOG_ERROR("%{public}s, callback error type.", __func__);
747             errInfo = "Parameter error. The type of \"options\" must be MissionCallback";
748             return nullptr;
749         }
750         napi_create_reference(env, args[ARGS_TWO], 1, &registerMissionCB->callbackRef);
751     }
752 
753     napi_value ret = RegisterMissionAsync(env, registerMissionCB);
754     HILOG_INFO("%{public}s called end.", __func__);
755     return ret;
756 }
757 
OnExecuteCB(napi_env & env,OnCB * onCB)758 void OnExecuteCB(napi_env &env, OnCB *onCB)
759 {
760     HILOG_INFO("%{public}s called.", __func__);
761     std::lock_guard<std::mutex> autoLock(onLock_);
762     sptr<NAPIRemoteOnListener> registrationOfOn;
763     auto item = registrationOfOn_.find(onCB->type);
764     if (item != registrationOfOn_.end()) {
765         HILOG_INFO("registrationOfOn exits.");
766         registrationOfOn = registrationOfOn_[onCB->type];
767     } else {
768         HILOG_INFO("registrationOfOn not exits.");
769         registrationOfOn = new (std::nothrow) NAPIRemoteOnListener();
770     }
771     onCB->onRegistration = registrationOfOn;
772     if (onCB->onRegistration == nullptr) {
773         HILOG_ERROR("%{public}s onRegistration == nullptr.", __func__);
774         onCB->result = -1;
775         int32_t errCode = ErrorCodeReturn(onCB->result);
776         napi_throw(env, GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode)));
777         return;
778     }
779     onCB->onRegistration->SetEnv(env);
780     onCB->onRegistration->
781         SetOnCallbackCBRef(onCB->onCallbackCB.callback);
782     HILOG_INFO("set callback success.");
783     onCB->result = DmsSaClient::GetInstance().AddListener(onCB->type, onCB->onRegistration);
784     if (onCB->result == NO_ERROR) {
785         HILOG_INFO("add registrationOfOn success.");
786         registrationOfOn_[onCB->type] = registrationOfOn;
787     } else {
788         HILOG_INFO("add registrationOfOn failed");
789     }
790     HILOG_INFO("%{public}s called end.", __func__);
791 }
792 
OnWrap(napi_env & env,napi_callback_info info,OnCB * onCB,std::string & errInfo)793 napi_value OnWrap(napi_env &env, napi_callback_info info,
794     OnCB *onCB, std::string &errInfo)
795 {
796     HILOG_INFO("%{public}s called.", __func__);
797     size_t argcAsync = 2;
798     napi_value args[ARGS_MAX_COUNT] = {nullptr};
799     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
800     if (argcAsync != ARGS_TWO) {
801         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
802         errInfo = "Parameter error. The type of \"number of parameters\" must be 2";
803         return nullptr;
804     }
805     if (!OnWrapType(env, args[0], onCB, errInfo)) {
806         HILOG_INFO("%{public}s, OnWrapType failed.", __func__);
807         return nullptr;
808     }
809     if (!CreateOnCallbackReference(env, args[1], onCB, errInfo)) {
810         return nullptr;
811     }
812     OnExecuteCB(env, onCB);
813     if (onCB->result != 0) {
814         int32_t errCode = ErrorCodeReturn(onCB->result);
815         napi_throw(env, GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode)));
816     }
817     if (onCB->callbackRef != nullptr) {
818         napi_delete_reference(env, onCB->callbackRef);
819     }
820     napi_value result = nullptr;
821     napi_get_undefined(env, &result);
822     HILOG_INFO("%{public}s called end.", __func__);
823     return result;
824 }
825 
OffExecuteCB(napi_env env,OnCB * onCB)826 void OffExecuteCB(napi_env env, OnCB *onCB)
827 {
828     HILOG_INFO("%{public}s called.", __func__);
829     std::lock_guard<std::mutex> autoLock(onLock_);
830     sptr<NAPIRemoteOnListener> registrationOfOn;
831     auto item = registrationOfOn_.find(onCB->type);
832     if (item != registrationOfOn_.end()) {
833         HILOG_INFO("registrationOfOff exits.");
834         registrationOfOn = registrationOfOn_[onCB->type];
835     } else {
836         HILOG_INFO("registrationOfOff not exits.");
837         onCB->result = -1;
838         return;
839     }
840     onCB->onRegistration = registrationOfOn;
841     DmsSaClient::GetInstance().DelListener(onCB->type, onCB->onRegistration);
842     if (onCB->result == NO_ERROR) {
843         HILOG_INFO("remove registration.");
844         registrationOfOn_.erase(onCB->type);
845     }
846     HILOG_DEBUG("%{public}s end.type:%{public}d ", __func__, onCB->result);
847 }
848 
OffWrap(napi_env & env,napi_callback_info info,OnCB * onCB,std::string & errInfo)849 napi_value OffWrap(napi_env &env, napi_callback_info info,
850     OnCB *onCB, std::string &errInfo)
851 {
852     HILOG_INFO("%{public}s called.", __func__);
853     size_t argcAsync = 2;
854     napi_value args[ARGS_MAX_COUNT] = {nullptr};
855     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
856     if (argcAsync != ARGS_ONE && argcAsync != ARGS_TWO) {
857         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
858         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2";
859         return nullptr;
860     }
861     if (!OnWrapType(env, args[0], onCB, errInfo)) {
862         HILOG_INFO("%{public}s, OffWrapType failed.", __func__);
863         return nullptr;
864     }
865     if (argcAsync == ARGS_TWO && !CreateOnCallbackReference(env, args[1], onCB, errInfo)) {
866         return nullptr;
867     }
868     OffExecuteCB(env, onCB);
869     if (onCB->result != 0) {
870         int32_t errCode = ErrorCodeReturn(onCB->result);
871         napi_throw(env, GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode)));
872     }
873     if (onCB->callbackRef != nullptr) {
874         napi_delete_reference(env, onCB->callbackRef);
875     }
876     napi_value result = nullptr;
877     napi_get_undefined(env, &result);
878     HILOG_INFO("%{public}s called end.", __func__);
879     return result;
880 }
881 
NAPI_RegisterMissionListener(napi_env env,napi_callback_info info)882 napi_value NAPI_RegisterMissionListener(napi_env env, napi_callback_info info)
883 {
884     HILOG_INFO("%{public}s called.", __func__);
885     std::string errInfo = "Parameter error";
886     RegisterMissionCB *registerMissionCB = CreateRegisterMissionCBCBInfo(env);
887     if (registerMissionCB == nullptr) {
888         HILOG_ERROR("%{public}s registerMissionCB == nullptr", __func__);
889         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
890         return GetUndefined(env);
891     }
892 
893     napi_value ret = RegisterMissionWrap(env, info, registerMissionCB, errInfo);
894     if (ret == nullptr) {
895         HILOG_ERROR("%{public}s ret == nullptr", __func__);
896         delete registerMissionCB;
897         registerMissionCB = nullptr;
898         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
899         return GetUndefined(env);
900     }
901     HILOG_INFO("%{public}s end.", __func__);
902     return ret;
903 }
904 
NAPI_On(napi_env env,napi_callback_info info)905 napi_value NAPI_On(napi_env env, napi_callback_info info)
906 {
907     HILOG_INFO("%{public}s called.", __func__);
908     std::string errInfo = "Parameter error";
909     OnCB *onCB = CreateOnCBCBInfo(env);
910     if (onCB == nullptr) {
911         HILOG_ERROR("%{public}s onCB == nullptr", __func__);
912         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
913         return GetUndefined(env);
914     }
915 
916     napi_value ret = OnWrap(env, info, onCB, errInfo);
917     if (ret == nullptr) {
918         HILOG_ERROR("%{public}s ret == nullptr", __func__);
919         delete onCB;
920         onCB = nullptr;
921         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
922         return GetUndefined(env);
923     }
924     HILOG_INFO("%{public}s end.", __func__);
925     return ret;
926 }
927 
NAPI_Off(napi_env env,napi_callback_info info)928 napi_value NAPI_Off(napi_env env, napi_callback_info info)
929 {
930     HILOG_INFO("%{public}s called.", __func__);
931     std::string errInfo = "Parameter error";
932     OnCB *onCB = CreateOnCBCBInfo(env);
933     if (onCB == nullptr) {
934         HILOG_ERROR("%{public}s onCB == nullptr", __func__);
935         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
936         return GetUndefined(env);
937     }
938 
939     napi_value ret = OffWrap(env, info, onCB, errInfo);
940     if (ret == nullptr) {
941         HILOG_ERROR("%{public}s ret == nullptr", __func__);
942         delete onCB;
943         onCB = nullptr;
944         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
945         return GetUndefined(env);
946     }
947     HILOG_INFO("%{public}s end.", __func__);
948     return ret;
949 }
950 
NAPI_ContinueState(napi_env env)951 napi_value NAPI_ContinueState(napi_env env)
952 {
953     HILOG_INFO("%{public}s called.", __func__);
954     napi_value continueState = nullptr;
955     napi_create_object(env, &continueState);
956     napi_value active = nullptr;
957     napi_value inActive = nullptr;
958     napi_create_int32(env, 0, &active);
959     napi_create_int32(env, 1, &inActive);
960     napi_set_named_property(env, continueState, "ACTIVE", active);
961     napi_set_named_property(env, continueState, "INACTIVE", inActive);
962     HILOG_INFO("%{public}s end.", __func__);
963     return continueState;
964 }
965 
SetEnv(const napi_env & env)966 void NAPIMissionContinue::SetEnv(const napi_env &env)
967 {
968     env_ = env;
969 }
970 
~NAPIRemoteMissionListener()971 NAPIRemoteMissionListener::~NAPIRemoteMissionListener()
972 {
973     if (env_ == nullptr) {
974         return;
975     }
976     if (notifyMissionsChangedRef_ != nullptr) {
977         napi_delete_reference(env_, notifyMissionsChangedRef_);
978         notifyMissionsChangedRef_ = nullptr;
979     }
980     if (notifySnapshotRef_ != nullptr) {
981         napi_delete_reference(env_, notifySnapshotRef_);
982         notifySnapshotRef_ = nullptr;
983     }
984     if (notifyNetDisconnectRef_ != nullptr) {
985         napi_delete_reference(env_, notifyNetDisconnectRef_);
986         notifyNetDisconnectRef_ = nullptr;
987     }
988 }
989 
~NAPIRemoteOnListener()990 NAPIRemoteOnListener::~NAPIRemoteOnListener()
991 {
992     if (env_ == nullptr) {
993         return;
994     }
995     if (onCallbackRef_ != nullptr) {
996         napi_delete_reference(env_, onCallbackRef_);
997         onCallbackRef_ = nullptr;
998     }
999 }
1000 
SetEnv(const napi_env & env)1001 void NAPIRemoteMissionListener::SetEnv(const napi_env &env)
1002 {
1003     env_ = env;
1004 }
1005 
SetEnv(const napi_env & env)1006 void NAPIRemoteOnListener::SetEnv(const napi_env &env)
1007 {
1008     env_ = env;
1009 }
1010 
SetNotifyMissionsChangedCBRef(const napi_ref & ref)1011 void NAPIRemoteMissionListener::SetNotifyMissionsChangedCBRef(const napi_ref &ref)
1012 {
1013     notifyMissionsChangedRef_ = ref;
1014 }
1015 
SetOnCallbackCBRef(const napi_ref & ref)1016 void NAPIRemoteOnListener::SetOnCallbackCBRef(const napi_ref &ref)
1017 {
1018     onCallbackRef_ = ref;
1019 }
1020 
SetNotifySnapshotCBRef(const napi_ref & ref)1021 void NAPIRemoteMissionListener::SetNotifySnapshotCBRef(const napi_ref &ref)
1022 {
1023     notifySnapshotRef_ = ref;
1024 }
1025 
SetNotifyNetDisconnectCBRef(const napi_ref & ref)1026 void NAPIRemoteMissionListener::SetNotifyNetDisconnectCBRef(const napi_ref &ref)
1027 {
1028     notifyNetDisconnectRef_ = ref;
1029 }
1030 
UvWorkNotifyMissionChanged(uv_work_t * work,int status)1031 void UvWorkNotifyMissionChanged(uv_work_t *work, int status)
1032 {
1033     HILOG_INFO("UvWorkNotifyMissionChanged, uv_queue_work");
1034     if (work == nullptr) {
1035         HILOG_ERROR("UvWorkNotifyMissionChanged, work is null");
1036         return;
1037     }
1038     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1039     if (registerMissionCB == nullptr) {
1040         HILOG_ERROR("UvWorkNotifyMissionChanged, registerMissionCB is null");
1041         delete work;
1042         return;
1043     }
1044     napi_handle_scope scope = nullptr;
1045     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1046     if (scope == nullptr) {
1047         delete registerMissionCB;
1048         registerMissionCB = nullptr;
1049         delete work;
1050         return;
1051     }
1052 
1053     napi_value result = nullptr;
1054     result =
1055         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1056 
1057     napi_value callback = nullptr;
1058     napi_value undefined = nullptr;
1059     napi_get_undefined(registerMissionCB->cbBase.cbInfo.env, &undefined);
1060     napi_value callResult = nullptr;
1061     napi_get_reference_value(
1062         registerMissionCB->cbBase.cbInfo.env, registerMissionCB->cbBase.cbInfo.callback, &callback);
1063 
1064     napi_call_function(registerMissionCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
1065 
1066     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1067     delete registerMissionCB;
1068     registerMissionCB = nullptr;
1069     delete work;
1070     HILOG_INFO("UvWorkNotifyMissionChanged, uv_queue_work end");
1071 }
1072 
UvWorkOnCallback(uv_work_t * work,int status)1073 void UvWorkOnCallback(uv_work_t *work, int status)
1074 {
1075     HILOG_INFO("UvWorkOnCallback, uv_queue_work");
1076     if (work == nullptr) {
1077         HILOG_ERROR("UvWorkOnCallback, work is null");
1078         return;
1079     }
1080     OnCB *onCB = static_cast<OnCB *>(work->data);
1081     if (onCB == nullptr) {
1082         HILOG_ERROR("UvWorkOnCallback, onCB is null");
1083         delete work;
1084         return;
1085     }
1086 
1087     napi_value result[3] = {nullptr};
1088     napi_create_int32(onCB->cbBase.cbInfo.env, onCB->continueState, &result[0]);
1089     napi_create_object(onCB->cbBase.cbInfo.env, &result[1]);
1090     napi_create_object(onCB->cbBase.cbInfo.env, &result[ARGS_TWO]);
1091     std::string napiValue1 = onCB->srcDeviceId;
1092     std::string napiValue2 = onCB->bundleName;
1093     napi_value jsValue1 = nullptr;
1094     napi_value jsValue2 = nullptr;
1095     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue1.c_str(), NAPI_AUTO_LENGTH, &jsValue1);
1096     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue2.c_str(), NAPI_AUTO_LENGTH, &jsValue2);
1097     std::string napiState = "state";
1098     std::string paramName1 = "srcDeviceId";
1099     std::string paramName2 = "bundleName";
1100     std::string napiInfo = "info";
1101     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName1.c_str(), jsValue1);
1102     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName2.c_str(), jsValue2);
1103     napi_set_named_property(onCB->cbBase.cbInfo.env, result[ARGS_TWO], napiState.c_str(), result[0]);
1104     napi_set_named_property(onCB->cbBase.cbInfo.env, result[ARGS_TWO], napiInfo.c_str(), result[1]);
1105 
1106     napi_value callback = nullptr;
1107     napi_value undefined = nullptr;
1108     napi_get_undefined(onCB->cbBase.cbInfo.env, &undefined);
1109     napi_value callResult = nullptr;
1110     napi_get_reference_value(onCB->cbBase.cbInfo.env, onCB->cbBase.cbInfo.callback, &callback);
1111 
1112     napi_call_function(onCB->cbBase.cbInfo.env, undefined, callback, ARGS_ONE, &result[ARGS_TWO], &callResult);
1113     delete onCB;
1114     onCB = nullptr;
1115     delete work;
1116     HILOG_INFO("UvWorkOnCallback, uv_queue_work end");
1117 }
1118 
NotifyMissionsChanged(const std::string & deviceId)1119 void NAPIRemoteMissionListener::NotifyMissionsChanged(const std::string &deviceId)
1120 {
1121     HILOG_INFO("%{public}s, called.", __func__);
1122     uv_loop_s *loop = nullptr;
1123 
1124     napi_get_uv_event_loop(env_, &loop);
1125     if (loop == nullptr) {
1126         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1127         return;
1128     }
1129 
1130     uv_work_t *work = new uv_work_t;
1131 
1132     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1133     if (registerMissionCB == nullptr) {
1134         HILOG_ERROR("%{public}s, registerMissionCB == nullptr.", __func__);
1135         delete work;
1136         return;
1137     }
1138     registerMissionCB->cbBase.cbInfo.env = env_;
1139     registerMissionCB->cbBase.cbInfo.callback = notifyMissionsChangedRef_;
1140     registerMissionCB->deviceId = deviceId;
1141     work->data = static_cast<void *>(registerMissionCB);
1142 
1143     int rev = uv_queue_work_with_qos(
1144         loop, work, [](uv_work_t *work) {}, UvWorkNotifyMissionChanged, uv_qos_user_initiated);
1145     if (rev != 0) {
1146         delete registerMissionCB;
1147         registerMissionCB = nullptr;
1148         delete work;
1149     }
1150     HILOG_INFO("%{public}s, end.", __func__);
1151 }
1152 
OnCallback(const uint32_t continueState,const std::string & srcDeviceId,const std::string & bundleName)1153 void NAPIRemoteOnListener::OnCallback(const uint32_t continueState, const std::string &srcDeviceId,
1154     const std::string &bundleName)
1155 {
1156     HILOG_INFO("%{public}s, called.", __func__);
1157     uv_loop_s *loop = nullptr;
1158 
1159     napi_get_uv_event_loop(env_, &loop);
1160     if (loop == nullptr) {
1161         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1162         return;
1163     }
1164 
1165     uv_work_t *work = new uv_work_t;
1166 
1167     auto onCB = new (std::nothrow) OnCB;
1168     if (onCB == nullptr) {
1169         HILOG_ERROR("%{public}s, onCB == nullptr.", __func__);
1170         delete work;
1171         return;
1172     }
1173     onCB->cbBase.cbInfo.env = env_;
1174     onCB->cbBase.cbInfo.callback = onCallbackRef_;
1175     onCB->continueState = continueState;
1176     onCB->srcDeviceId = srcDeviceId;
1177     onCB->bundleName = bundleName;
1178     work->data = static_cast<void *>(onCB);
1179 
1180     int rev = uv_queue_work_with_qos(
1181         loop, work, [](uv_work_t *work) {}, UvWorkOnCallback, uv_qos_user_initiated);
1182     if (rev != 0) {
1183         delete onCB;
1184         onCB = nullptr;
1185         delete work;
1186     }
1187     HILOG_INFO("%{public}s, end.", __func__);
1188 }
1189 
UvWorkNotifySnapshot(uv_work_t * work,int status)1190 void UvWorkNotifySnapshot(uv_work_t *work, int status)
1191 {
1192     HILOG_INFO("UvWorkNotifySnapshot, uv_queue_work");
1193     if (work == nullptr) {
1194         HILOG_ERROR("UvWorkNotifySnapshot, work is null");
1195         return;
1196     }
1197     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1198     if (registerMissionCB == nullptr) {
1199         HILOG_ERROR("UvWorkNotifySnapshot, registerMissionCB is null");
1200         delete work;
1201         return;
1202     }
1203     napi_handle_scope scope = nullptr;
1204     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1205     if (scope == nullptr) {
1206         delete registerMissionCB;
1207         registerMissionCB = nullptr;
1208         delete work;
1209         return;
1210     }
1211 
1212     napi_value result[2] = {nullptr};
1213     result[0] =
1214         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1215     result[1] =
1216         WrapInt32(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->missionId, "missionId");
1217     CallbackReturn(&result[0], registerMissionCB);
1218 
1219     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1220     delete registerMissionCB;
1221     registerMissionCB = nullptr;
1222     delete work;
1223     HILOG_INFO("UvWorkNotifySnapshot, uv_queue_work end");
1224 }
1225 
CallbackReturn(napi_value * result,RegisterMissionCB * registerMissionCB)1226 void CallbackReturn(napi_value *result, RegisterMissionCB *registerMissionCB)
1227 {
1228     napi_value callback = nullptr;
1229     napi_value undefined = nullptr;
1230     napi_get_undefined(registerMissionCB->cbBase.cbInfo.env, &undefined);
1231     napi_value callResult = nullptr;
1232     napi_get_reference_value(
1233         registerMissionCB->cbBase.cbInfo.env, registerMissionCB->cbBase.cbInfo.callback, &callback);
1234 
1235     napi_call_function(registerMissionCB->cbBase.cbInfo.env, undefined, callback, ARGS_TWO, &result[0], &callResult);
1236 }
1237 
NotifySnapshot(const std::string & deviceId,int32_t missionId)1238 void NAPIRemoteMissionListener::NotifySnapshot(const std::string &deviceId, int32_t missionId)
1239 {
1240     uv_loop_s *loop = nullptr;
1241 
1242     napi_get_uv_event_loop(env_, &loop);
1243     if (loop == nullptr) {
1244         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1245         return;
1246     }
1247 
1248     uv_work_t *work = new uv_work_t;
1249 
1250     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1251     if (registerMissionCB == nullptr) {
1252         HILOG_ERROR("%{public}s, registerMissionCB == nullptr.", __func__);
1253         delete work;
1254         return;
1255     }
1256     registerMissionCB->cbBase.cbInfo.env = env_;
1257     registerMissionCB->cbBase.cbInfo.callback = notifySnapshotRef_;
1258     registerMissionCB->deviceId = deviceId;
1259     registerMissionCB->missionId = missionId;
1260     work->data = static_cast<void *>(registerMissionCB);
1261 
1262     int rev = uv_queue_work(
1263         loop, work, [](uv_work_t *work) {}, UvWorkNotifySnapshot);
1264     if (rev != 0) {
1265         delete registerMissionCB;
1266         registerMissionCB = nullptr;
1267         delete work;
1268     }
1269     HILOG_INFO("%{public}s, end.", __func__);
1270 }
1271 
UvWorkNotifyNetDisconnect(uv_work_t * work,int status)1272 void UvWorkNotifyNetDisconnect(uv_work_t *work, int status)
1273 {
1274     HILOG_INFO("UvWorkNotifyNetDisconnect, uv_queue_work");
1275     if (work == nullptr) {
1276         HILOG_ERROR("UvWorkNotifyNetDisconnect, work is null");
1277         return;
1278     }
1279     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1280     if (registerMissionCB == nullptr) {
1281         HILOG_ERROR("UvWorkNotifyNetDisconnect, registerMissionCB is null");
1282         delete work;
1283         return;
1284     }
1285     napi_handle_scope scope = nullptr;
1286     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1287     if (scope == nullptr) {
1288         delete registerMissionCB;
1289         registerMissionCB = nullptr;
1290         delete work;
1291         return;
1292     }
1293 
1294     napi_value result[2] = {nullptr};
1295     result[0] =
1296         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1297     HILOG_INFO("UvWorkNotifyNetDisconnect, state = %{public}d", registerMissionCB->state);
1298     result[1] =
1299         WrapInt32(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->state, "state");
1300 
1301     CallbackReturn(&result[0], registerMissionCB);
1302 
1303     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1304     delete registerMissionCB;
1305     registerMissionCB = nullptr;
1306     delete work;
1307     HILOG_INFO("UvWorkNotifyNetDisconnect, uv_queue_work end");
1308 }
1309 
NotifyNetDisconnect(const std::string & deviceId,int32_t state)1310 void NAPIRemoteMissionListener::NotifyNetDisconnect(const std::string &deviceId, int32_t state)
1311 {
1312     HILOG_INFO("%{public}s called. state = %{public}d", __func__, state);
1313     uv_loop_s *loop = nullptr;
1314 
1315     napi_get_uv_event_loop(env_, &loop);
1316     if (loop == nullptr) {
1317         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1318         return;
1319     }
1320 
1321     uv_work_t *work = new uv_work_t;
1322 
1323     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1324     if (registerMissionCB == nullptr) {
1325         HILOG_ERROR("%{public}s, registerMissionCB == nullptr.", __func__);
1326         delete work;
1327         return;
1328     }
1329     registerMissionCB->cbBase.cbInfo.env = env_;
1330     registerMissionCB->cbBase.cbInfo.callback = notifyNetDisconnectRef_;
1331     registerMissionCB->deviceId = deviceId;
1332     registerMissionCB->state = state;
1333     work->data = static_cast<void *>(registerMissionCB);
1334 
1335     int rev = uv_queue_work(
1336         loop, work, [](uv_work_t *work) {}, UvWorkNotifyNetDisconnect);
1337     if (rev != 0) {
1338         delete registerMissionCB;
1339         registerMissionCB = nullptr;
1340         delete work;
1341     }
1342     HILOG_INFO("%{public}s, end.", __func__);
1343 }
1344 
UnRegisterMissionExecuteCB(napi_env env,void * data)1345 void UnRegisterMissionExecuteCB(napi_env env, void *data)
1346 {
1347     HILOG_INFO("%{public}s called.", __func__);
1348     auto registerMissionCB = (RegisterMissionCB*)data;
1349 
1350     std::lock_guard<std::mutex> autoLock(registrationLock_);
1351     sptr<NAPIRemoteMissionListener> registration;
1352     auto item = registration_.find(registerMissionCB->deviceId);
1353     if (item != registration_.end()) {
1354         HILOG_INFO("registration exits.");
1355         registration = registration_[registerMissionCB->deviceId];
1356     } else {
1357         HILOG_INFO("registration not exits.");
1358         registerMissionCB->result = -1;
1359         return;
1360     }
1361     registerMissionCB->missionRegistration = registration;
1362 
1363     registerMissionCB->result =
1364         AbilityManagerClient::GetInstance()->
1365         UnRegisterMissionListener(registerMissionCB->deviceId,
1366         registerMissionCB->missionRegistration);
1367     if (registerMissionCB->result == NO_ERROR) {
1368         HILOG_INFO("remove registration.");
1369         registration_.erase(registerMissionCB->deviceId);
1370     }
1371     HILOG_DEBUG("%{public}s end.deviceId:%{public}d ", __func__, registerMissionCB->result);
1372 }
1373 
UnRegisterMissionPromiseCompletedCB(napi_env env,napi_status status,void * data)1374 void UnRegisterMissionPromiseCompletedCB(napi_env env, napi_status status, void *data)
1375 {
1376     HILOG_INFO("%{public}s called.", __func__);
1377     auto registerMissionCB = (RegisterMissionCB*)data;
1378     // set result
1379     napi_value result[2] = { nullptr };
1380     napi_get_undefined(env, &result[1]);
1381     if (registerMissionCB->result == 0) {
1382         napi_get_undefined(env, &result[0]);
1383     } else {
1384         int32_t errCode = ErrorCodeReturn(registerMissionCB->result);
1385         result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
1386     }
1387 
1388     ReturnValueToApplication(env, &result[0], registerMissionCB);
1389     delete registerMissionCB;
1390     registerMissionCB = nullptr;
1391     HILOG_INFO("%{public}s end.", __func__);
1392 }
1393 
UnRegisterMissionPromise(napi_env env,RegisterMissionCB * registerMissionCB)1394 napi_value UnRegisterMissionPromise(napi_env env, RegisterMissionCB *registerMissionCB)
1395 {
1396     HILOG_INFO("%{public}s asyncCallback.", __func__);
1397     if (registerMissionCB == nullptr) {
1398         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1399         return nullptr;
1400     }
1401     napi_value promise = nullptr;
1402     if (registerMissionCB->callbackRef == nullptr) {
1403         napi_create_promise(env, &registerMissionCB->cbBase.deferred, &promise);
1404     } else {
1405         napi_get_undefined(env, &promise);
1406     }
1407 
1408     napi_value resourceName = nullptr;
1409     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1410 
1411     napi_create_async_work(env,
1412         nullptr,
1413         resourceName,
1414         UnRegisterMissionExecuteCB,
1415         UnRegisterMissionPromiseCompletedCB,
1416         static_cast<void *>(registerMissionCB),
1417         &registerMissionCB->cbBase.asyncWork);
1418     napi_queue_async_work(env, registerMissionCB->cbBase.asyncWork);
1419     HILOG_INFO("%{public}s asyncCallback end.", __func__);
1420     return promise;
1421 }
1422 
GetUnRegisterMissionDeviceId(napi_env & env,const napi_value & value,RegisterMissionCB * registerMissionCB,std::string & errInfo)1423 bool GetUnRegisterMissionDeviceId(napi_env &env, const napi_value &value,
1424     RegisterMissionCB *registerMissionCB, std::string &errInfo)
1425 {
1426     HILOG_INFO("%{public}s called.", __func__);
1427     napi_value napiDeviceId = nullptr;
1428     napi_valuetype valueType = napi_undefined;
1429     bool isDeviceId = false;
1430     napi_has_named_property(env, value, "deviceId", &isDeviceId);
1431     napi_typeof(env, value, &valueType);
1432     if (isDeviceId && valueType == napi_object) {
1433         napi_get_named_property(env, value, "deviceId", &napiDeviceId);
1434     } else {
1435         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
1436         errInfo = "Parameter error. The key of \"MissionDeviceInfo\" must be deviceId";
1437         return false;
1438     }
1439     if (napiDeviceId == nullptr) {
1440         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
1441         errInfo = "Parameter error. The value of \"deviceId\" must not be undefined";
1442         return false;
1443     }
1444 
1445     size_t valueLen = 0;
1446     napi_typeof(env, napiDeviceId, &valueType);
1447     if (valueType != napi_string) {
1448         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1449         errInfo = "Parameter error. The type of \"deviceId\" must be string";
1450         return false;
1451     }
1452     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
1453     napi_get_value_string_utf8(env, napiDeviceId, deviceId, VALUE_BUFFER_SIZE + 1, &valueLen);
1454     if (valueLen > VALUE_BUFFER_SIZE) {
1455         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
1456         errInfo = "Parameter error. The length of \"deviceId\" must be less than " +
1457             std::to_string(VALUE_BUFFER_SIZE);
1458         return false;
1459     }
1460     registerMissionCB->deviceId = std::string(deviceId);
1461     HILOG_INFO("%{public}s called end.", __func__);
1462     return true;
1463 }
1464 
UnRegisterMissionWrap(napi_env & env,napi_callback_info info,RegisterMissionCB * registerMissionCB,std::string & errInfo)1465 napi_value UnRegisterMissionWrap(napi_env &env, napi_callback_info info,
1466     RegisterMissionCB *registerMissionCB, std::string &errInfo)
1467 {
1468     HILOG_INFO("%{public}s called.", __func__);
1469     size_t argc = 2;
1470     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1471     napi_value ret = nullptr;
1472 
1473     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1474     HILOG_INFO("argc is %{public}zu", argc);
1475     if (argc != ARGS_ONE && argc != ARGS_TWO) {
1476         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1477         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2";
1478         return nullptr;
1479     }
1480 
1481     if (!GetUnRegisterMissionDeviceId(env, args[0], registerMissionCB, errInfo)) {
1482         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
1483         return nullptr;
1484     }
1485 
1486     if (argc == ARGS_TWO) {
1487         napi_valuetype valueType = napi_undefined;
1488         napi_typeof(env, args[1], &valueType);
1489         if (valueType != napi_function) {
1490             HILOG_ERROR("%{public}s, callback error type.", __func__);
1491             errInfo = "Parameter error. The type of \"callback\" must be AsynCallback<void>: void";
1492             return nullptr;
1493         }
1494         napi_create_reference(env, args[1], 1, &registerMissionCB->callbackRef);
1495     }
1496     ret = UnRegisterMissionPromise(env, registerMissionCB);
1497     HILOG_INFO("%{public}s called end.", __func__);
1498     return ret;
1499 }
1500 
NAPI_UnRegisterMissionListener(napi_env env,napi_callback_info info)1501 napi_value NAPI_UnRegisterMissionListener(napi_env env, napi_callback_info info)
1502 {
1503     HILOG_INFO("%{public}s called.", __func__);
1504     std::string errInfo = "Parameter error";
1505     RegisterMissionCB *registerMissionCB = CreateRegisterMissionCBCBInfo(env);
1506     if (registerMissionCB == nullptr) {
1507         HILOG_ERROR("%{public}s registerMissionCB == nullptr", __func__);
1508         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
1509         return GetUndefined(env);
1510     }
1511 
1512     napi_value ret = UnRegisterMissionWrap(env, info, registerMissionCB, errInfo);
1513     if (ret == nullptr) {
1514         HILOG_ERROR("%{public}s ret == nullptr", __func__);
1515         delete registerMissionCB;
1516         registerMissionCB = nullptr;
1517         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
1518         return GetUndefined(env);
1519     }
1520     HILOG_INFO("%{public}s end.", __func__);
1521     return ret;
1522 }
1523 
WrapString(napi_env & env,const std::string & param,const std::string & paramName)1524 napi_value WrapString(napi_env &env, const std::string &param, const std::string &paramName)
1525 {
1526     HILOG_INFO("%{public}s called.", __func__);
1527 
1528     napi_value jsObject = nullptr;
1529     napi_create_object(env, &jsObject);
1530 
1531     napi_value jsValue = nullptr;
1532     HILOG_DEBUG("%{public}s called. %{public}s = %{public}s", __func__, paramName.c_str(), param.c_str());
1533     napi_create_string_utf8(env, param.c_str(), NAPI_AUTO_LENGTH, &jsValue);
1534     napi_set_named_property(env, jsObject, paramName.c_str(), jsValue);
1535 
1536     return jsObject;
1537 }
1538 
WrapInt32(napi_env & env,int32_t num,const std::string & paramName)1539 napi_value WrapInt32(napi_env &env, int32_t num, const std::string &paramName)
1540 {
1541     HILOG_INFO("%{public}s called.", __func__);
1542 
1543     napi_value jsObject = nullptr;
1544     napi_create_object(env, &jsObject);
1545 
1546     napi_value jsValue = nullptr;
1547     HILOG_DEBUG("%{public}s called. %{public}s = %{public}d", __func__, paramName.c_str(), num);
1548     napi_create_int32(env, num, &jsValue);
1549     napi_set_named_property(env, jsObject, paramName.c_str(), jsValue);
1550 
1551     return jsObject;
1552 }
1553 
CreateContinueAbilityCBCBInfo(napi_env & env)1554 ContinueAbilityCB *CreateContinueAbilityCBCBInfo(napi_env &env)
1555 {
1556     HILOG_INFO("%{public}s called.", __func__);
1557     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
1558     if (continueAbilityCB == nullptr) {
1559         HILOG_ERROR("%{public}s continueAbilityCB == nullptr", __func__);
1560         return nullptr;
1561     }
1562     continueAbilityCB->cbBase.cbInfo.env = env;
1563     continueAbilityCB->cbBase.asyncWork = nullptr;
1564     continueAbilityCB->cbBase.deferred = nullptr;
1565     continueAbilityCB->callbackRef = nullptr;
1566     HILOG_INFO("%{public}s end.", __func__);
1567     return continueAbilityCB;
1568 }
1569 
ContinueAbilityExecuteCB(napi_env env,void * data)1570 void ContinueAbilityExecuteCB(napi_env env, void *data)
1571 {
1572     HILOG_INFO("%{public}s called.", __func__);
1573     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1574     HILOG_INFO("create continueAbilityCB success.");
1575     sptr<NAPIMissionContinue> continuation(new (std::nothrow) NAPIMissionContinue());
1576     continueAbilityCB->abilityContinuation = continuation;
1577     if (continueAbilityCB->abilityContinuation == nullptr) {
1578         HILOG_ERROR("%{public}s abilityContinuation == nullptr.", __func__);
1579         return;
1580     }
1581     continueAbilityCB->abilityContinuation->SetContinueAbilityEnv(env);
1582     HILOG_INFO("set env success.");
1583     if (continueAbilityCB->abilityContinuationCB.callback[0] != nullptr) {
1584         continueAbilityCB->abilityContinuation->
1585             SetContinueAbilityCBRef(continueAbilityCB->abilityContinuationCB.callback[0]);
1586         HILOG_INFO("set callback success.");
1587     } else {
1588         continueAbilityCB->abilityContinuation->
1589             SetContinueAbilityPromiseRef(continueAbilityCB->cbBase.deferred);
1590         HILOG_INFO("set promise success.");
1591     }
1592 
1593     continueAbilityCB->result = -1;
1594     continueAbilityCB->abilityContinuation->SetContinueAbilityHasBundleName(continueAbilityCB->hasArgsWithBundleName);
1595     if (continueAbilityCB->hasArgsWithBundleName) {
1596         continueAbilityCB->result = AAFwk::AbilityManagerClient::GetInstance()->
1597         ContinueMission(continueAbilityCB->srcDeviceId, continueAbilityCB->dstDeviceId,
1598         continueAbilityCB->bundleName, continueAbilityCB->abilityContinuation,
1599         continueAbilityCB->wantParams);
1600     } else {
1601         continueAbilityCB->result = AAFwk::AbilityManagerClient::GetInstance()->
1602         ContinueMission(continueAbilityCB->srcDeviceId, continueAbilityCB->dstDeviceId,
1603         continueAbilityCB->missionId, continueAbilityCB->abilityContinuation,
1604         continueAbilityCB->wantParams);
1605     }
1606     HILOG_INFO("%{public}s end. error:%{public}d ", __func__, continueAbilityCB->result);
1607 }
1608 
ContinueAbilityCallbackCompletedCB(napi_env env,napi_status status,void * data)1609 void ContinueAbilityCallbackCompletedCB(napi_env env, napi_status status, void *data)
1610 {
1611     HILOG_INFO("%{public}s called.", __func__);
1612     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1613     // set result
1614     napi_value result[2] = { nullptr };
1615     napi_get_undefined(env, &result[1]);
1616     if (continueAbilityCB->result == 0) {
1617         napi_get_undefined(env, &result[0]);
1618     } else {
1619         int32_t errCode = ErrorCodeReturn(continueAbilityCB->result);
1620         result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
1621     }
1622     if (!continueAbilityCB->hasArgsWithBundleName) {
1623         if (continueAbilityCB->callbackRef == nullptr) { // promise
1624             if (continueAbilityCB->result == 0) {
1625                 napi_resolve_deferred(env, continueAbilityCB->cbBase.deferred, result[1]);
1626             } else {
1627                 napi_reject_deferred(env, continueAbilityCB->cbBase.deferred, result[0]);
1628             }
1629         } else { // AsyncCallback
1630             napi_value callback = nullptr;
1631             napi_get_reference_value(env, continueAbilityCB->callbackRef, &callback);
1632             napi_value callResult;
1633             napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
1634             napi_delete_reference(env, continueAbilityCB->callbackRef);
1635         }
1636     } else {
1637         if (continueAbilityCB->callbackRef == nullptr && continueAbilityCB->result != 0) { // promise
1638             napi_reject_deferred(env, continueAbilityCB->cbBase.deferred, result[0]);
1639         } else if (continueAbilityCB->callbackRef != nullptr && continueAbilityCB->result != 0) { // AsyncCallback
1640             napi_value callback = nullptr;
1641             napi_get_reference_value(env, continueAbilityCB->callbackRef, &callback);
1642             napi_value callResult;
1643             napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
1644             napi_delete_reference(env, continueAbilityCB->callbackRef);
1645         }
1646     }
1647     napi_delete_async_work(env, continueAbilityCB->cbBase.asyncWork);
1648     delete continueAbilityCB;
1649     continueAbilityCB = nullptr;
1650     HILOG_INFO("%{public}s end.", __func__);
1651 }
1652 
ContinueAbilityAsync(napi_env env,ContinueAbilityCB * continueAbilityCB)1653 napi_value ContinueAbilityAsync(napi_env env, ContinueAbilityCB *continueAbilityCB)
1654 {
1655     HILOG_INFO("%{public}s asyncCallback.", __func__);
1656     if (continueAbilityCB == nullptr) {
1657         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1658         return nullptr;
1659     }
1660 
1661     napi_value result = nullptr;
1662     if (continueAbilityCB->callbackRef == nullptr) {
1663         napi_create_promise(env, &continueAbilityCB->cbBase.deferred, &result);
1664     } else {
1665         napi_get_undefined(env, &result);
1666     }
1667 
1668     napi_value resourceName = nullptr;
1669     napi_create_string_latin1(env, "ContinueAbilityAsyncForLauncher", NAPI_AUTO_LENGTH, &resourceName);
1670 
1671     napi_create_async_work(env,
1672         nullptr,
1673         resourceName,
1674         ContinueAbilityExecuteCB,
1675         ContinueAbilityCallbackCompletedCB,
1676         static_cast<void *>(continueAbilityCB),
1677         &continueAbilityCB->cbBase.asyncWork);
1678     napi_queue_async_work_with_qos(env, continueAbilityCB->cbBase.asyncWork, napi_qos_user_initiated);
1679     HILOG_INFO("%{public}s asyncCallback end.", __func__);
1680     return result;
1681 }
1682 
CheckContinueKeyExist(napi_env & env,const napi_value & value)1683 bool CheckContinueKeyExist(napi_env &env, const napi_value &value)
1684 {
1685     bool isSrcDeviceId = false;
1686     napi_has_named_property(env, value, "srcDeviceId", &isSrcDeviceId);
1687     bool isDstDeviceId = false;
1688     napi_has_named_property(env, value, "dstDeviceId", &isDstDeviceId);
1689     bool isMissionId = false;
1690     napi_has_named_property(env, value, "missionId", &isMissionId);
1691     bool isWantParam = false;
1692     napi_has_named_property(env, value, "wantParam", &isWantParam);
1693     if (!isSrcDeviceId && !isDstDeviceId && !isMissionId && !isWantParam) {
1694         HILOG_ERROR("%{public}s, Wrong argument key.", __func__);
1695         return false;
1696     }
1697     return true;
1698 }
1699 
CheckBundleNameExist(napi_env & env,const napi_value & value)1700 bool CheckBundleNameExist(napi_env &env, const napi_value &value)
1701 {
1702     bool isSrcDeviceId = false;
1703     napi_has_named_property(env, value, "srcDeviceId", &isSrcDeviceId);
1704     bool isDstDeviceId = false;
1705     napi_has_named_property(env, value, "dstDeviceId", &isDstDeviceId);
1706     bool isBundleName = false;
1707     napi_has_named_property(env, value, "bundleName", &isBundleName);
1708     bool isWantParam = false;
1709     napi_has_named_property(env, value, "wantParam", &isWantParam);
1710     if (!isSrcDeviceId && !isDstDeviceId && !isBundleName && !isWantParam) {
1711         return false;
1712     }
1713     return true;
1714 }
1715 
CheckContinueDeviceInfoSrcDeviceId(napi_env & env,napi_value & napiSrcDeviceId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1716 bool CheckContinueDeviceInfoSrcDeviceId(napi_env &env, napi_value &napiSrcDeviceId,
1717     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1718 {
1719     napi_valuetype valueType = napi_undefined;
1720     napi_typeof(env, napiSrcDeviceId, &valueType);
1721     if (valueType != napi_string) {
1722         HILOG_ERROR("%{public}s, Wrong argument type srcDeviceId.", __func__);
1723         errInfo = "Parameter error. The type of \"srcDeviceId\" must be string";
1724         return false;
1725     }
1726     continueAbilityCB->srcDeviceId = AppExecFwk::UnwrapStringFromJS(env, napiSrcDeviceId, "");
1727     return true;
1728 }
1729 
CheckContinueDeviceInfoDstDeviceId(napi_env & env,napi_value & napiDstDeviceId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1730 bool CheckContinueDeviceInfoDstDeviceId(napi_env &env, napi_value &napiDstDeviceId,
1731     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1732 {
1733     napi_valuetype valueType = napi_undefined;
1734     napi_typeof(env, napiDstDeviceId, &valueType);
1735     if (valueType != napi_string) {
1736         HILOG_ERROR("%{public}s, Wrong argument type dstDeviceId.", __func__);
1737         errInfo = "Parameter error. The type of \"dstDeviceId\" must be string";
1738         return false;
1739     }
1740     continueAbilityCB->dstDeviceId = AppExecFwk::UnwrapStringFromJS(env, napiDstDeviceId, "");
1741     return true;
1742 }
1743 
CheckContinueDeviceInfoMissionId(napi_env & env,napi_value & napiMissionId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1744 bool CheckContinueDeviceInfoMissionId(napi_env &env, napi_value &napiMissionId,
1745     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1746 {
1747     napi_valuetype valueType = napi_undefined;
1748     napi_typeof(env, napiMissionId, &valueType);
1749     if (valueType != napi_number) {
1750         HILOG_ERROR("%{public}s, Wrong argument type missionId.", __func__);
1751         errInfo = "Parameter error. The type of \"missionId\" must be number";
1752         return false;
1753     }
1754     continueAbilityCB->missionId = AppExecFwk::UnwrapInt32FromJS(env, napiMissionId, -1);
1755     return true;
1756 }
1757 
CheckContinueDeviceInfoBundleName(napi_env & env,napi_value & napiBundleName,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1758 bool CheckContinueDeviceInfoBundleName(napi_env &env, napi_value &napiBundleName,
1759     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1760 {
1761     napi_valuetype valueType = napi_undefined;
1762     napi_typeof(env, napiBundleName, &valueType);
1763     if (valueType != napi_string) {
1764         HILOG_ERROR("%{public}s, Wrong argument type missionId.", __func__);
1765         errInfo = "Parameter error. The type of \"bundleName\" must be string";
1766         return false;
1767     }
1768     continueAbilityCB->bundleName = AppExecFwk::UnwrapStringFromJS(env, napiBundleName, "");
1769     return true;
1770 }
1771 
CheckContinueDeviceInfoWantParam(napi_env & env,napi_value & napiWantParam,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1772 bool CheckContinueDeviceInfoWantParam(napi_env &env, napi_value &napiWantParam,
1773     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1774 {
1775     napi_valuetype valueType = napi_undefined;
1776     napi_typeof(env, napiWantParam, &valueType);
1777     if (valueType != napi_object) {
1778         HILOG_ERROR("%{public}s, Wrong argument type wantParam.", __func__);
1779         errInfo = "Parameter error. The type of \"wantParams\" must be object";
1780         return false;
1781     }
1782     if (!AppExecFwk::UnwrapWantParams(env, napiWantParam, continueAbilityCB->wantParams)) {
1783         HILOG_ERROR("%{public}s, Wrong argument type wantParam.", __func__);
1784         errInfo = "Parameter error. The type of \"wantParams\" must be array";
1785         return false;
1786     }
1787     return true;
1788 }
1789 
CheckContinueFirstArgs(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1790 bool CheckContinueFirstArgs(napi_env &env, const napi_value &value,
1791     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1792 {
1793     HILOG_INFO("%{public}s called.", __func__);
1794     if (!CheckContinueKeyExist(env, value)) {
1795         HILOG_ERROR("%{public}s, Wrong argument key.", __func__);
1796         errInfo = "Parameter error. The type of \"parameter\" must be ContinueMission";
1797         return false;
1798     }
1799     napi_value napiSrcDeviceId = nullptr;
1800     napi_value napiDstDeviceId = nullptr;
1801     napi_value napiMissionId = nullptr;
1802     napi_value napiWantParam = nullptr;
1803     napi_valuetype valueType = napi_undefined;
1804     napi_typeof(env, value, &valueType);
1805     if (valueType != napi_object) {
1806         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1807         errInfo = "Parameter error. The type of \"parameter\" must be ContinueMission";
1808         return false;
1809     }
1810     napi_get_named_property(env, value, "srcDeviceId", &napiSrcDeviceId);
1811     napi_get_named_property(env, value, "dstDeviceId", &napiDstDeviceId);
1812     napi_get_named_property(env, value, "missionId", &napiMissionId);
1813     napi_get_named_property(env, value, "wantParam", &napiWantParam);
1814     if (napiSrcDeviceId == nullptr || napiDstDeviceId == nullptr ||
1815         napiMissionId == nullptr || napiWantParam == nullptr) {
1816         HILOG_ERROR("%{public}s, miss required parameters.", __func__);
1817         errInfo = "Parameter error. The number of \"ContinueMission\" must be 4";
1818         return false;
1819     }
1820 
1821     if (!CheckContinueDeviceInfoSrcDeviceId(env, napiSrcDeviceId, continueAbilityCB, errInfo) ||
1822         !CheckContinueDeviceInfoDstDeviceId(env, napiDstDeviceId, continueAbilityCB, errInfo) ||
1823         !CheckContinueDeviceInfoMissionId(env, napiMissionId, continueAbilityCB, errInfo) ||
1824         !CheckContinueDeviceInfoWantParam(env, napiWantParam, continueAbilityCB, errInfo)) {
1825         HILOG_ERROR("%{public}s, continueMission check ContinueDeviceInfo value failed.", __func__);
1826         return false;
1827     }
1828 
1829     HILOG_INFO("%{public}s called end.", __func__);
1830     return true;
1831 }
1832 
CheckArgsWithBundleName(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1833 bool CheckArgsWithBundleName(napi_env &env, const napi_value &value,
1834     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1835 {
1836     HILOG_INFO("%{public}s called.", __func__);
1837     if (!CheckBundleNameExist(env, value)) {
1838         HILOG_ERROR("%{public}s, Args without bundleName.", __func__);
1839         return false;
1840     }
1841     napi_value napiSrcDeviceId = nullptr;
1842     napi_value napiDstDeviceId = nullptr;
1843     napi_value napiBundleName = nullptr;
1844     napi_value napiWantParam = nullptr;
1845     napi_valuetype valueType = napi_undefined;
1846     napi_typeof(env, value, &valueType);
1847     if (valueType != napi_object) {
1848         HILOG_ERROR("%{public}s, Args without bundleName.", __func__);
1849         return false;
1850     }
1851     napi_get_named_property(env, value, "srcDeviceId", &napiSrcDeviceId);
1852     napi_get_named_property(env, value, "dstDeviceId", &napiDstDeviceId);
1853     napi_get_named_property(env, value, "bundleName", &napiBundleName);
1854     napi_get_named_property(env, value, "wantParam", &napiWantParam);
1855     if (napiSrcDeviceId == nullptr || napiDstDeviceId == nullptr ||
1856         napiBundleName == nullptr || napiWantParam == nullptr) {
1857         HILOG_ERROR("%{public}s, miss required parameters.", __func__);
1858         return false;
1859     }
1860 
1861     if (!CheckContinueDeviceInfoSrcDeviceId(env, napiSrcDeviceId, continueAbilityCB, errInfo) ||
1862         !CheckContinueDeviceInfoDstDeviceId(env, napiDstDeviceId, continueAbilityCB, errInfo) ||
1863         !CheckContinueDeviceInfoBundleName(env, napiBundleName, continueAbilityCB, errInfo) ||
1864         !CheckContinueDeviceInfoWantParam(env, napiWantParam, continueAbilityCB, errInfo)) {
1865         HILOG_ERROR("%{public}s, continueMission check ContinueDeviceInfo value failed.", __func__);
1866         return false;
1867     }
1868     HILOG_INFO("%{public}s called end.", __func__);
1869     return true;
1870 }
1871 
CheckContinueCallback(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1872 bool CheckContinueCallback(napi_env &env, const napi_value &value,
1873     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1874 {
1875     HILOG_INFO("%{public}s called.", __func__);
1876     napi_value jsMethod = nullptr;
1877     napi_valuetype valuetype = napi_undefined;
1878     napi_typeof(env, value, &valuetype);
1879     if (valuetype != napi_object) {
1880         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1881         errInfo = "Parameter error. The type of \"options\" must be ContinueCallback";
1882         return false;
1883     }
1884     bool isFirstCallback = false;
1885     napi_has_named_property(env, value, "onContinueDone", &isFirstCallback);
1886     if (!isFirstCallback) {
1887         HILOG_ERROR("%{public}s, Wrong argument name for onContinueDone.", __func__);
1888         errInfo = "Parameter error. The key of \"ContinueCallback\" must be onContinueDone";
1889         return false;
1890     }
1891     napi_get_named_property(env, value, "onContinueDone", &jsMethod);
1892     if (jsMethod == nullptr) {
1893         HILOG_ERROR("%{public}s, not find callback onContinueDone.", __func__);
1894         errInfo = "Parameter error. The value of \"onContinueDone\" must not be undefined";
1895         return false;
1896     }
1897     napi_typeof(env, jsMethod, &valuetype);
1898     if (valuetype != napi_function) {
1899         HILOG_ERROR("%{public}s, onContinueDone callback error type.", __func__);
1900         errInfo = "Parameter error. The type of \"onContinueDone\" must be function";
1901         return false;
1902     }
1903     napi_create_reference(env, jsMethod, 1, &continueAbilityCB->abilityContinuationCB.callback[0]);
1904     HILOG_INFO("%{public}s called end.", __func__);
1905     return true;
1906 }
1907 
CheckContinueCallbackWithBundleName(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1908 bool CheckContinueCallbackWithBundleName(napi_env &env, const napi_value &value,
1909     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1910 {
1911     HILOG_INFO("%{public}s called.", __func__);
1912     napi_valuetype valueType = napi_undefined;
1913     napi_typeof(env, value, &valueType);
1914     if (valueType != napi_function) {
1915         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1916         return false;
1917     }
1918     napi_create_reference(env, value, 1, &continueAbilityCB->abilityContinuationCB.callback[0]);
1919     napi_create_reference(env, value, 1, &continueAbilityCB->callbackRef);
1920     HILOG_INFO("%{public}s called end.", __func__);
1921     return true;
1922 }
1923 
ContinueAbilityWrap(napi_env & env,napi_callback_info info,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1924 napi_value ContinueAbilityWrap(napi_env &env, napi_callback_info info,
1925     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1926 {
1927     HILOG_INFO("%{public}s called.", __func__);
1928     size_t argcAsync = 3;
1929     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1930     napi_value ret = nullptr;
1931 
1932     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
1933     HILOG_INFO("argcAsync is %{public}zu", argcAsync);
1934 
1935     if (argcAsync != ARGS_ONE && argcAsync != ARGS_TWO && argcAsync != ARGS_THREE) {
1936         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1937         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2 or 3";
1938         return nullptr;
1939     }
1940 
1941     if (CheckArgsWithBundleName(env, args[0], continueAbilityCB, errInfo)) {
1942         continueAbilityCB->hasArgsWithBundleName = true;
1943         if (argcAsync == ARGS_TWO && CheckContinueCallbackWithBundleName(env, args[1], continueAbilityCB, errInfo)) {
1944             ret = ContinueAbilityAsync(env, continueAbilityCB);
1945             HILOG_INFO("%{public}s called end.", __func__);
1946             return ret;
1947         }
1948     }
1949 
1950     if (!continueAbilityCB->hasArgsWithBundleName) {
1951         if (!CheckContinueFirstArgs(env, args[0], continueAbilityCB, errInfo)) {
1952             HILOG_ERROR("%{public}s, check the first argument failed.", __func__);
1953             return nullptr;
1954         }
1955 
1956         if (argcAsync > 1) {
1957             if (!CheckContinueCallback(env, args[1], continueAbilityCB, errInfo)) {
1958                 HILOG_ERROR("%{public}s, check callback failed.", __func__);
1959                 return nullptr;
1960             }
1961         }
1962 
1963         if (argcAsync == ARGS_THREE) {
1964             napi_valuetype valueType = napi_undefined;
1965             napi_typeof(env, args[ARGS_TWO], &valueType);
1966             if (valueType != napi_function) {
1967                 HILOG_ERROR("%{public}s, callback error type.", __func__);
1968                 errInfo = "Parameter error. The type of \"callback\" must be AsynCallback<void>: void";
1969                 return nullptr;
1970             }
1971             napi_create_reference(env, args[ARGS_TWO], 1, &continueAbilityCB->callbackRef);
1972         }
1973     }
1974 
1975     ret = ContinueAbilityAsync(env, continueAbilityCB);
1976     HILOG_INFO("%{public}s called end.", __func__);
1977     return ret;
1978 }
1979 
NAPI_ContinueAbility(napi_env env,napi_callback_info info)1980 napi_value NAPI_ContinueAbility(napi_env env, napi_callback_info info)
1981 {
1982     HILOG_INFO("%{public}s called.", __func__);
1983     std::string errInfo = "Parameter error";
1984     ContinueAbilityCB *continueAbilityCB = CreateContinueAbilityCBCBInfo(env);
1985     if (continueAbilityCB == nullptr) {
1986         HILOG_ERROR("%{public}s continueAbilityCB == nullptr", __func__);
1987         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
1988         return GetUndefined(env);
1989     }
1990 
1991     napi_value ret = ContinueAbilityWrap(env, info, continueAbilityCB, errInfo);
1992     if (ret == nullptr) {
1993         HILOG_ERROR("%{public}s ret == nullptr", __func__);
1994         delete continueAbilityCB;
1995         continueAbilityCB = nullptr;
1996         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
1997         return GetUndefined(env);
1998     }
1999     HILOG_INFO("%{public}s end.", __func__);
2000     return ret;
2001 }
2002 
UvWorkOnContinueDone(uv_work_t * work,int status)2003 void UvWorkOnContinueDone(uv_work_t *work, int status)
2004 {
2005     HILOG_INFO("UvWorkOnContinueDone, uv_queue_work");
2006     if (work == nullptr) {
2007         HILOG_ERROR("UvWorkOnContinueDone, work is null");
2008         return;
2009     }
2010     ContinueAbilityCB *continueAbilityCB = static_cast<ContinueAbilityCB *>(work->data);
2011     if (continueAbilityCB == nullptr) {
2012         HILOG_ERROR("UvWorkOnContinueDone, continueAbilityCB is null");
2013         delete work;
2014         return;
2015     }
2016     napi_handle_scope scope = nullptr;
2017     napi_open_handle_scope(continueAbilityCB->cbBase.cbInfo.env, &scope);
2018     if (scope == nullptr) {
2019         delete continueAbilityCB;
2020         continueAbilityCB = nullptr;
2021         delete work;
2022         return;
2023     }
2024     HILOG_INFO("UvWorkOnContinueDone, resultCode = %{public}d", continueAbilityCB->resultCode);
2025     napi_value result = WrapInt32(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->resultCode, "resultCode");
2026     if (continueAbilityCB->hasArgsWithBundleName) {
2027         result = WrapInt32(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->resultCode, "code");
2028     }
2029     if (continueAbilityCB->cbBase.deferred == nullptr) {
2030         napi_value callback = nullptr;
2031         napi_value undefined = nullptr;
2032         napi_get_undefined(continueAbilityCB->cbBase.cbInfo.env, &undefined);
2033         napi_value callResult = nullptr;
2034         napi_get_reference_value(continueAbilityCB->cbBase.cbInfo.env,
2035             continueAbilityCB->cbBase.cbInfo.callback, &callback);
2036         napi_call_function(continueAbilityCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
2037         if (continueAbilityCB->cbBase.cbInfo.callback != nullptr) {
2038             napi_delete_reference(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.cbInfo.callback);
2039         }
2040     } else {
2041         napi_value result[2] = { nullptr };
2042         napi_get_undefined(continueAbilityCB->cbBase.cbInfo.env, &result[1]);
2043         if (continueAbilityCB->resultCode == 0) {
2044             napi_resolve_deferred(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.deferred, result[1]);
2045         } else {
2046             result[0] = GenerateBusinessError(continueAbilityCB->cbBase.cbInfo.env,
2047                 continueAbilityCB->resultCode, ErrorMessageReturn(continueAbilityCB->resultCode));
2048             napi_reject_deferred(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.deferred, result[0]);
2049         }
2050     }
2051     napi_close_handle_scope(continueAbilityCB->cbBase.cbInfo.env, scope);
2052     delete continueAbilityCB;
2053     continueAbilityCB = nullptr;
2054     delete work;
2055     HILOG_INFO("UvWorkOnContinueDone, uv_queue_work end");
2056 }
2057 
OnContinueDone(int32_t result)2058 void NAPIMissionContinue::OnContinueDone(int32_t result)
2059 {
2060     HILOG_INFO("%{public}s, called. result = %{public}d", __func__, result);
2061     uv_loop_s *loop = nullptr;
2062 
2063     napi_get_uv_event_loop(env_, &loop);
2064     if (loop == nullptr) {
2065         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
2066         return;
2067     }
2068 
2069     uv_work_t *work = new uv_work_t;
2070 
2071     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
2072     if (continueAbilityCB == nullptr) {
2073         HILOG_ERROR("%{public}s, continueAbilityCB == nullptr.", __func__);
2074         delete work;
2075         return;
2076     }
2077     continueAbilityCB->cbBase.cbInfo.env = env_;
2078     continueAbilityCB->hasArgsWithBundleName = onContinueDoneHasBundleName_;
2079     if (onContinueDoneRef_ != nullptr) {
2080         continueAbilityCB->cbBase.cbInfo.callback = onContinueDoneRef_;
2081     } else {
2082         continueAbilityCB->cbBase.deferred = promiseDeferred_;
2083     }
2084     continueAbilityCB->resultCode = result;
2085     work->data = static_cast<void *>(continueAbilityCB);
2086 
2087     int rev = uv_queue_work_with_qos(
2088         loop, work, [](uv_work_t *work) {}, UvWorkOnContinueDone, uv_qos_user_initiated);
2089     if (rev != 0) {
2090         delete continueAbilityCB;
2091         continueAbilityCB = nullptr;
2092         delete work;
2093     }
2094     HILOG_INFO("%{public}s, end.", __func__);
2095 }
2096 
SetContinueAbilityEnv(const napi_env & env)2097 void NAPIMissionContinue::SetContinueAbilityEnv(const napi_env &env)
2098 {
2099     env_ = env;
2100 }
2101 
SetContinueAbilityCBRef(const napi_ref & ref)2102 void NAPIMissionContinue::SetContinueAbilityCBRef(const napi_ref &ref)
2103 {
2104     onContinueDoneRef_ = ref;
2105 }
2106 
SetContinueAbilityHasBundleName(bool hasBundleName)2107 void NAPIMissionContinue::SetContinueAbilityHasBundleName(bool hasBundleName)
2108 {
2109     onContinueDoneHasBundleName_ = hasBundleName;
2110 }
2111 
SetContinueAbilityPromiseRef(const napi_deferred & promiseDeferred)2112 void NAPIMissionContinue::SetContinueAbilityPromiseRef(const napi_deferred &promiseDeferred)
2113 {
2114     promiseDeferred_ = promiseDeferred;
2115 }
2116 
DistributedMissionManagerExport(napi_env env,napi_value exports)2117 napi_value DistributedMissionManagerExport(napi_env env, napi_value exports)
2118 {
2119     HILOG_INFO("%{public}s,called", __func__);
2120     napi_value continueState = NAPI_ContinueState(env);
2121     napi_property_descriptor properties[] = {
2122         DECLARE_NAPI_FUNCTION("startSyncRemoteMissions", NAPI_StartSyncRemoteMissions),
2123         DECLARE_NAPI_FUNCTION("stopSyncRemoteMissions", NAPI_StopSyncRemoteMissions),
2124         DECLARE_NAPI_FUNCTION("registerMissionListener", NAPI_RegisterMissionListener),
2125         DECLARE_NAPI_FUNCTION("unRegisterMissionListener", NAPI_UnRegisterMissionListener),
2126         DECLARE_NAPI_FUNCTION("continueMission", NAPI_ContinueAbility),
2127         DECLARE_NAPI_FUNCTION("on", NAPI_On),
2128         DECLARE_NAPI_FUNCTION("off", NAPI_Off),
2129         DECLARE_NAPI_PROPERTY("ContinueState", continueState),
2130     };
2131     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
2132     return exports;
2133 }
2134 
2135 static napi_module missionModule = {
2136     .nm_version = 1,
2137     .nm_flags = 0,
2138     .nm_filename = nullptr,
2139     .nm_register_func = DistributedMissionManagerExport,
2140     .nm_modname = "distributedMissionManager",
2141     .nm_priv = (static_cast<void*>(nullptr)),
2142     .reserved = {nullptr}
2143 };
2144 
AbilityRegister()2145 extern "C" __attribute__((constructor)) void AbilityRegister()
2146 {
2147     napi_module_register(&missionModule);
2148 }
2149 }
2150 }
2151