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