• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~NAPIRemoteMissionListener()966 NAPIRemoteMissionListener::~NAPIRemoteMissionListener()
967 {
968     if (env_ == nullptr) {
969         return;
970     }
971     if (notifyMissionsChangedRef_ != nullptr) {
972         napi_delete_reference(env_, notifyMissionsChangedRef_);
973         notifyMissionsChangedRef_ = nullptr;
974     }
975     if (notifySnapshotRef_ != nullptr) {
976         napi_delete_reference(env_, notifySnapshotRef_);
977         notifySnapshotRef_ = nullptr;
978     }
979     if (notifyNetDisconnectRef_ != nullptr) {
980         napi_delete_reference(env_, notifyNetDisconnectRef_);
981         notifyNetDisconnectRef_ = nullptr;
982     }
983 }
984 
SetEnv(const napi_env & env)985 void NAPIRemoteMissionListener::SetEnv(const napi_env &env)
986 {
987     env_ = env;
988 }
989 
SetEnv(const napi_env & env)990 void NAPIRemoteOnListener::SetEnv(const napi_env &env)
991 {
992     env_ = env;
993 }
994 
SetNotifyMissionsChangedCBRef(const napi_ref & ref)995 void NAPIRemoteMissionListener::SetNotifyMissionsChangedCBRef(const napi_ref &ref)
996 {
997     notifyMissionsChangedRef_ = ref;
998 }
999 
SetOnCallbackCBRef(std::shared_ptr<NativeReference> & ref)1000 void NAPIRemoteOnListener::SetOnCallbackCBRef(std::shared_ptr<NativeReference> &ref)
1001 {
1002     callbacks_.push_back(ref);
1003 }
1004 
GetOnCallbackCBRef()1005 std::vector<std::shared_ptr<NativeReference>> NAPIRemoteOnListener::GetOnCallbackCBRef()
1006 {
1007     return callbacks_;
1008 }
1009 
DelOnCallbackCBRef(napi_env env,std::shared_ptr<NativeReference> & ref)1010 bool NAPIRemoteOnListener::DelOnCallbackCBRef(napi_env env, std::shared_ptr<NativeReference> &ref)
1011 {
1012     bool result = false;
1013     for (auto ele = callbacks_.begin(); ele != callbacks_.end(); ++ele) {
1014         napi_strict_equals(env, (*ele)->GetNapiValue(), ref->GetNapiValue(), &result);
1015         if (result) {
1016             TAG_LOGE(AAFwkTag::MISSION, "Object does match value, del callback");
1017             callbacks_.erase(ele);
1018             return result;
1019         }
1020     }
1021 
1022     return result;
1023 }
1024 
SetNotifySnapshotCBRef(const napi_ref & ref)1025 void NAPIRemoteMissionListener::SetNotifySnapshotCBRef(const napi_ref &ref)
1026 {
1027     notifySnapshotRef_ = ref;
1028 }
1029 
SetNotifyNetDisconnectCBRef(const napi_ref & ref)1030 void NAPIRemoteMissionListener::SetNotifyNetDisconnectCBRef(const napi_ref &ref)
1031 {
1032     notifyNetDisconnectRef_ = ref;
1033 }
1034 
UvWorkNotifyMissionChanged(uv_work_t * work,int status)1035 void UvWorkNotifyMissionChanged(uv_work_t *work, int status)
1036 {
1037     TAG_LOGI(AAFwkTag::MISSION, "start, uv_queue_work");
1038     if (work == nullptr) {
1039         TAG_LOGE(AAFwkTag::MISSION, "null work");
1040         return;
1041     }
1042     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1043     if (registerMissionCB == nullptr) {
1044         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1045         delete work;
1046         return;
1047     }
1048     napi_handle_scope scope = nullptr;
1049     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1050     if (scope == nullptr) {
1051         delete registerMissionCB;
1052         registerMissionCB = nullptr;
1053         delete work;
1054         return;
1055     }
1056 
1057     napi_value result = nullptr;
1058     result =
1059         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1060 
1061     napi_value callback = nullptr;
1062     napi_value undefined = nullptr;
1063     napi_get_undefined(registerMissionCB->cbBase.cbInfo.env, &undefined);
1064     napi_value callResult = nullptr;
1065     napi_get_reference_value(
1066         registerMissionCB->cbBase.cbInfo.env, registerMissionCB->cbBase.cbInfo.callback, &callback);
1067 
1068     napi_call_function(registerMissionCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
1069 
1070     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1071     delete registerMissionCB;
1072     registerMissionCB = nullptr;
1073     delete work;
1074     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work end");
1075 }
1076 
UvWorkOnCallback(uv_work_t * work,int status)1077 void UvWorkOnCallback(uv_work_t *work, int status)
1078 {
1079     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work");
1080     if (work == nullptr) {
1081         TAG_LOGE(AAFwkTag::MISSION, "null work");
1082         return;
1083     }
1084     OnCB *onCB = static_cast<OnCB *>(work->data);
1085     if (onCB == nullptr) {
1086         TAG_LOGE(AAFwkTag::MISSION, "null onCB");
1087         delete work;
1088         return;
1089     }
1090     napi_value result[3] = {nullptr};
1091     napi_create_int32(onCB->cbBase.cbInfo.env, onCB->continueState, &result[0]);
1092     napi_create_object(onCB->cbBase.cbInfo.env, &result[1]);
1093     napi_create_object(onCB->cbBase.cbInfo.env, &result[ARGS_TWO]);
1094     std::string napiValue1 = onCB->srcDeviceId;
1095     std::string napiValue2 = onCB->bundleName;
1096     std::string napiValue3 = onCB->continueType;
1097     std::string napiValue4 = onCB->srcBundleName;
1098     napi_value jsValueArr[PARAM4] = {nullptr};
1099     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue1.c_str(), NAPI_AUTO_LENGTH, &jsValueArr[0]);
1100     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue2.c_str(), NAPI_AUTO_LENGTH, &jsValueArr[1]);
1101     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue3.c_str(), NAPI_AUTO_LENGTH, &jsValueArr[ARGS_TWO]);
1102     napi_create_string_utf8(onCB->cbBase.cbInfo.env, napiValue4.c_str(), NAPI_AUTO_LENGTH, &jsValueArr[ARGS_THREE]);
1103     std::string napiState = "state";
1104     std::string paramName1 = "srcDeviceId";
1105     std::string paramName2 = "bundleName";
1106     std::string paramName3 = "continueType";
1107     std::string paramName4 = "srcBundleName";
1108     std::string napiInfo = "info";
1109     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName1.c_str(), jsValueArr[0]);
1110     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName2.c_str(), jsValueArr[1]);
1111     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName3.c_str(), jsValueArr[ARGS_TWO]);
1112     napi_set_named_property(onCB->cbBase.cbInfo.env, result[1], paramName4.c_str(), jsValueArr[ARGS_THREE]);
1113     napi_set_named_property(onCB->cbBase.cbInfo.env, result[ARGS_TWO], napiState.c_str(), result[0]);
1114     napi_set_named_property(onCB->cbBase.cbInfo.env, result[ARGS_TWO], napiInfo.c_str(), result[1]);
1115     for (auto ele = onCB->cbBase.cbInfo.vecCallbacks.begin(); ele != onCB->cbBase.cbInfo.vecCallbacks.end(); ++ele) {
1116         napi_value undefined = nullptr;
1117         napi_get_undefined(onCB->cbBase.cbInfo.env, &undefined);
1118         napi_value callResult = nullptr;
1119         napi_call_function(onCB->cbBase.cbInfo.env, undefined,
1120             (*ele)->GetNapiValue(), ARGS_ONE, &result[ARGS_TWO], &callResult);
1121     }
1122     delete onCB;
1123     onCB = nullptr;
1124     delete work;
1125     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work end");
1126 }
1127 
NotifyMissionsChanged(const std::string & deviceId)1128 void NAPIRemoteMissionListener::NotifyMissionsChanged(const std::string &deviceId)
1129 {
1130     TAG_LOGI(AAFwkTag::MISSION, "called");
1131     uv_loop_s *loop = nullptr;
1132 
1133     napi_get_uv_event_loop(env_, &loop);
1134     if (loop == nullptr) {
1135         TAG_LOGE(AAFwkTag::MISSION, "null loop");
1136         return;
1137     }
1138 
1139     uv_work_t *work = new uv_work_t;
1140 
1141     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1142     if (registerMissionCB == nullptr) {
1143         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1144         delete work;
1145         return;
1146     }
1147     registerMissionCB->cbBase.cbInfo.env = env_;
1148     registerMissionCB->cbBase.cbInfo.callback = notifyMissionsChangedRef_;
1149     registerMissionCB->deviceId = deviceId;
1150     work->data = static_cast<void *>(registerMissionCB);
1151 
1152     int rev = uv_queue_work_with_qos(
1153         loop, work, [](uv_work_t *work) {}, UvWorkNotifyMissionChanged, uv_qos_user_initiated);
1154     if (rev != 0) {
1155         delete registerMissionCB;
1156         registerMissionCB = nullptr;
1157         delete work;
1158     }
1159     TAG_LOGI(AAFwkTag::MISSION, "end");
1160 }
1161 
OnCallback(const uint32_t continueState,const std::string & srcDeviceId,const std::string & bundleName,const std::string & continueType,const std::string & srcBundleName)1162 void NAPIRemoteOnListener::OnCallback(const uint32_t continueState, const std::string &srcDeviceId,
1163     const std::string &bundleName, const std::string &continueType, const std::string &srcBundleName)
1164 {
1165     TAG_LOGI(AAFwkTag::MISSION, "called");
1166     uv_loop_s *loop = nullptr;
1167 
1168     napi_get_uv_event_loop(env_, &loop);
1169     if (loop == nullptr) {
1170         TAG_LOGE(AAFwkTag::MISSION, "null loop");
1171         return;
1172     }
1173 
1174     uv_work_t *work = new uv_work_t;
1175 
1176     auto onCB = new (std::nothrow) OnCB;
1177     if (onCB == nullptr) {
1178         TAG_LOGE(AAFwkTag::MISSION, "null onCB");
1179         delete work;
1180         return;
1181     }
1182     for (auto ele = callbacks_.begin(); ele != callbacks_.end(); ++ele) {
1183         onCB->cbBase.cbInfo.vecCallbacks.push_back(*ele);
1184     }
1185     onCB->cbBase.cbInfo.env = env_;
1186     onCB->continueState = continueState;
1187     onCB->srcDeviceId = srcDeviceId;
1188     onCB->bundleName = bundleName;
1189     onCB->continueType = continueType;
1190     onCB->srcBundleName = srcBundleName;
1191     work->data = static_cast<void *>(onCB);
1192 
1193     int rev = uv_queue_work_with_qos(
1194         loop, work, [](uv_work_t *work) {}, UvWorkOnCallback, uv_qos_user_initiated);
1195     if (rev != 0) {
1196         delete onCB;
1197         onCB = nullptr;
1198         delete work;
1199     }
1200     TAG_LOGI(AAFwkTag::MISSION, "OnCallback end");
1201 }
1202 
UvWorkNotifySnapshot(uv_work_t * work,int status)1203 void UvWorkNotifySnapshot(uv_work_t *work, int status)
1204 {
1205     TAG_LOGI(AAFwkTag::MISSION, "called");
1206     if (work == nullptr) {
1207         TAG_LOGE(AAFwkTag::MISSION, "null work");
1208         return;
1209     }
1210     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1211     if (registerMissionCB == nullptr) {
1212         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1213         delete work;
1214         return;
1215     }
1216     napi_handle_scope scope = nullptr;
1217     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1218     if (scope == nullptr) {
1219         delete registerMissionCB;
1220         registerMissionCB = nullptr;
1221         delete work;
1222         return;
1223     }
1224 
1225     napi_value result[2] = {nullptr};
1226     result[0] =
1227         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1228     result[1] =
1229         CreateInt32(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->missionId, "missionId");
1230     CallbackReturn(&result[0], registerMissionCB);
1231 
1232     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1233     delete registerMissionCB;
1234     registerMissionCB = nullptr;
1235     delete work;
1236     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work end");
1237 }
1238 
CallbackReturn(napi_value * result,RegisterMissionCB * registerMissionCB)1239 void CallbackReturn(napi_value *result, RegisterMissionCB *registerMissionCB)
1240 {
1241     napi_value callback = nullptr;
1242     napi_value undefined = nullptr;
1243     napi_get_undefined(registerMissionCB->cbBase.cbInfo.env, &undefined);
1244     napi_value callResult = nullptr;
1245     napi_get_reference_value(
1246         registerMissionCB->cbBase.cbInfo.env, registerMissionCB->cbBase.cbInfo.callback, &callback);
1247 
1248     napi_call_function(registerMissionCB->cbBase.cbInfo.env, undefined, callback, ARGS_TWO, &result[0], &callResult);
1249 }
1250 
NotifySnapshot(const std::string & deviceId,int32_t missionId)1251 void NAPIRemoteMissionListener::NotifySnapshot(const std::string &deviceId, int32_t missionId)
1252 {
1253     uv_loop_s *loop = nullptr;
1254 
1255     napi_get_uv_event_loop(env_, &loop);
1256     if (loop == nullptr) {
1257         TAG_LOGE(AAFwkTag::MISSION, "null loop");
1258         return;
1259     }
1260 
1261     uv_work_t *work = new uv_work_t;
1262 
1263     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1264     if (registerMissionCB == nullptr) {
1265         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1266         delete work;
1267         return;
1268     }
1269     registerMissionCB->cbBase.cbInfo.env = env_;
1270     registerMissionCB->cbBase.cbInfo.callback = notifySnapshotRef_;
1271     registerMissionCB->deviceId = deviceId;
1272     registerMissionCB->missionId = missionId;
1273     work->data = static_cast<void *>(registerMissionCB);
1274 
1275     int rev = uv_queue_work(
1276         loop, work, [](uv_work_t *work) {}, UvWorkNotifySnapshot);
1277     if (rev != 0) {
1278         delete registerMissionCB;
1279         registerMissionCB = nullptr;
1280         delete work;
1281     }
1282     TAG_LOGI(AAFwkTag::MISSION, "NotifySnapshot end");
1283 }
1284 
UvWorkNotifyNetDisconnect(uv_work_t * work,int status)1285 void UvWorkNotifyNetDisconnect(uv_work_t *work, int status)
1286 {
1287     TAG_LOGI(AAFwkTag::MISSION, "begin, uv_queue_work");
1288     if (work == nullptr) {
1289         TAG_LOGE(AAFwkTag::MISSION, "null work");
1290         return;
1291     }
1292     RegisterMissionCB *registerMissionCB = static_cast<RegisterMissionCB *>(work->data);
1293     if (registerMissionCB == nullptr) {
1294         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1295         delete work;
1296         return;
1297     }
1298     napi_handle_scope scope = nullptr;
1299     napi_open_handle_scope(registerMissionCB->cbBase.cbInfo.env, &scope);
1300     if (scope == nullptr) {
1301         delete registerMissionCB;
1302         registerMissionCB = nullptr;
1303         delete work;
1304         return;
1305     }
1306 
1307     napi_value result[2] = {nullptr};
1308     result[0] =
1309         WrapString(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->deviceId.c_str(), "deviceId");
1310     TAG_LOGI(AAFwkTag::MISSION, "state: %{public}d", registerMissionCB->state);
1311     result[1] =
1312         CreateInt32(registerMissionCB->cbBase.cbInfo.env, registerMissionCB->state, "state");
1313 
1314     CallbackReturn(&result[0], registerMissionCB);
1315 
1316     napi_close_handle_scope(registerMissionCB->cbBase.cbInfo.env, scope);
1317     delete registerMissionCB;
1318     registerMissionCB = nullptr;
1319     delete work;
1320     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work end");
1321 }
1322 
NotifyNetDisconnect(const std::string & deviceId,int32_t state)1323 void NAPIRemoteMissionListener::NotifyNetDisconnect(const std::string &deviceId, int32_t state)
1324 {
1325     TAG_LOGI(AAFwkTag::MISSION, "called. state: %{public}d", state);
1326     uv_loop_s *loop = nullptr;
1327 
1328     napi_get_uv_event_loop(env_, &loop);
1329     if (loop == nullptr) {
1330         TAG_LOGE(AAFwkTag::MISSION, "null loop");
1331         return;
1332     }
1333 
1334     uv_work_t *work = new uv_work_t;
1335 
1336     auto registerMissionCB = new (std::nothrow) RegisterMissionCB;
1337     if (registerMissionCB == nullptr) {
1338         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1339         delete work;
1340         return;
1341     }
1342     registerMissionCB->cbBase.cbInfo.env = env_;
1343     registerMissionCB->cbBase.cbInfo.callback = notifyNetDisconnectRef_;
1344     registerMissionCB->deviceId = deviceId;
1345     registerMissionCB->state = state;
1346     work->data = static_cast<void *>(registerMissionCB);
1347 
1348     int rev = uv_queue_work(
1349         loop, work, [](uv_work_t *work) {}, UvWorkNotifyNetDisconnect);
1350     if (rev != 0) {
1351         delete registerMissionCB;
1352         registerMissionCB = nullptr;
1353         delete work;
1354     }
1355     TAG_LOGI(AAFwkTag::MISSION, "end");
1356 }
1357 
UnRegisterMissionExecuteCB(napi_env env,void * data)1358 void UnRegisterMissionExecuteCB(napi_env env, void *data)
1359 {
1360     TAG_LOGI(AAFwkTag::MISSION, "called");
1361     auto registerMissionCB = (RegisterMissionCB*)data;
1362 
1363     std::lock_guard<std::mutex> autoLock(registrationLock_);
1364     sptr<NAPIRemoteMissionListener> registration;
1365     auto item = registration_.find(registerMissionCB->deviceId);
1366     if (item != registration_.end()) {
1367         TAG_LOGI(AAFwkTag::MISSION, "registration exits");
1368         registration = registration_[registerMissionCB->deviceId];
1369     } else {
1370         TAG_LOGI(AAFwkTag::MISSION, "registration not exits");
1371         registerMissionCB->result = INVALID_PARAMETERS_ERR;
1372         return;
1373     }
1374     registerMissionCB->missionRegistration = registration;
1375 
1376     registerMissionCB->result =
1377         AbilityManagerClient::GetInstance()->
1378         UnRegisterMissionListener(registerMissionCB->deviceId,
1379         registerMissionCB->missionRegistration);
1380     if (registerMissionCB->result == NO_ERROR) {
1381         TAG_LOGI(AAFwkTag::MISSION, "remove registration");
1382         registration_.erase(registerMissionCB->deviceId);
1383     }
1384     TAG_LOGD(AAFwkTag::MISSION, "end.deviceId:%{public}d", registerMissionCB->result);
1385 }
1386 
UnRegisterMissionPromiseCompletedCB(napi_env env,napi_status status,void * data)1387 void UnRegisterMissionPromiseCompletedCB(napi_env env, napi_status status, void *data)
1388 {
1389     TAG_LOGI(AAFwkTag::MISSION, "called");
1390     auto registerMissionCB = (RegisterMissionCB*)data;
1391     // set result
1392     napi_value result[2] = { nullptr };
1393     napi_get_undefined(env, &result[1]);
1394     if (registerMissionCB->result == 0) {
1395         napi_get_undefined(env, &result[0]);
1396     } else {
1397         int32_t errCode = ErrorCodeReturn(registerMissionCB->result);
1398         result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
1399     }
1400 
1401     ReturnValueToApplication(env, &result[0], registerMissionCB);
1402     delete registerMissionCB;
1403     registerMissionCB = nullptr;
1404     TAG_LOGI(AAFwkTag::MISSION, "end");
1405 }
1406 
UnRegisterMissionPromise(napi_env env,RegisterMissionCB * registerMissionCB)1407 napi_value UnRegisterMissionPromise(napi_env env, RegisterMissionCB *registerMissionCB)
1408 {
1409     TAG_LOGI(AAFwkTag::MISSION, "asyncCallback");
1410     if (registerMissionCB == nullptr) {
1411         TAG_LOGE(AAFwkTag::MISSION, "null param");
1412         return nullptr;
1413     }
1414     napi_value promise = nullptr;
1415     if (registerMissionCB->callbackRef == nullptr) {
1416         napi_create_promise(env, &registerMissionCB->cbBase.deferred, &promise);
1417     } else {
1418         napi_get_undefined(env, &promise);
1419     }
1420 
1421     napi_value resourceName = nullptr;
1422     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1423 
1424     napi_create_async_work(env,
1425         nullptr,
1426         resourceName,
1427         UnRegisterMissionExecuteCB,
1428         UnRegisterMissionPromiseCompletedCB,
1429         static_cast<void *>(registerMissionCB),
1430         &registerMissionCB->cbBase.asyncWork);
1431     napi_queue_async_work(env, registerMissionCB->cbBase.asyncWork);
1432     TAG_LOGI(AAFwkTag::MISSION, "asyncCallback end");
1433     return promise;
1434 }
1435 
GetUnRegisterMissionDeviceId(napi_env & env,const napi_value & value,RegisterMissionCB * registerMissionCB,std::string & errInfo)1436 bool GetUnRegisterMissionDeviceId(napi_env &env, const napi_value &value,
1437     RegisterMissionCB *registerMissionCB, std::string &errInfo)
1438 {
1439     TAG_LOGI(AAFwkTag::MISSION, "called");
1440     napi_value napiDeviceId = nullptr;
1441     napi_valuetype valueType = napi_undefined;
1442     bool isDeviceId = false;
1443     napi_has_named_property(env, value, "deviceId", &isDeviceId);
1444     napi_typeof(env, value, &valueType);
1445     if (isDeviceId && valueType == napi_object) {
1446         napi_get_named_property(env, value, "deviceId", &napiDeviceId);
1447     } else {
1448         TAG_LOGE(AAFwkTag::MISSION, "Wrong deviceId argument name");
1449         errInfo = "Parameter error. The key of \"MissionDeviceInfo\" must be deviceId";
1450         return false;
1451     }
1452     if (napiDeviceId == nullptr) {
1453         TAG_LOGE(AAFwkTag::MISSION, "not find deviceId");
1454         errInfo = "Parameter error. The value of \"deviceId\" must not be undefined";
1455         return false;
1456     }
1457 
1458     size_t valueLen = 0;
1459     napi_typeof(env, napiDeviceId, &valueType);
1460     if (valueType != napi_string) {
1461         TAG_LOGE(AAFwkTag::MISSION, " Wrong argument type");
1462         errInfo = "Parameter error. The type of \"deviceId\" must be string";
1463         return false;
1464     }
1465     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
1466     napi_get_value_string_utf8(env, napiDeviceId, deviceId, VALUE_BUFFER_SIZE + 1, &valueLen);
1467     if (valueLen > VALUE_BUFFER_SIZE) {
1468         TAG_LOGE(AAFwkTag::MISSION, "deviceId length not correct");
1469         errInfo = "Parameter error. The length of \"deviceId\" must be less than " +
1470             std::to_string(VALUE_BUFFER_SIZE);
1471         return false;
1472     }
1473     registerMissionCB->deviceId = std::string(deviceId);
1474     TAG_LOGI(AAFwkTag::MISSION, "called end");
1475     return true;
1476 }
1477 
UnRegisterMissionWrap(napi_env & env,napi_callback_info info,RegisterMissionCB * registerMissionCB,std::string & errInfo)1478 napi_value UnRegisterMissionWrap(napi_env &env, napi_callback_info info,
1479     RegisterMissionCB *registerMissionCB, std::string &errInfo)
1480 {
1481     TAG_LOGI(AAFwkTag::MISSION, "called");
1482     size_t argc = 2;
1483     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1484     napi_value ret = nullptr;
1485 
1486     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1487     TAG_LOGI(AAFwkTag::MISSION, "argc is %{public}zu", argc);
1488     if (argc != ARGS_ONE && argc != ARGS_TWO) {
1489         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument count");
1490         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2";
1491         return nullptr;
1492     }
1493 
1494     if (!GetUnRegisterMissionDeviceId(env, args[0], registerMissionCB, errInfo)) {
1495         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument");
1496         return nullptr;
1497     }
1498 
1499     if (argc == ARGS_TWO) {
1500         napi_valuetype valueType = napi_undefined;
1501         napi_typeof(env, args[1], &valueType);
1502         if (valueType != napi_function) {
1503             TAG_LOGE(AAFwkTag::MISSION, "callback error type");
1504             errInfo = "Parameter error. The type of \"callback\" must be AsynCallback<void>: void";
1505             return nullptr;
1506         }
1507         napi_create_reference(env, args[1], 1, &registerMissionCB->callbackRef);
1508     }
1509     ret = UnRegisterMissionPromise(env, registerMissionCB);
1510     TAG_LOGI(AAFwkTag::MISSION, "called end");
1511     return ret;
1512 }
1513 
NAPI_UnRegisterMissionListener(napi_env env,napi_callback_info info)1514 napi_value NAPI_UnRegisterMissionListener(napi_env env, napi_callback_info info)
1515 {
1516     TAG_LOGI(AAFwkTag::MISSION, "called");
1517     std::string errInfo = "Parameter error";
1518     RegisterMissionCB *registerMissionCB = CreateRegisterMissionCBCBInfo(env);
1519     if (registerMissionCB == nullptr) {
1520         TAG_LOGE(AAFwkTag::MISSION, "null registerMissionCB");
1521         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
1522         return GetUndefined(env);
1523     }
1524 
1525     napi_value ret = UnRegisterMissionWrap(env, info, registerMissionCB, errInfo);
1526     if (ret == nullptr) {
1527         TAG_LOGE(AAFwkTag::MISSION, "null ret");
1528         delete registerMissionCB;
1529         registerMissionCB = nullptr;
1530         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
1531         return GetUndefined(env);
1532     }
1533     TAG_LOGI(AAFwkTag::MISSION, "end");
1534     return ret;
1535 }
1536 
WrapString(napi_env & env,const std::string & param,const std::string & paramName)1537 napi_value WrapString(napi_env &env, const std::string &param, const std::string &paramName)
1538 {
1539     TAG_LOGI(AAFwkTag::MISSION, "called");
1540 
1541     napi_value jsValue = nullptr;
1542     TAG_LOGD(AAFwkTag::MISSION, "called. %{public}s = %{public}s",
1543         paramName.c_str(), param.c_str());
1544     napi_create_string_utf8(env, param.c_str(), NAPI_AUTO_LENGTH, &jsValue);
1545 
1546     return jsValue;
1547 }
1548 
WrapInt32(napi_env & env,int32_t num,const std::string & paramName)1549 napi_value WrapInt32(napi_env &env, int32_t num, const std::string &paramName)
1550 {
1551     TAG_LOGI(AAFwkTag::MISSION, "called");
1552 
1553     napi_value jsObject = nullptr;
1554     napi_create_object(env, &jsObject);
1555 
1556     napi_value jsValue = nullptr;
1557     TAG_LOGD(AAFwkTag::MISSION, "called. %{public}s = %{public}d", paramName.c_str(), num);
1558     napi_create_int32(env, num, &jsValue);
1559     napi_set_named_property(env, jsObject, paramName.c_str(), jsValue);
1560 
1561     return jsObject;
1562 }
1563 
CreateInt32(napi_env & env,int32_t num,const std::string & paramName)1564 napi_value CreateInt32(napi_env &env, int32_t num, const std::string &paramName)
1565 {
1566     TAG_LOGD(AAFwkTag::MISSION, "called. %{public}s = %{public}d", paramName.c_str(), num);
1567 
1568     napi_value jsValue = nullptr;
1569     napi_create_int32(env, num, &jsValue);
1570 
1571     return jsValue;
1572 }
1573 
CreateContinueAbilityCBCBInfo(napi_env & env)1574 ContinueAbilityCB *CreateContinueAbilityCBCBInfo(napi_env &env)
1575 {
1576     TAG_LOGI(AAFwkTag::MISSION, "called");
1577     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
1578     if (continueAbilityCB == nullptr) {
1579         TAG_LOGE(AAFwkTag::MISSION, "null continueAbilityCB");
1580         return nullptr;
1581     }
1582     continueAbilityCB->cbBase.cbInfo.env = env;
1583     continueAbilityCB->cbBase.asyncWork = nullptr;
1584     continueAbilityCB->cbBase.deferred = nullptr;
1585     continueAbilityCB->callbackRef = nullptr;
1586     TAG_LOGI(AAFwkTag::MISSION, "end");
1587     return continueAbilityCB;
1588 }
1589 
ContinueAbilityExecuteCB(napi_env env,void * data)1590 void ContinueAbilityExecuteCB(napi_env env, void *data)
1591 {
1592     TAG_LOGI(AAFwkTag::MISSION, "called");
1593     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1594     TAG_LOGI(AAFwkTag::MISSION, "create continueAbilityCB success.");
1595     sptr<NAPIMissionContinue> continuation(new (std::nothrow) NAPIMissionContinue());
1596     continueAbilityCB->abilityContinuation = continuation;
1597     if (continueAbilityCB->abilityContinuation == nullptr) {
1598         TAG_LOGE(AAFwkTag::MISSION, "null abilityContinuation");
1599         return;
1600     }
1601     continueAbilityCB->abilityContinuation->SetContinueAbilityEnv(env);
1602     TAG_LOGI(AAFwkTag::MISSION, "set env success");
1603     if (continueAbilityCB->abilityContinuationCB.callback[0] != nullptr) {
1604         continueAbilityCB->abilityContinuation->
1605             SetContinueAbilityCBRef(continueAbilityCB->abilityContinuationCB.callback[0]);
1606         TAG_LOGI(AAFwkTag::MISSION, "set callback success");
1607     } else {
1608         continueAbilityCB->abilityContinuation->
1609             SetContinueAbilityPromiseRef(continueAbilityCB->cbBase.deferred);
1610         TAG_LOGI(AAFwkTag::MISSION, "set promise success");
1611     }
1612 
1613     continueAbilityCB->result = -1;
1614     continueAbilityCB->abilityContinuation->SetContinueAbilityHasBundleName(continueAbilityCB->hasArgsWithBundleName);
1615     if (continueAbilityCB->hasArgsWithBundleName) {
1616         ContinueMissionInfo continueMissionInfo;
1617         continueMissionInfo.dstDeviceId = continueAbilityCB->dstDeviceId;
1618         continueMissionInfo.srcDeviceId = continueAbilityCB->srcDeviceId;
1619         continueMissionInfo.bundleName = continueAbilityCB->bundleName;
1620         continueMissionInfo.srcBundleName = continueAbilityCB->srcBundleName;
1621         continueMissionInfo.continueType = continueAbilityCB->continueType;
1622         continueMissionInfo.wantParams = continueAbilityCB->wantParams;
1623         continueAbilityCB->result = AAFwk::AbilityManagerClient::GetInstance()->
1624         ContinueMission(continueMissionInfo, continueAbilityCB->abilityContinuation);
1625     } else {
1626         continueAbilityCB->result = AAFwk::AbilityManagerClient::GetInstance()->
1627         ContinueMission(continueAbilityCB->srcDeviceId, continueAbilityCB->dstDeviceId,
1628         continueAbilityCB->missionId, continueAbilityCB->abilityContinuation,
1629         continueAbilityCB->wantParams);
1630     }
1631     TAG_LOGI(AAFwkTag::MISSION, "end. error:%{public}d ", continueAbilityCB->result);
1632 }
1633 
ContinueAbilityCallbackCompletedCB(napi_env env,napi_status status,void * data)1634 void ContinueAbilityCallbackCompletedCB(napi_env env, napi_status status, void *data)
1635 {
1636     TAG_LOGI(AAFwkTag::MISSION, "called");
1637     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1638     // set result
1639     napi_value result[2] = { nullptr };
1640     napi_get_undefined(env, &result[1]);
1641     if (continueAbilityCB->result == 0) {
1642         napi_get_undefined(env, &result[0]);
1643     } else {
1644         int32_t errCode = ErrorCodeReturn(continueAbilityCB->result);
1645         result[0] = GenerateBusinessError(env, errCode, ErrorMessageReturn(errCode));
1646     }
1647     if (!continueAbilityCB->hasArgsWithBundleName) {
1648         if (continueAbilityCB->callbackRef == nullptr) { // promise
1649             if (continueAbilityCB->result == 0) {
1650                 napi_resolve_deferred(env, continueAbilityCB->cbBase.deferred, result[1]);
1651             } else {
1652                 napi_reject_deferred(env, continueAbilityCB->cbBase.deferred, result[0]);
1653             }
1654         } else { // AsyncCallback
1655             napi_value callback = nullptr;
1656             napi_get_reference_value(env, continueAbilityCB->callbackRef, &callback);
1657             napi_value callResult;
1658             napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
1659             napi_delete_reference(env, continueAbilityCB->callbackRef);
1660         }
1661     } else {
1662         if (continueAbilityCB->callbackRef == nullptr && continueAbilityCB->result != 0) { // promise
1663             napi_reject_deferred(env, continueAbilityCB->cbBase.deferred, result[0]);
1664         } else if (continueAbilityCB->callbackRef != nullptr && continueAbilityCB->result != 0) { // AsyncCallback
1665             napi_value callback = nullptr;
1666             napi_get_reference_value(env, continueAbilityCB->callbackRef, &callback);
1667             napi_value callResult;
1668             napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
1669             napi_delete_reference(env, continueAbilityCB->callbackRef);
1670         }
1671     }
1672     napi_delete_async_work(env, continueAbilityCB->cbBase.asyncWork);
1673     delete continueAbilityCB;
1674     continueAbilityCB = nullptr;
1675     TAG_LOGI(AAFwkTag::MISSION, "end");
1676 }
1677 
ContinueAbilityAsync(napi_env env,ContinueAbilityCB * continueAbilityCB)1678 napi_value ContinueAbilityAsync(napi_env env, ContinueAbilityCB *continueAbilityCB)
1679 {
1680     TAG_LOGI(AAFwkTag::MISSION, "asyncCallback");
1681     if (continueAbilityCB == nullptr) {
1682         TAG_LOGE(AAFwkTag::MISSION, "null param");
1683         return nullptr;
1684     }
1685 
1686     napi_value result = nullptr;
1687     if (continueAbilityCB->callbackRef == nullptr) {
1688         napi_create_promise(env, &continueAbilityCB->cbBase.deferred, &result);
1689     } else {
1690         napi_get_undefined(env, &result);
1691     }
1692 
1693     napi_value resourceName = nullptr;
1694     napi_create_string_latin1(env, "ContinueAbilityAsyncForLauncher", NAPI_AUTO_LENGTH, &resourceName);
1695 
1696     napi_create_async_work(env,
1697         nullptr,
1698         resourceName,
1699         ContinueAbilityExecuteCB,
1700         ContinueAbilityCallbackCompletedCB,
1701         static_cast<void *>(continueAbilityCB),
1702         &continueAbilityCB->cbBase.asyncWork);
1703     napi_queue_async_work_with_qos(env, continueAbilityCB->cbBase.asyncWork, napi_qos_user_initiated);
1704     TAG_LOGI(AAFwkTag::MISSION, "asyncCallback end");
1705     return result;
1706 }
1707 
CheckContinueDeviceInfoSrcDeviceId(napi_env & env,napi_value & napiSrcDeviceId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1708 bool CheckContinueDeviceInfoSrcDeviceId(napi_env &env, napi_value &napiSrcDeviceId,
1709     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1710 {
1711     napi_valuetype valueType = napi_undefined;
1712     napi_typeof(env, napiSrcDeviceId, &valueType);
1713     if (valueType != napi_string) {
1714         TAG_LOGE(AAFwkTag::MISSION, "srcDeviceId invalid type");
1715         errInfo = "Parameter error. The type of \"srcDeviceId\" must be string";
1716         return false;
1717     }
1718     continueAbilityCB->srcDeviceId = AppExecFwk::UnwrapStringFromJS(env, napiSrcDeviceId, "");
1719     return true;
1720 }
1721 
CheckContinueDeviceInfoDstDeviceId(napi_env & env,napi_value & napiDstDeviceId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1722 bool CheckContinueDeviceInfoDstDeviceId(napi_env &env, napi_value &napiDstDeviceId,
1723     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1724 {
1725     napi_valuetype valueType = napi_undefined;
1726     napi_typeof(env, napiDstDeviceId, &valueType);
1727     if (valueType != napi_string) {
1728         TAG_LOGE(AAFwkTag::MISSION, "dstDeviceId invalid type");
1729         errInfo = "Parameter error. The type of \"dstDeviceId\" must be string";
1730         return false;
1731     }
1732     continueAbilityCB->dstDeviceId = AppExecFwk::UnwrapStringFromJS(env, napiDstDeviceId, "");
1733     return true;
1734 }
1735 
CheckContinueDeviceInfoMissionId(napi_env & env,napi_value & napiMissionId,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1736 bool CheckContinueDeviceInfoMissionId(napi_env &env, napi_value &napiMissionId,
1737     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1738 {
1739     napi_valuetype valueType = napi_undefined;
1740     napi_typeof(env, napiMissionId, &valueType);
1741     if (valueType != napi_number) {
1742         TAG_LOGE(AAFwkTag::MISSION, "missionId invalid type");
1743         errInfo = "Parameter error. The type of \"missionId\" must be number";
1744         return false;
1745     }
1746     continueAbilityCB->missionId = AppExecFwk::UnwrapInt32FromJS(env, napiMissionId, -1);
1747     return true;
1748 }
1749 
CheckContinueDeviceInfoBundleName(napi_env & env,napi_value & napiBundleName,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1750 bool CheckContinueDeviceInfoBundleName(napi_env &env, napi_value &napiBundleName,
1751     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1752 {
1753     napi_valuetype valueType = napi_undefined;
1754     napi_typeof(env, napiBundleName, &valueType);
1755     if (valueType != napi_string) {
1756         TAG_LOGE(AAFwkTag::MISSION, "missionId invalid type");
1757         errInfo = "Parameter error. The type of \"bundleName\" must be string";
1758         return false;
1759     }
1760     continueAbilityCB->bundleName = AppExecFwk::UnwrapStringFromJS(env, napiBundleName, "");
1761     return true;
1762 }
1763 
CheckContinueDeviceInfoSrcBundleName(napi_env & env,napi_value & napiSrcBundleName,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1764 bool CheckContinueDeviceInfoSrcBundleName(napi_env &env, napi_value &napiSrcBundleName,
1765     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1766 {
1767     napi_valuetype valueType = napi_undefined;
1768     napi_typeof(env, napiSrcBundleName, &valueType);
1769     if (valueType != napi_string) {
1770         TAG_LOGE(AAFwkTag::MISSION, "missionId invalid type");
1771         errInfo = "Parameter error. The type of \"bundleName\" must be string";
1772         return false;
1773     }
1774     continueAbilityCB->srcBundleName = AppExecFwk::UnwrapStringFromJS(env, napiSrcBundleName, "");
1775     return true;
1776 }
1777 
CheckContinueDeviceInfoContinueType(napi_env & env,napi_value & napiContinueType,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1778 bool CheckContinueDeviceInfoContinueType(napi_env &env, napi_value &napiContinueType,
1779     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1780 {
1781     napi_valuetype valueType = napi_undefined;
1782     napi_typeof(env, napiContinueType, &valueType);
1783     if (valueType != napi_string) {
1784         TAG_LOGE(AAFwkTag::MISSION, "missionId invalid type");
1785         errInfo = "Parameter error. The type of \"bundleName\" must be string";
1786         return false;
1787     }
1788     continueAbilityCB->continueType = AppExecFwk::UnwrapStringFromJS(env, napiContinueType, "");
1789     return true;
1790 }
1791 
CheckContinueDeviceInfoWantParam(napi_env & env,napi_value & napiWantParam,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1792 bool CheckContinueDeviceInfoWantParam(napi_env &env, napi_value &napiWantParam,
1793     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1794 {
1795     napi_valuetype valueType = napi_undefined;
1796     napi_typeof(env, napiWantParam, &valueType);
1797     if (valueType != napi_object) {
1798         TAG_LOGE(AAFwkTag::MISSION, "wantParam invalid type");
1799         errInfo = "Parameter error. The type of \"wantParams\" must be object";
1800         return false;
1801     }
1802     if (!AppExecFwk::UnwrapWantParams(env, napiWantParam, continueAbilityCB->wantParams)) {
1803         TAG_LOGE(AAFwkTag::MISSION, "wantParam invalid type");
1804         errInfo = "Parameter error. The type of \"wantParams\" must be array";
1805         return false;
1806     }
1807     return true;
1808 }
1809 
CheckContinueFirstArgs(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1810 bool CheckContinueFirstArgs(napi_env &env, const napi_value &value,
1811     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1812 {
1813     TAG_LOGI(AAFwkTag::MISSION, "called");
1814     if (!CheckContinueKeyExist(env, value)) {
1815         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument key");
1816         errInfo = "Parameter error. The type of \"parameter\" must be ContinueMission";
1817         return false;
1818     }
1819     napi_value napiSrcDeviceId = nullptr;
1820     napi_value napiDstDeviceId = nullptr;
1821     napi_value napiMissionId = nullptr;
1822     napi_value napiWantParam = nullptr;
1823     napi_valuetype valueType = napi_undefined;
1824     napi_typeof(env, value, &valueType);
1825     if (valueType != napi_object) {
1826         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument type");
1827         errInfo = "Parameter error. The type of \"parameter\" must be ContinueMission";
1828         return false;
1829     }
1830     napi_get_named_property(env, value, "srcDeviceId", &napiSrcDeviceId);
1831     napi_get_named_property(env, value, "dstDeviceId", &napiDstDeviceId);
1832     napi_get_named_property(env, value, "missionId", &napiMissionId);
1833     napi_get_named_property(env, value, "wantParam", &napiWantParam);
1834     if (napiSrcDeviceId == nullptr || napiDstDeviceId == nullptr ||
1835         napiMissionId == nullptr || napiWantParam == nullptr) {
1836         TAG_LOGE(AAFwkTag::MISSION, "miss required parameters");
1837         errInfo = "Parameter error. The number of \"ContinueMission\" must be 4";
1838         return false;
1839     }
1840     if (!CheckContinueDeviceInfoSrcDeviceId(env, napiSrcDeviceId, continueAbilityCB, errInfo) ||
1841         !CheckContinueDeviceInfoDstDeviceId(env, napiDstDeviceId, continueAbilityCB, errInfo) ||
1842         !CheckContinueDeviceInfoMissionId(env, napiMissionId, continueAbilityCB, errInfo) ||
1843         !CheckContinueDeviceInfoWantParam(env, napiWantParam, continueAbilityCB, errInfo)) {
1844         TAG_LOGE(AAFwkTag::MISSION, "continueMission check ContinueDeviceInfo failed");
1845         return false;
1846     }
1847     TAG_LOGI(AAFwkTag::MISSION, "called end");
1848     return true;
1849 }
1850 
CheckArgsWithBundleName(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1851 bool CheckArgsWithBundleName(napi_env &env, const napi_value &value,
1852     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1853 {
1854     TAG_LOGI(AAFwkTag::MISSION, "called");
1855     if (!CheckBundleNameExist(env, value)) {
1856         TAG_LOGE(AAFwkTag::MISSION, "Args without bundleName");
1857         return false;
1858     }
1859     napi_value napiValue[ARGS_SIX] = {nullptr};
1860     napi_valuetype valueType = napi_undefined;
1861     napi_typeof(env, value, &valueType);
1862     if (valueType != napi_object) {
1863         TAG_LOGE(AAFwkTag::MISSION, "Args without bundleName");
1864         return false;
1865     }
1866     napi_get_named_property(env, value, "srcDeviceId", &napiValue[ARGS_ZERO]);
1867     napi_get_named_property(env, value, "dstDeviceId", &napiValue[ARGS_ONE]);
1868     napi_get_named_property(env, value, "bundleName", &napiValue[ARGS_TWO]);
1869     napi_get_named_property(env, value, "wantParam", &napiValue[ARGS_THREE]);
1870     napi_get_named_property(env, value, "srcBundleName", &napiValue[ARGS_FOUR]);
1871     napi_get_named_property(env, value, "continueType", &napiValue[ARGS_FIVE]);
1872     if (napiValue[ARGS_ZERO] == nullptr || napiValue[ARGS_ONE] == nullptr ||
1873         napiValue[ARGS_TWO] == nullptr || napiValue[ARGS_THREE] == nullptr) {
1874         TAG_LOGE(AAFwkTag::MISSION, "miss required parameters");
1875         return false;
1876     }
1877     CheckContinueDeviceInfoContinueType(env, napiValue[ARGS_FIVE], continueAbilityCB, errInfo);
1878     CheckContinueDeviceInfoSrcBundleName(env, napiValue[ARGS_FOUR], continueAbilityCB, errInfo);
1879     if (!CheckContinueDeviceInfoSrcDeviceId(env, napiValue[ARGS_ZERO], continueAbilityCB, errInfo) ||
1880         !CheckContinueDeviceInfoDstDeviceId(env, napiValue[ARGS_ONE], continueAbilityCB, errInfo) ||
1881         !CheckContinueDeviceInfoBundleName(env, napiValue[ARGS_TWO], continueAbilityCB, errInfo) ||
1882         !CheckContinueDeviceInfoWantParam(env, napiValue[ARGS_THREE], continueAbilityCB, errInfo)) {
1883         TAG_LOGE(AAFwkTag::MISSION, "continueMission check ContinueDeviceInfo failed");
1884         return false;
1885     }
1886     TAG_LOGI(AAFwkTag::MISSION, "called end");
1887     return true;
1888 }
1889 
CheckContinueCallback(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1890 bool CheckContinueCallback(napi_env &env, const napi_value &value,
1891     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1892 {
1893     TAG_LOGI(AAFwkTag::MISSION, "called");
1894     napi_value jsMethod = nullptr;
1895     napi_valuetype valuetype = napi_undefined;
1896     napi_typeof(env, value, &valuetype);
1897     if (valuetype != napi_object) {
1898         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument type");
1899         errInfo = "Parameter error. The type of \"options\" must be ContinueCallback";
1900         return false;
1901     }
1902     bool isFirstCallback = false;
1903     napi_has_named_property(env, value, "onContinueDone", &isFirstCallback);
1904     if (!isFirstCallback) {
1905         TAG_LOGE(AAFwkTag::MISSION, "invalid onContinueDone name");
1906         errInfo = "Parameter error. The key of \"ContinueCallback\" must be onContinueDone";
1907         return false;
1908     }
1909     napi_get_named_property(env, value, "onContinueDone", &jsMethod);
1910     if (jsMethod == nullptr) {
1911         TAG_LOGE(AAFwkTag::MISSION, "not find onContinueDone");
1912         errInfo = "Parameter error. The value of \"onContinueDone\" must not be undefined";
1913         return false;
1914     }
1915     napi_typeof(env, jsMethod, &valuetype);
1916     if (valuetype != napi_function) {
1917         TAG_LOGE(AAFwkTag::MISSION, "onContinueDone error type");
1918         errInfo = "Parameter error. The type of \"onContinueDone\" must be function";
1919         return false;
1920     }
1921     napi_create_reference(env, jsMethod, 1, &continueAbilityCB->abilityContinuationCB.callback[0]);
1922     TAG_LOGI(AAFwkTag::MISSION, "called end");
1923     return true;
1924 }
1925 
CheckContinueCallbackWithBundleName(napi_env & env,const napi_value & value,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1926 bool CheckContinueCallbackWithBundleName(napi_env &env, const napi_value &value,
1927     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1928 {
1929     TAG_LOGI(AAFwkTag::MISSION, "called");
1930     napi_valuetype valueType = napi_undefined;
1931     napi_typeof(env, value, &valueType);
1932     if (valueType != napi_function) {
1933         TAG_LOGE(AAFwkTag::MISSION, "Wrong argument type");
1934         return false;
1935     }
1936     napi_create_reference(env, value, 1, &continueAbilityCB->abilityContinuationCB.callback[0]);
1937     napi_create_reference(env, value, 1, &continueAbilityCB->callbackRef);
1938     TAG_LOGI(AAFwkTag::MISSION, "called end");
1939     return true;
1940 }
1941 
ContinueAbilityWrap(napi_env & env,napi_callback_info info,ContinueAbilityCB * continueAbilityCB,std::string & errInfo)1942 napi_value ContinueAbilityWrap(napi_env &env, napi_callback_info info,
1943     ContinueAbilityCB *continueAbilityCB, std::string &errInfo)
1944 {
1945     TAG_LOGI(AAFwkTag::MISSION, "called");
1946     size_t argcAsync = 3;
1947     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1948     napi_value ret = nullptr;
1949 
1950     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
1951     TAG_LOGI(AAFwkTag::MISSION, "argcAsync is %{public}zu", argcAsync);
1952 
1953     if (argcAsync != ARGS_ONE && argcAsync != ARGS_TWO && argcAsync != ARGS_THREE) {
1954         TAG_LOGE(AAFwkTag::MISSION, "invalid argc");
1955         errInfo = "Parameter error. The type of \"number of parameters\" must be 1 or 2 or 3";
1956         return nullptr;
1957     }
1958 
1959     if (CheckArgsWithBundleName(env, args[0], continueAbilityCB, errInfo)) {
1960         continueAbilityCB->hasArgsWithBundleName = true;
1961         if (argcAsync == ARGS_TWO && CheckContinueCallbackWithBundleName(env, args[1], continueAbilityCB, errInfo)) {
1962             ret = ContinueAbilityAsync(env, continueAbilityCB);
1963             TAG_LOGI(AAFwkTag::MISSION, "called end");
1964             return ret;
1965         }
1966     }
1967 
1968     if (!continueAbilityCB->hasArgsWithBundleName) {
1969         if (!CheckContinueFirstArgs(env, args[0], continueAbilityCB, errInfo)) {
1970             TAG_LOGE(AAFwkTag::MISSION, "check the first argument failed");
1971             return nullptr;
1972         }
1973 
1974         if (argcAsync > 1) {
1975             if (!CheckContinueCallback(env, args[1], continueAbilityCB, errInfo)) {
1976                 TAG_LOGE(AAFwkTag::MISSION, "check callback failed");
1977                 return nullptr;
1978             }
1979         }
1980 
1981         if (argcAsync == ARGS_THREE) {
1982             napi_valuetype valueType = napi_undefined;
1983             napi_typeof(env, args[ARGS_TWO], &valueType);
1984             if (valueType != napi_function) {
1985                 TAG_LOGE(AAFwkTag::MISSION, "callback error type");
1986                 errInfo = "Parameter error. The type of \"callback\" must be AsynCallback<void>: void";
1987                 return nullptr;
1988             }
1989             napi_create_reference(env, args[ARGS_TWO], 1, &continueAbilityCB->callbackRef);
1990         }
1991     }
1992 
1993     ret = ContinueAbilityAsync(env, continueAbilityCB);
1994     TAG_LOGI(AAFwkTag::MISSION, "called end");
1995     return ret;
1996 }
1997 
NAPI_ContinueAbility(napi_env env,napi_callback_info info)1998 napi_value NAPI_ContinueAbility(napi_env env, napi_callback_info info)
1999 {
2000     TAG_LOGI(AAFwkTag::MISSION, "called");
2001     std::string errInfo = "Parameter error";
2002     ContinueAbilityCB *continueAbilityCB = CreateContinueAbilityCBCBInfo(env);
2003     if (continueAbilityCB == nullptr) {
2004         TAG_LOGE(AAFwkTag::MISSION, "null continueAbilityCB");
2005         napi_throw(env, GenerateBusinessError(env, SYSTEM_WORK_ABNORMALLY, ErrorMessageReturn(SYSTEM_WORK_ABNORMALLY)));
2006         return GetUndefined(env);
2007     }
2008 
2009     napi_value ret = ContinueAbilityWrap(env, info, continueAbilityCB, errInfo);
2010     if (ret == nullptr) {
2011         TAG_LOGE(AAFwkTag::MISSION, "null ret");
2012         delete continueAbilityCB;
2013         continueAbilityCB = nullptr;
2014         napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
2015         return GetUndefined(env);
2016     }
2017     TAG_LOGI(AAFwkTag::MISSION, "end");
2018     return ret;
2019 }
2020 
CheckAndGetParameters(uv_work_t * work,napi_handle_scope * scope)2021 ContinueAbilityCB *CheckAndGetParameters(uv_work_t *work, napi_handle_scope *scope)
2022 {
2023     TAG_LOGI(AAFwkTag::MISSION, "start");
2024     if (work == nullptr) {
2025         TAG_LOGE(AAFwkTag::MISSION, "null work");
2026         return nullptr;
2027     }
2028     ContinueAbilityCB *continueAbilityCB = static_cast<ContinueAbilityCB *>(work->data);
2029     if (continueAbilityCB == nullptr) {
2030         TAG_LOGE(AAFwkTag::MISSION, "null continueAbilityCB");
2031         delete work;
2032         return nullptr;
2033     }
2034     napi_open_handle_scope(continueAbilityCB->cbBase.cbInfo.env, scope);
2035     if (scope == nullptr) {
2036         delete continueAbilityCB;
2037         continueAbilityCB = nullptr;
2038         delete work;
2039         return nullptr;
2040     }
2041     return continueAbilityCB;
2042 }
2043 
UvWorkOnContinueDone(uv_work_t * work,int status)2044 void UvWorkOnContinueDone(uv_work_t *work, int status)
2045 {
2046     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work");
2047     napi_handle_scope scope = nullptr;
2048     ContinueAbilityCB *continueAbilityCB = CheckAndGetParameters(work, &scope);
2049     if (continueAbilityCB == nullptr) {
2050         return;
2051     }
2052     TAG_LOGI(AAFwkTag::MISSION, "resultCode: %{public}d", continueAbilityCB->resultCode);
2053     napi_value result = WrapInt32(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->resultCode, "resultCode");
2054     if (continueAbilityCB->hasArgsWithBundleName) {
2055         result = WrapInt32(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->resultCode, "code");
2056     }
2057     if (continueAbilityCB->cbBase.deferred == nullptr) {
2058         std::lock_guard<std::mutex> autoLock(registrationLock_);
2059         napi_value callback = nullptr;
2060         napi_value undefined = nullptr;
2061         napi_get_undefined(continueAbilityCB->cbBase.cbInfo.env, &undefined);
2062         napi_value callResult = nullptr;
2063         napi_get_reference_value(continueAbilityCB->cbBase.cbInfo.env,
2064             continueAbilityCB->cbBase.cbInfo.callback, &callback);
2065         napi_call_function(continueAbilityCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
2066         if (continueAbilityCB->cbBase.cbInfo.callback != nullptr) {
2067             napi_delete_reference(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.cbInfo.callback);
2068             continueAbilityCB->cbBase.cbInfo.callback = nullptr;
2069         }
2070     } else {
2071         napi_value result[2] = { nullptr };
2072         napi_get_undefined(continueAbilityCB->cbBase.cbInfo.env, &result[1]);
2073         if (continueAbilityCB->resultCode == 0) {
2074             napi_resolve_deferred(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.deferred, result[1]);
2075         } else {
2076             result[0] = GenerateBusinessError(continueAbilityCB->cbBase.cbInfo.env,
2077                 continueAbilityCB->resultCode, ErrorMessageReturn(continueAbilityCB->resultCode));
2078             napi_reject_deferred(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.deferred, result[0]);
2079         }
2080     }
2081     napi_close_handle_scope(continueAbilityCB->cbBase.cbInfo.env, scope);
2082     delete continueAbilityCB;
2083     continueAbilityCB = nullptr;
2084     delete work;
2085     TAG_LOGI(AAFwkTag::MISSION, "uv_queue_work end");
2086 }
2087 
OnContinueDone(int32_t result)2088 void NAPIMissionContinue::OnContinueDone(int32_t result)
2089 {
2090     TAG_LOGI(AAFwkTag::MISSION, "called. result = %{public}d", result);
2091     uv_loop_s *loop = nullptr;
2092 
2093     napi_get_uv_event_loop(env_, &loop);
2094     if (loop == nullptr) {
2095         TAG_LOGE(AAFwkTag::MISSION, "null loop");
2096         return;
2097     }
2098 
2099     uv_work_t *work = new uv_work_t;
2100 
2101     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
2102     if (continueAbilityCB == nullptr) {
2103         TAG_LOGE(AAFwkTag::MISSION, "null continueAbilityCB");
2104         delete work;
2105         return;
2106     }
2107     continueAbilityCB->cbBase.cbInfo.env = env_;
2108     continueAbilityCB->hasArgsWithBundleName = onContinueDoneHasBundleName_;
2109     if (onContinueDoneRef_ != nullptr) {
2110         continueAbilityCB->cbBase.cbInfo.callback = onContinueDoneRef_;
2111     } else {
2112         continueAbilityCB->cbBase.deferred = promiseDeferred_;
2113     }
2114     continueAbilityCB->resultCode = result;
2115     work->data = static_cast<void *>(continueAbilityCB);
2116 
2117     int rev = uv_queue_work_with_qos(
2118         loop, work, [](uv_work_t *work) {}, UvWorkOnContinueDone, uv_qos_user_initiated);
2119     if (rev != 0) {
2120         delete continueAbilityCB;
2121         continueAbilityCB = nullptr;
2122         delete work;
2123     }
2124     TAG_LOGI(AAFwkTag::MISSION, "end");
2125 }
2126 
DistributedMissionManagerExport(napi_env env,napi_value exports)2127 napi_value DistributedMissionManagerExport(napi_env env, napi_value exports)
2128 {
2129     TAG_LOGI(AAFwkTag::MISSION, "called");
2130     napi_property_descriptor properties[] = {
2131         DECLARE_NAPI_FUNCTION("startSyncRemoteMissions", NAPI_StartSyncRemoteMissions),
2132         DECLARE_NAPI_FUNCTION("stopSyncRemoteMissions", NAPI_StopSyncRemoteMissions),
2133         DECLARE_NAPI_FUNCTION("registerMissionListener", NAPI_RegisterMissionListener),
2134         DECLARE_NAPI_FUNCTION("unRegisterMissionListener", NAPI_UnRegisterMissionListener),
2135         DECLARE_NAPI_FUNCTION("continueMission", NAPI_ContinueAbility),
2136         DECLARE_NAPI_FUNCTION("on", NAPI_NotifyToOn),
2137         DECLARE_NAPI_FUNCTION("off", NAPI_NotifyToOff),
2138     };
2139     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
2140     return exports;
2141 }
2142 
2143 static napi_module missionModule = {
2144     .nm_version = 1,
2145     .nm_flags = 0,
2146     .nm_filename = nullptr,
2147     .nm_register_func = DistributedMissionManagerExport,
2148     .nm_modname = "distributedMissionManager",
2149     .nm_priv = (static_cast<void*>(nullptr)),
2150     .reserved = {nullptr}
2151 };
2152 
AbilityRegister()2153 extern "C" __attribute__((constructor)) void AbilityRegister()
2154 {
2155     napi_module_register(&missionModule);
2156 }
2157 }
2158 }
2159