• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "hilog_wrapper.h"
22 #include "ipc_skeleton.h"
23 #include "napi_common_data.h"
24 #include "napi_common_util.h"
25 #include "napi_common_want.h"
26 #include "napi_remote_object.h"
27 
28 using namespace OHOS::AppExecFwk;
29 
30 namespace OHOS {
31 namespace AAFwk {
32 using AbilityManagerClient = AAFwk::AbilityManagerClient;
33 const std::string TAG = "NAPIMissionRegistration";
34 constexpr size_t VALUE_BUFFER_SIZE = 128;
35 
SetStartSyncMissionsContext(const napi_env & env,const napi_value & value,SyncRemoteMissionsContext * context)36 bool SetStartSyncMissionsContext(const napi_env &env, const napi_value &value,
37     SyncRemoteMissionsContext* context)
38 {
39     HILOG_INFO("%{public}s call.", __func__);
40     bool isFixConflict = false;
41     napi_has_named_property(env, value, "fixConflict", &isFixConflict);
42     if (!isFixConflict) {
43         HILOG_ERROR("%{public}s, Wrong argument name for fixConflict.", __func__);
44         return false;
45     }
46     napi_value fixConflictValue = nullptr;
47     napi_get_named_property(env, value, "fixConflict", &fixConflictValue);
48     if (fixConflictValue == nullptr) {
49         HILOG_ERROR("%{public}s, not find fixConflict.", __func__);
50         return false;
51     }
52     napi_valuetype valueType = napi_undefined;
53     napi_typeof(env, fixConflictValue, &valueType);
54     if (valueType != napi_boolean) {
55         HILOG_ERROR("%{public}s, fixConflict error type.", __func__);
56         return false;
57     }
58     napi_get_value_bool(env, fixConflictValue, &context->fixConflict);
59     bool isTag = false;
60     napi_has_named_property(env, value, "tag", &isTag);
61     if (!isTag) {
62         HILOG_ERROR("%{public}s, Wrong argument name for tag.", __func__);
63         return false;
64     }
65     napi_value tagValue = nullptr;
66     napi_get_named_property(env, value, "tag", &tagValue);
67     if (tagValue == nullptr) {
68         HILOG_ERROR("%{public}s, not find tag.", __func__);
69         return false;
70     }
71     napi_typeof(env, tagValue, &valueType);
72     if (valueType != napi_number) {
73         HILOG_ERROR("%{public}s, tag error type.", __func__);
74         return false;
75     }
76     napi_get_value_int64(env, tagValue, &context->tag);
77     HILOG_INFO("%{public}s end.", __func__);
78     return true;
79 }
80 
SetSyncRemoteMissionsContext(const napi_env & env,const napi_value & value,bool isStart,SyncRemoteMissionsContext * context)81 bool SetSyncRemoteMissionsContext(const napi_env &env, const napi_value &value,
82     bool isStart, SyncRemoteMissionsContext* context)
83 {
84     HILOG_INFO("%{public}s call.", __func__);
85     napi_valuetype valueType = napi_undefined;
86     napi_typeof(env, value, &valueType);
87     if (valueType != napi_object) {
88         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
89         return false;
90     }
91     napi_value deviceIdValue = nullptr;
92     bool isDeviceId = false;
93     napi_has_named_property(env, value, "deviceId", &isDeviceId);
94     if (!isDeviceId) {
95         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
96         return false;
97     }
98     napi_get_named_property(env, value, "deviceId", &deviceIdValue);
99     if (deviceIdValue == nullptr) {
100         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
101         return false;
102     }
103     napi_typeof(env, deviceIdValue, &valueType);
104     if (valueType != napi_string) {
105         HILOG_ERROR("%{public}s, deviceId error type.", __func__);
106         return false;
107     }
108 
109     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
110     napi_get_value_string_utf8(env, deviceIdValue, deviceId, VALUE_BUFFER_SIZE + 1, &context->valueLen);
111     if (context->valueLen > VALUE_BUFFER_SIZE) {
112         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
113         return false;
114     }
115     context->deviceId = deviceId;
116     HILOG_INFO("%{public}s deviceId:%{public}s", __func__, context->deviceId.c_str());
117 
118     if (isStart) {
119         if (!SetStartSyncMissionsContext (env, value, context)) {
120             HILOG_ERROR("%{public}s, Wrong argument for start sync.", __func__);
121             return false;
122         }
123     }
124     HILOG_INFO("%{public}s end.", __func__);
125     return true;
126 }
127 
ProcessSyncInput(napi_env env,napi_callback_info info,bool isStart,SyncRemoteMissionsContext * syncContext)128 bool ProcessSyncInput(napi_env env, napi_callback_info info, bool isStart,
129     SyncRemoteMissionsContext* syncContext)
130 {
131     HILOG_INFO("%{public}s,called.", __func__);
132     size_t argc = 2;
133     napi_value argv[2] = { 0 };
134     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
135     if (argc != ARGS_ONE && argc != ARGS_TWO) {
136         HILOG_ERROR("%{public}s, argument size error.", __func__);
137         return false;
138     }
139     syncContext->env = env;
140     if (!SetSyncRemoteMissionsContext(env, argv[0], isStart, syncContext)) {
141         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
142         return false;
143     }
144     if (argc == ARGS_TWO) {
145         napi_valuetype valueType = napi_undefined;
146         napi_typeof(env, argv[1], &valueType);
147         if (valueType != napi_function) {
148             HILOG_ERROR("%{public}s, callback error type.", __func__);
149             return false;
150         }
151         napi_create_reference(env, argv[1], 1, &syncContext->callbackRef);
152     }
153     HILOG_INFO("%{public}s, end.", __func__);
154     return true;
155 }
156 
StartSyncRemoteMissionsAsyncWork(napi_env env,const napi_value resourceName,SyncRemoteMissionsContext * syncContext)157 void StartSyncRemoteMissionsAsyncWork(napi_env env, const napi_value resourceName,
158     SyncRemoteMissionsContext* syncContext)
159 {
160     HILOG_INFO("%{public}s, called.", __func__);
161     napi_create_async_work(env, nullptr, resourceName,
162         [](napi_env env, void* data) {
163             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
164             syncContext->result = AbilityManagerClient::GetInstance()->
165                 StartSyncRemoteMissions(syncContext->deviceId,
166                 syncContext->fixConflict, syncContext->tag);
167         },
168         [](napi_env env, napi_status status, void* data) {
169             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
170             // set result
171             napi_value result[2] = { 0 };
172             napi_get_undefined(env, &result[1]);
173             if (syncContext->result == 0) {
174                 napi_get_undefined(env, &result[0]);
175             } else {
176                 napi_value message = nullptr;
177                 napi_create_string_utf8(env, ("StartSyncRemoteMissions failed, error : " +
178                     std::to_string(syncContext->result)).c_str(), NAPI_AUTO_LENGTH, &message);
179                 napi_create_error(env, nullptr, message, &result[0]);
180             }
181 
182             if (syncContext->callbackRef == nullptr) { // promise
183                 if (syncContext->result == 0) {
184                     napi_resolve_deferred(env, syncContext->deferred, result[1]);
185                 } else {
186                     napi_reject_deferred(env, syncContext->deferred, result[0]);
187                 }
188             } else { // AsyncCallback
189                 napi_value callback = nullptr;
190                 napi_get_reference_value(env, syncContext->callbackRef, &callback);
191                 napi_value callResult;
192                 napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
193                 napi_delete_reference(env, syncContext->callbackRef);
194             }
195             napi_delete_async_work(env, syncContext->work);
196             delete syncContext;
197             syncContext = nullptr;
198         },
199         (void *)syncContext,
200         &syncContext->work);
201         napi_queue_async_work(env, syncContext->work);
202     HILOG_INFO("%{public}s, end.", __func__);
203 }
204 
NAPI_StartSyncRemoteMissions(napi_env env,napi_callback_info info)205 napi_value NAPI_StartSyncRemoteMissions(napi_env env, napi_callback_info info)
206 {
207     HILOG_INFO("%{public}s, test1 called.", __func__);
208     auto syncContext = new SyncRemoteMissionsContext();
209     if (syncContext == nullptr) {
210         HILOG_ERROR("%{public}s, syncContext is nullptr.", __func__);
211         NAPI_ASSERT(env, false, "wrong arguments");
212     }
213     if (!ProcessSyncInput(env, info, true, syncContext)) {
214         delete syncContext;
215         syncContext = nullptr;
216         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
217         NAPI_ASSERT(env, false, "Wrong argument");
218     }
219     napi_value result = nullptr;
220     if (syncContext->callbackRef == nullptr) {
221         napi_create_promise(env, &syncContext->deferred, &result);
222     } else {
223         napi_get_undefined(env, &result);
224     }
225 
226     napi_value resourceName = nullptr;
227     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
228 
229     StartSyncRemoteMissionsAsyncWork(env, resourceName, syncContext);
230     HILOG_INFO("%{public}s, end.", __func__);
231     return result;
232 }
233 
StopSyncRemoteMissionsAsyncWork(napi_env env,napi_value resourceName,SyncRemoteMissionsContext * syncContext)234 void StopSyncRemoteMissionsAsyncWork(napi_env env, napi_value resourceName,
235     SyncRemoteMissionsContext* syncContext)
236 {
237     HILOG_INFO("%{public}s, called.", __func__);
238     napi_create_async_work(env, nullptr, resourceName,
239         [](napi_env env, void* data) {
240             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
241             syncContext->result = AbilityManagerClient::GetInstance()->
242                 StopSyncRemoteMissions(syncContext->deviceId);
243         },
244         [](napi_env env, napi_status status, void* data) {
245             SyncRemoteMissionsContext* syncContext = (SyncRemoteMissionsContext*)data;
246             // set result
247             napi_value result[2] = { 0 };
248             napi_get_undefined(env, &result[1]);
249             if (syncContext->result == 0) {
250                 napi_get_undefined(env, &result[0]);
251             } else {
252                 napi_value message = nullptr;
253                 napi_create_string_utf8(env, ("StopSyncRemoteMissions failed, error : " +
254                     std::to_string(syncContext->result)).c_str(), NAPI_AUTO_LENGTH, &message);
255                 napi_create_error(env, nullptr, message, &result[0]);
256             }
257 
258             if (syncContext->callbackRef == nullptr) { // promise
259                 if (syncContext->result == 0) {
260                     napi_resolve_deferred(env, syncContext->deferred, result[1]);
261                 } else {
262                     napi_reject_deferred(env, syncContext->deferred, result[0]);
263                 }
264             } else { // AsyncCallback
265                 napi_value callback = nullptr;
266                 napi_get_reference_value(env, syncContext->callbackRef, &callback);
267                 napi_value callResult;
268                 napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
269                 napi_delete_reference(env, syncContext->callbackRef);
270             }
271             napi_delete_async_work(env, syncContext->work);
272             delete syncContext;
273             syncContext = nullptr;
274         },
275         (void *)syncContext,
276         &syncContext->work);
277         napi_queue_async_work(env, syncContext->work);
278     HILOG_INFO("%{public}s, end.", __func__);
279 }
280 
NAPI_StopSyncRemoteMissions(napi_env env,napi_callback_info info)281 napi_value NAPI_StopSyncRemoteMissions(napi_env env, napi_callback_info info)
282 {
283     HILOG_INFO("%{public}s, called.", __func__);
284     auto syncContext = new SyncRemoteMissionsContext();
285     if (syncContext == nullptr) {
286         HILOG_ERROR("%{public}s, syncContext is nullptr.", __func__);
287         NAPI_ASSERT(env, false, "wrong arguments");
288     }
289     if (!ProcessSyncInput(env, info, false, syncContext)) {
290         delete syncContext;
291         syncContext = nullptr;
292         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
293         NAPI_ASSERT(env, false, "Wrong argument");
294     }
295     napi_value result = nullptr;
296     if (syncContext->callbackRef == nullptr) {
297         napi_create_promise(env, &syncContext->deferred, &result);
298     } else {
299         napi_get_undefined(env, &result);
300     }
301 
302     napi_value resourceName = nullptr;
303     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
304 
305     StopSyncRemoteMissionsAsyncWork(env, resourceName, syncContext);
306     HILOG_INFO("%{public}s, end.", __func__);
307     return result;
308 }
309 
CreateRegisterMissonCBCBInfo(napi_env env)310 RegisterMissonCB *CreateRegisterMissonCBCBInfo(napi_env env)
311 {
312     HILOG_INFO("%{public}s called.", __func__);
313     auto registerMissonCB = new (std::nothrow) RegisterMissonCB;
314     if (registerMissonCB == nullptr) {
315         HILOG_ERROR("%{public}s registerMissonCB == nullptr", __func__);
316         return nullptr;
317     }
318     registerMissonCB->cbBase.cbInfo.env = env;
319     registerMissonCB->cbBase.asyncWork = nullptr;
320     registerMissonCB->cbBase.deferred = nullptr;
321     registerMissonCB->callbackRef = nullptr;
322     HILOG_INFO("%{public}s end.", __func__);
323     return registerMissonCB;
324 }
325 
RegisterMissonExecuteCB(napi_env env,void * data)326 void RegisterMissonExecuteCB(napi_env env, void *data)
327 {
328     HILOG_INFO("%{public}s called.", __func__);
329     auto registerMissonCB = (RegisterMissonCB*)data;
330 
331     std::lock_guard<std::mutex> autoLock(registrationLock_);
332     sptr<NAPIRemoteMissionListener> registration;
333     auto item = registration_.find(registerMissonCB->deviceId);
334     if (item != registration_.end()) {
335         HILOG_INFO("registration exits.");
336         registration = registration_[registerMissonCB->deviceId];
337     } else {
338         HILOG_INFO("registration not exits.");
339         registration = new (std::nothrow) NAPIRemoteMissionListener();
340     }
341     registerMissonCB->missionRegistration = registration;
342     if (registerMissonCB->missionRegistration == nullptr) {
343         HILOG_ERROR("%{public}s missionRegistration == nullptr.", __func__);
344         registerMissonCB->result = -1;
345         return;
346     }
347     registerMissonCB->missionRegistration->SetEnv(env);
348     registerMissonCB->missionRegistration->
349         SetNotifyMissionsChangedCBRef(registerMissonCB->missionRegistrationCB.callback[0]);
350     registerMissonCB->missionRegistration->
351         SetNotifySnapshotCBRef(registerMissonCB->missionRegistrationCB.callback[1]);
352     registerMissonCB->missionRegistration->
353         SetNotifyNetDisconnectCBRef(registerMissonCB->
354             missionRegistrationCB.callback[2]); // 2 refers the second argument
355     HILOG_INFO("set callback success.");
356 
357     registerMissonCB->result =
358         AbilityManagerClient::GetInstance()->
359         RegisterMissionListener(registerMissonCB->deviceId,
360         registerMissonCB->missionRegistration);
361     if (registerMissonCB->result == NO_ERROR) {
362         HILOG_INFO("add registration.");
363         registration_[registerMissonCB->deviceId] = registration;
364     }
365     HILOG_INFO("%{public}s end.deviceId:%{public}d ", __func__, registerMissonCB->result);
366 }
367 
RegisterMissonCallbackCompletedCB(napi_env env,napi_status status,void * data)368 void RegisterMissonCallbackCompletedCB(napi_env env, napi_status status, void *data)
369 {
370     HILOG_INFO("%{public}s called.", __func__);
371     auto registerMissonCB = static_cast<RegisterMissonCB *>(data);
372     // set result
373     napi_value result[2] = { 0 };
374     napi_get_undefined(env, &result[1]);
375     if (registerMissonCB->result == 0) {
376         napi_get_undefined(env, &result[0]);
377     } else {
378         napi_value message = nullptr;
379         napi_create_string_utf8(env, ("registerMissionListener failed, error : " +
380             std::to_string(registerMissonCB->result)).c_str(), NAPI_AUTO_LENGTH, &message);
381         napi_create_error(env, nullptr, message, &result[0]);
382     }
383 
384     if (registerMissonCB->callbackRef == nullptr) { // promise
385         if (registerMissonCB->result == 0) {
386             napi_resolve_deferred(env, registerMissonCB->cbBase.deferred, result[1]);
387         } else {
388             napi_reject_deferred(env, registerMissonCB->cbBase.deferred, result[0]);
389         }
390     } else { // AsyncCallback
391         napi_value callback = nullptr;
392         napi_get_reference_value(env, registerMissonCB->callbackRef, &callback);
393         napi_value callResult;
394         napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
395         napi_delete_reference(env, registerMissonCB->callbackRef);
396     }
397     NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, registerMissonCB->cbBase.asyncWork));
398     delete registerMissonCB;
399     registerMissonCB = nullptr;
400     HILOG_INFO("%{public}s end.", __func__);
401 }
402 
RegisterMissonAsync(napi_env env,napi_value * args,RegisterMissonCB * registerMissonCB)403 napi_value RegisterMissonAsync(napi_env env, napi_value *args, RegisterMissonCB *registerMissonCB)
404 {
405     HILOG_INFO("%{public}s asyncCallback.", __func__);
406     if (args == nullptr || registerMissonCB == nullptr) {
407         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
408         return nullptr;
409     }
410     napi_value result = nullptr;
411     if (registerMissonCB->callbackRef == nullptr) {
412         napi_create_promise(env, &registerMissonCB->cbBase.deferred, &result);
413     } else {
414         napi_get_undefined(env, &result);
415     }
416     napi_value resourceName = nullptr;
417     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
418 
419     napi_create_async_work(env,
420         nullptr,
421         resourceName,
422         RegisterMissonExecuteCB,
423         RegisterMissonCallbackCompletedCB,
424         (void *)registerMissonCB,
425         &registerMissonCB->cbBase.asyncWork);
426     napi_queue_async_work(env, registerMissonCB->cbBase.asyncWork);
427     HILOG_INFO("%{public}s asyncCallback end.", __func__);
428     return result;
429 }
430 
SetCallbackReference(napi_env env,const napi_value & value,RegisterMissonCB * registerMissonCB)431 bool SetCallbackReference(napi_env env, const napi_value& value, RegisterMissonCB *registerMissonCB)
432 {
433     HILOG_INFO("%{public}s called.", __func__);
434     bool isFirstCallback = false;
435     napi_has_named_property(env, value, "notifyMissionsChanged", &isFirstCallback);
436     bool isSecondCallback = false;
437     napi_has_named_property(env, value, "notifySnapshot", &isSecondCallback);
438     bool isThirdCallback = false;
439     napi_has_named_property(env, value, "notifyNetDisconnect", &isThirdCallback);
440     if (!isFirstCallback || !isSecondCallback || !isThirdCallback) {
441         HILOG_ERROR("%{public}s, Wrong argument name for callback.", __func__);
442         return false;
443     }
444     napi_value jsMethod = nullptr;
445     napi_get_named_property(env, value, "notifyMissionsChanged", &jsMethod);
446     if (jsMethod == nullptr) {
447         HILOG_ERROR("%{public}s, not find callback notifyMissionsChanged.", __func__);
448         return false;
449     }
450     napi_valuetype valuetype = napi_undefined;
451     napi_typeof(env, jsMethod, &valuetype);
452     if (valuetype != napi_function) {
453         HILOG_ERROR("%{public}s, notifyMissionsChanged callback error type.", __func__);
454         return false;
455     }
456     napi_create_reference(env, jsMethod, 1, &registerMissonCB->missionRegistrationCB.callback[0]);
457 
458     napi_get_named_property(env, value, "notifySnapshot", &jsMethod);
459     if (jsMethod == nullptr) {
460         HILOG_ERROR("%{public}s, not find callback notifySnapshot.", __func__);
461         return false;
462     }
463     napi_typeof(env, jsMethod, &valuetype);
464     if (valuetype != napi_function) {
465         HILOG_ERROR("%{public}s, notifySnapshot callback error type.", __func__);
466         return false;
467     }
468     napi_create_reference(env, jsMethod, 1, &registerMissonCB->missionRegistrationCB.callback[1]);
469 
470     napi_get_named_property(env, value, "notifyNetDisconnect", &jsMethod);
471     if (jsMethod == nullptr) {
472         HILOG_ERROR("%{public}s, not find callback notifyNetDisconnect.", __func__);
473         return false;
474     }
475     napi_typeof(env, jsMethod, &valuetype);
476     if (valuetype != napi_function) {
477         HILOG_ERROR("%{public}s, notifyNetDisconnect callback error type.", __func__);
478         return false;
479     }
480     napi_create_reference(env, jsMethod, 1,
481         &registerMissonCB->missionRegistrationCB.callback[2]); // 2 refers the second argument
482     HILOG_INFO("%{public}s called end.", __func__);
483     return true;
484 }
485 
CreateCallbackReference(napi_env env,const napi_value & value,RegisterMissonCB * registerMissonCB)486 bool CreateCallbackReference(napi_env env, const napi_value& value, RegisterMissonCB *registerMissonCB)
487 {
488     HILOG_INFO("%{public}s called.", __func__);
489     napi_valuetype valuetype = napi_undefined;
490     napi_typeof(env, value, &valuetype);
491     if (valuetype == napi_object) {
492         if (!SetCallbackReference(env, value, registerMissonCB)) {
493             HILOG_ERROR("%{public}s, Wrong callback.", __func__);
494             return false;
495         }
496     } else {
497         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
498         return false;
499     }
500     HILOG_INFO("%{public}s called end.", __func__);
501     return true;
502 }
503 
RegisterMissonWrap(napi_env env,napi_callback_info info,RegisterMissonCB * registerMissonCB)504 napi_value RegisterMissonWrap(napi_env env, napi_callback_info info, RegisterMissonCB *registerMissonCB)
505 {
506     HILOG_INFO("%{public}s called.", __func__);
507     size_t argcAsync = 3;
508     napi_value args[ARGS_MAX_COUNT] = {nullptr};
509     napi_value ret = nullptr;
510     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
511     HILOG_INFO("argcAsync is %{public}zu", argcAsync);
512     if (argcAsync != ARGS_TWO && argcAsync != ARGS_THREE) {
513         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
514         return nullptr;
515     }
516     napi_value firstNApi = nullptr;
517     napi_valuetype valueType = napi_undefined;
518     bool isDeviceId = false;
519     napi_has_named_property(env, args[0], "deviceId", &isDeviceId);
520     napi_typeof(env, args[0], &valueType);
521     if (isDeviceId && valueType == napi_object) {
522         napi_get_named_property(env, args[0], "deviceId", &firstNApi);
523     } else {
524         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
525         return nullptr;
526     }
527     if (firstNApi == nullptr) {
528         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
529         return nullptr;
530     }
531 
532     napi_typeof(env, firstNApi, &valueType);
533     if (valueType != napi_string) {
534         HILOG_ERROR("%{public}s, deviceId error type.", __func__);
535         return nullptr;
536     }
537     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
538     size_t valueLen = 0;
539     napi_get_value_string_utf8(env, firstNApi, deviceId, VALUE_BUFFER_SIZE + 1, &valueLen);
540     if (valueLen > VALUE_BUFFER_SIZE) {
541         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
542         return nullptr;
543     }
544     registerMissonCB->deviceId = deviceId;
545     HILOG_INFO("%{public}s deviceId:%{public}s", __func__, registerMissonCB->deviceId.c_str());
546 
547     if (argcAsync > 1 && !CreateCallbackReference(env, args[1], registerMissonCB)) {
548         HILOG_ERROR("%{public}s, Wrong arguments.", __func__);
549         return nullptr;
550     }
551 
552     if (argcAsync == ARGS_THREE) {
553         napi_typeof(env, args[ARGS_TWO], &valueType);
554         if (valueType != napi_function) {
555             HILOG_ERROR("%{public}s, callback error type.", __func__);
556             return nullptr;
557         }
558         napi_create_reference(env, args[ARGS_TWO], 1, &registerMissonCB->callbackRef);
559     }
560 
561     ret = RegisterMissonAsync(env, args, registerMissonCB);
562     HILOG_INFO("%{public}s called end.", __func__);
563     return ret;
564 }
565 
NAPI_RegisterMissionListener(napi_env env,napi_callback_info info)566 napi_value NAPI_RegisterMissionListener(napi_env env, napi_callback_info info)
567 {
568     HILOG_INFO("%{public}s called.", __func__);
569     RegisterMissonCB *registerMissonCB = CreateRegisterMissonCBCBInfo(env);
570     if (registerMissonCB == nullptr) {
571         HILOG_ERROR("%{public}s registerMissonCB == nullptr", __func__);
572         NAPI_ASSERT(env, false, "wrong arguments");
573     }
574 
575     napi_value ret = RegisterMissonWrap(env, info, registerMissonCB);
576     if (ret == nullptr) {
577         HILOG_ERROR("%{public}s ret == nullptr", __func__);
578         delete registerMissonCB;
579         registerMissonCB = nullptr;
580         NAPI_ASSERT(env, false, "wrong arguments");
581     }
582     HILOG_INFO("%{public}s end.", __func__);
583     return ret;
584 }
585 
SetEnv(const napi_env & env)586 void NAPIMissionContinue::SetEnv(const napi_env &env)
587 {
588     env_ = env;
589 }
590 
SetEnv(const napi_env & env)591 void NAPIRemoteMissionListener::SetEnv(const napi_env &env)
592 {
593     env_ = env;
594 }
595 
SetNotifyMissionsChangedCBRef(const napi_ref & ref)596 void NAPIRemoteMissionListener::SetNotifyMissionsChangedCBRef(const napi_ref &ref)
597 {
598     notifyMissionsChangedRef_ = ref;
599 }
600 
SetNotifySnapshotCBRef(const napi_ref & ref)601 void NAPIRemoteMissionListener::SetNotifySnapshotCBRef(const napi_ref &ref)
602 {
603     notifySnapshotRef_ = ref;
604 }
605 
SetNotifyNetDisconnectCBRef(const napi_ref & ref)606 void NAPIRemoteMissionListener::SetNotifyNetDisconnectCBRef(const napi_ref &ref)
607 {
608     notifyNetDisconnectRef_ = ref;
609 }
610 
UvWorkNotifyMissionChanged(uv_work_t * work,int status)611 void UvWorkNotifyMissionChanged(uv_work_t *work, int status)
612 {
613     HILOG_INFO("UvWorkNotifyMissionChanged, uv_queue_work");
614     if (work == nullptr) {
615         HILOG_ERROR("UvWorkNotifyMissionChanged, work is null");
616         return;
617     }
618     RegisterMissonCB *registerMissonCB = static_cast<RegisterMissonCB *>(work->data);
619     if (registerMissonCB == nullptr) {
620         HILOG_ERROR("UvWorkNotifyMissionChanged, registerMissonCB is null");
621         delete work;
622         return;
623     }
624     napi_value result = nullptr;
625     HILOG_INFO("UvWorkNotifyMissionChanged, deviceId = %{public}s", registerMissonCB->deviceId.c_str());
626     result =
627         WrapString(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->deviceId.c_str(), "deviceId");
628 
629     napi_value callback = nullptr;
630     napi_value undefined = nullptr;
631     napi_get_undefined(registerMissonCB->cbBase.cbInfo.env, &undefined);
632     napi_value callResult = nullptr;
633     napi_get_reference_value(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->cbBase.cbInfo.callback, &callback);
634 
635     napi_call_function(registerMissonCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
636     delete registerMissonCB;
637     registerMissonCB = nullptr;
638     delete work;
639     HILOG_INFO("UvWorkNotifyMissionChanged, uv_queue_work end");
640 }
641 
NotifyMissionsChanged(const std::string & deviceId)642 void NAPIRemoteMissionListener::NotifyMissionsChanged(const std::string& deviceId)
643 {
644     HILOG_INFO("%{public}s, called. deviceId = %{public}s", __func__, deviceId.c_str());
645     uv_loop_s *loop = nullptr;
646 
647     napi_get_uv_event_loop(env_, &loop);
648     if (loop == nullptr) {
649         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
650         return;
651     }
652 
653     uv_work_t *work = new uv_work_t;
654     if (work == nullptr) {
655         HILOG_ERROR("%{public}s, work==nullptr.", __func__);
656         return;
657     }
658 
659     auto registerMissonCB = new (std::nothrow) RegisterMissonCB;
660     if (registerMissonCB == nullptr) {
661         HILOG_ERROR("%{public}s, registerMissonCB == nullptr.", __func__);
662         delete work;
663         return;
664     }
665     registerMissonCB->cbBase.cbInfo.env = env_;
666     registerMissonCB->cbBase.cbInfo.callback = notifyMissionsChangedRef_;
667     registerMissonCB->deviceId = deviceId;
668     work->data = (void *)registerMissonCB;
669 
670     int rev = uv_queue_work(
671         loop, work, [](uv_work_t *work) {}, UvWorkNotifyMissionChanged);
672     if (rev != 0) {
673         delete registerMissonCB;
674         registerMissonCB = nullptr;
675         delete work;
676     }
677     HILOG_INFO("%{public}s, end.", __func__);
678 }
679 
UvWorkNotifySnapshot(uv_work_t * work,int status)680 void UvWorkNotifySnapshot(uv_work_t *work, int status)
681 {
682     HILOG_INFO("UvWorkNotifySnapshot, uv_queue_work");
683     if (work == nullptr) {
684         HILOG_ERROR("UvWorkNotifySnapshot, work is null");
685         return;
686     }
687     RegisterMissonCB *registerMissonCB = static_cast<RegisterMissonCB *>(work->data);
688     if (registerMissonCB == nullptr) {
689         HILOG_ERROR("UvWorkNotifySnapshot, registerMissonCB is null");
690         delete work;
691         return;
692     }
693     napi_value result[2] = {0};
694     HILOG_INFO("UvWorkNotifySnapshot, deviceId = %{public}s", registerMissonCB->deviceId.c_str());
695     result[0] =
696         WrapString(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->deviceId.c_str(), "deviceId");
697     HILOG_INFO("UvWorkNotifySnapshot, missionId = %{public}d", registerMissonCB->missionId);
698     result[1] =
699         WrapInt32(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->missionId, "missionId");
700 
701     napi_value callback = nullptr;
702     napi_value undefined = nullptr;
703     napi_get_undefined(registerMissonCB->cbBase.cbInfo.env, &undefined);
704     napi_value callResult = nullptr;
705     napi_get_reference_value(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->cbBase.cbInfo.callback, &callback);
706 
707     napi_call_function(registerMissonCB->cbBase.cbInfo.env, undefined, callback, ARGS_TWO, &result[0], &callResult);
708     delete registerMissonCB;
709     registerMissonCB = nullptr;
710     delete work;
711     HILOG_INFO("UvWorkNotifySnapshot, uv_queue_work end");
712 }
713 
NotifySnapshot(const std::string & deviceId,int32_t missionId)714 void NAPIRemoteMissionListener::NotifySnapshot(const std::string& deviceId, int32_t missionId)
715 {
716     HILOG_INFO("%{public}s, called. deviceId = %{public}s", __func__, deviceId.c_str());
717     uv_loop_s *loop = nullptr;
718 
719     napi_get_uv_event_loop(env_, &loop);
720     if (loop == nullptr) {
721         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
722         return;
723     }
724 
725     uv_work_t *work = new uv_work_t;
726     if (work == nullptr) {
727         HILOG_ERROR("%{public}s, work==nullptr.", __func__);
728         return;
729     }
730 
731     auto registerMissonCB = new (std::nothrow) RegisterMissonCB;
732     if (registerMissonCB == nullptr) {
733         HILOG_ERROR("%{public}s, registerMissonCB == nullptr.", __func__);
734         delete work;
735         return;
736     }
737     registerMissonCB->cbBase.cbInfo.env = env_;
738     registerMissonCB->cbBase.cbInfo.callback = notifySnapshotRef_;
739     registerMissonCB->deviceId = deviceId;
740     registerMissonCB->missionId = missionId;
741     work->data = (void *)registerMissonCB;
742 
743     int rev = uv_queue_work(
744         loop, work, [](uv_work_t *work) {}, UvWorkNotifySnapshot);
745     if (rev != 0) {
746         delete registerMissonCB;
747         registerMissonCB = nullptr;
748         delete work;
749     }
750     HILOG_INFO("%{public}s, end.", __func__);
751 }
752 
UvWorkNotifyNetDisconnect(uv_work_t * work,int status)753 void UvWorkNotifyNetDisconnect(uv_work_t *work, int status)
754 {
755     HILOG_INFO("UvWorkNotifyNetDisconnect, uv_queue_work");
756     if (work == nullptr) {
757         HILOG_ERROR("UvWorkNotifyNetDisconnect, work is null");
758         return;
759     }
760     RegisterMissonCB *registerMissonCB = static_cast<RegisterMissonCB *>(work->data);
761     if (registerMissonCB == nullptr) {
762         HILOG_ERROR("UvWorkNotifyNetDisconnect, registerMissonCB is null");
763         delete work;
764         return;
765     }
766     napi_value result[2] = {0};
767     HILOG_INFO("UvWorkNotifyNetDisconnect, deviceId = %{public}s", registerMissonCB->deviceId.c_str());
768     result[0] =
769         WrapString(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->deviceId.c_str(), "deviceId");
770     HILOG_INFO("UvWorkNotifyNetDisconnect, state = %{public}d", registerMissonCB->state);
771     result[1] =
772         WrapInt32(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->state, "state");
773 
774     napi_value callback = nullptr;
775     napi_value undefined = nullptr;
776     napi_get_undefined(registerMissonCB->cbBase.cbInfo.env, &undefined);
777     napi_value callResult = nullptr;
778     napi_get_reference_value(registerMissonCB->cbBase.cbInfo.env, registerMissonCB->cbBase.cbInfo.callback, &callback);
779 
780     napi_call_function(registerMissonCB->cbBase.cbInfo.env, undefined, callback, ARGS_TWO, &result[0], &callResult);
781     delete registerMissonCB;
782     registerMissonCB = nullptr;
783     delete work;
784     HILOG_INFO("UvWorkNotifyNetDisconnect, uv_queue_work end");
785 }
786 
NotifyNetDisconnect(const std::string & deviceId,int32_t state)787 void NAPIRemoteMissionListener::NotifyNetDisconnect(const std::string& deviceId, int32_t state)
788 {
789     HILOG_INFO("%{public}s called. deviceId = %{public}s. state = %{public}d", __func__,
790         deviceId.c_str(), state);
791     uv_loop_s *loop = nullptr;
792 
793     napi_get_uv_event_loop(env_, &loop);
794     if (loop == nullptr) {
795         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
796         return;
797     }
798 
799     uv_work_t *work = new uv_work_t;
800     if (work == nullptr) {
801         HILOG_ERROR("%{public}s, work==nullptr.", __func__);
802         return;
803     }
804 
805     auto registerMissonCB = new (std::nothrow) RegisterMissonCB;
806     if (registerMissonCB == nullptr) {
807         HILOG_ERROR("%{public}s, registerMissonCB == nullptr.", __func__);
808         delete work;
809         return;
810     }
811     registerMissonCB->cbBase.cbInfo.env = env_;
812     registerMissonCB->cbBase.cbInfo.callback = notifyNetDisconnectRef_;
813     registerMissonCB->deviceId = deviceId;
814     registerMissonCB->state = state;
815     work->data = (void *)registerMissonCB;
816 
817     int rev = uv_queue_work(
818         loop, work, [](uv_work_t *work) {}, UvWorkNotifyNetDisconnect);
819     if (rev != 0) {
820         delete registerMissonCB;
821         registerMissonCB = nullptr;
822         delete work;
823     }
824     HILOG_INFO("%{public}s, end.", __func__);
825 }
826 
UnRegisterMissonExecuteCB(napi_env env,void * data)827 void UnRegisterMissonExecuteCB(napi_env env, void *data)
828 {
829     HILOG_INFO("%{public}s called.", __func__);
830     auto registerMissonCB = (RegisterMissonCB*)data;
831 
832     std::lock_guard<std::mutex> autoLock(registrationLock_);
833     sptr<NAPIRemoteMissionListener> registration;
834     auto item = registration_.find(registerMissonCB->deviceId);
835     if (item != registration_.end()) {
836         HILOG_INFO("registration exits.");
837         registration = registration_[registerMissonCB->deviceId];
838     } else {
839         HILOG_INFO("registration not exits.");
840         registerMissonCB->result = -1;
841         return;
842     }
843     registerMissonCB->missionRegistration = registration;
844 
845     registerMissonCB->result =
846         AbilityManagerClient::GetInstance()->
847         UnRegisterMissionListener(registerMissonCB->deviceId,
848         registerMissonCB->missionRegistration);
849     if (registerMissonCB->result == NO_ERROR) {
850         HILOG_INFO("remove registration.");
851         registration_.erase(registerMissonCB->deviceId);
852     }
853     HILOG_INFO("%{public}s end.deviceId:%{public}d ", __func__, registerMissonCB->result);
854 }
855 
UnRegisterMissonPromiseCompletedCB(napi_env env,napi_status status,void * data)856 void UnRegisterMissonPromiseCompletedCB(napi_env env, napi_status status, void *data)
857 {
858     HILOG_INFO("%{public}s called.", __func__);
859     auto registerMissonCB = (RegisterMissonCB*)data;
860     // set result
861     napi_value result[2] = { 0 };
862     napi_get_undefined(env, &result[1]);
863     if (registerMissonCB->result == 0) {
864         napi_get_undefined(env, &result[0]);
865     } else {
866         napi_value message = nullptr;
867         napi_create_string_utf8(env, ("unRegisterMissionListener failed, error : " +
868             std::to_string(registerMissonCB->result)).c_str(), NAPI_AUTO_LENGTH, &message);
869         napi_create_error(env, nullptr, message, &result[0]);
870     }
871 
872     if (registerMissonCB->callbackRef == nullptr) { // promise
873         if (registerMissonCB->result == 0) {
874             napi_resolve_deferred(env, registerMissonCB->cbBase.deferred, result[1]);
875         } else {
876             napi_reject_deferred(env, registerMissonCB->cbBase.deferred, result[0]);
877         }
878     } else { // AsyncCallback
879         napi_value callback = nullptr;
880         napi_get_reference_value(env, registerMissonCB->callbackRef, &callback);
881         napi_value callResult;
882         napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
883         napi_delete_reference(env, registerMissonCB->callbackRef);
884     }
885     napi_delete_async_work(env, registerMissonCB->cbBase.asyncWork);
886     delete registerMissonCB;
887     registerMissonCB = nullptr;
888     HILOG_INFO("%{public}s end.", __func__);
889 }
890 
UnRegisterMissonPromise(napi_env env,RegisterMissonCB * registerMissonCB)891 napi_value UnRegisterMissonPromise(napi_env env, RegisterMissonCB *registerMissonCB)
892 {
893     HILOG_INFO("%{public}s asyncCallback.", __func__);
894     if (registerMissonCB == nullptr) {
895         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
896         return nullptr;
897     }
898     napi_value promise = nullptr;
899     if (registerMissonCB->callbackRef == nullptr) {
900         napi_create_promise(env, &registerMissonCB->cbBase.deferred, &promise);
901     } else {
902         napi_get_undefined(env, &promise);
903     }
904 
905     napi_value resourceName = nullptr;
906     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
907 
908     napi_create_async_work(env,
909         nullptr,
910         resourceName,
911         UnRegisterMissonExecuteCB,
912         UnRegisterMissonPromiseCompletedCB,
913         (void *)registerMissonCB,
914         &registerMissonCB->cbBase.asyncWork);
915     napi_queue_async_work(env, registerMissonCB->cbBase.asyncWork);
916     HILOG_INFO("%{public}s asyncCallback end.", __func__);
917     return promise;
918 }
919 
GetUnRegisterMissonDeviceId(napi_env env,const napi_value & value,RegisterMissonCB * registerMissonCB)920 bool GetUnRegisterMissonDeviceId(napi_env env, const napi_value& value, RegisterMissonCB *registerMissonCB)
921 {
922     HILOG_INFO("%{public}s called.", __func__);
923     napi_value firstNApi = nullptr;
924     napi_valuetype valueType = napi_undefined;
925     bool isDeviceId = false;
926     napi_has_named_property(env, value, "deviceId", &isDeviceId);
927     napi_typeof(env, value, &valueType);
928     if (isDeviceId && valueType == napi_object) {
929         napi_get_named_property(env, value, "deviceId", &firstNApi);
930     } else {
931         HILOG_ERROR("%{public}s, Wrong argument name for deviceId.", __func__);
932         return false;
933     }
934     if (firstNApi == nullptr) {
935         HILOG_ERROR("%{public}s, not find deviceId.", __func__);
936         return false;
937     }
938 
939     size_t valueLen = 0;
940     napi_typeof(env, firstNApi, &valueType);
941     if (valueType != napi_string) {
942         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
943         return false;
944     }
945     char deviceId[VALUE_BUFFER_SIZE + 1] = {0};
946     napi_get_value_string_utf8(env, firstNApi, deviceId, VALUE_BUFFER_SIZE + 1, &valueLen);
947     if (valueLen > VALUE_BUFFER_SIZE) {
948         HILOG_ERROR("%{public}s, deviceId length not correct", __func__);
949         return false;
950     }
951     registerMissonCB->deviceId = deviceId;
952     HILOG_INFO("%{public}s deviceId:%{public}s", __func__, registerMissonCB->deviceId.c_str());
953     HILOG_INFO("%{public}s called end.", __func__);
954     return true;
955 }
956 
UnRegisterMissonWrap(napi_env env,napi_callback_info info,RegisterMissonCB * registerMissonCB)957 napi_value UnRegisterMissonWrap(napi_env env, napi_callback_info info, RegisterMissonCB *registerMissonCB)
958 {
959     HILOG_INFO("%{public}s called.", __func__);
960     size_t argc = 2;
961     napi_value args[ARGS_MAX_COUNT] = {nullptr};
962     napi_value ret = nullptr;
963 
964     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
965     HILOG_INFO("argc is %{public}zu", argc);
966     if (argc != ARGS_ONE && argc != ARGS_TWO) {
967         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
968         return nullptr;
969     }
970 
971     if (!GetUnRegisterMissonDeviceId(env, args[0], registerMissonCB)) {
972         HILOG_ERROR("%{public}s, Wrong argument.", __func__);
973         return nullptr;
974     }
975 
976     if (argc == ARGS_TWO) {
977         napi_valuetype valueType = napi_undefined;
978         napi_typeof(env, args[1], &valueType);
979         if (valueType != napi_function) {
980             HILOG_ERROR("%{public}s, callback error type.", __func__);
981             return nullptr;
982         }
983         napi_create_reference(env, args[1], 1, &registerMissonCB->callbackRef);
984     }
985     ret = UnRegisterMissonPromise(env, registerMissonCB);
986     HILOG_INFO("%{public}s called end.", __func__);
987     return ret;
988 }
989 
NAPI_UnRegisterMissionListener(napi_env env,napi_callback_info info)990 napi_value NAPI_UnRegisterMissionListener(napi_env env, napi_callback_info info)
991 {
992     HILOG_INFO("%{public}s called.", __func__);
993     RegisterMissonCB *registerMissonCB = CreateRegisterMissonCBCBInfo(env);
994     if (registerMissonCB == nullptr) {
995         HILOG_ERROR("%{public}s registerMissonCB == nullptr", __func__);
996         NAPI_ASSERT(env, false, "wrong arguments");
997     }
998 
999     napi_value ret = UnRegisterMissonWrap(env, info, registerMissonCB);
1000     if (ret == nullptr) {
1001         HILOG_ERROR("%{public}s ret == nullptr", __func__);
1002         delete registerMissonCB;
1003         registerMissonCB = nullptr;
1004         NAPI_ASSERT(env, false, "wrong arguments");
1005     }
1006     HILOG_INFO("%{public}s end.", __func__);
1007     return ret;
1008 }
1009 
WrapString(napi_env env,const std::string & param,const std::string & paramName)1010 napi_value WrapString(napi_env env, const std::string &param, const std::string &paramName)
1011 {
1012     HILOG_INFO("%{public}s called.", __func__);
1013 
1014     napi_value jsObject = nullptr;
1015     napi_create_object(env, &jsObject);
1016 
1017     napi_value jsValue = nullptr;
1018     HILOG_INFO("%{public}s called. %{public}s = %{public}s", __func__, paramName.c_str(), param.c_str());
1019     napi_create_string_utf8(env, param.c_str(), NAPI_AUTO_LENGTH, &jsValue);
1020     napi_set_named_property(env, jsObject, paramName.c_str(), jsValue);
1021 
1022     return jsObject;
1023 }
1024 
WrapInt32(napi_env env,int32_t num,const std::string & paramName)1025 napi_value WrapInt32(napi_env env, int32_t num, const std::string &paramName)
1026 {
1027     HILOG_INFO("%{public}s called.", __func__);
1028 
1029     napi_value jsObject = nullptr;
1030     napi_create_object(env, &jsObject);
1031 
1032     napi_value jsValue = nullptr;
1033     HILOG_INFO("%{public}s called. %{public}s = %{public}d", __func__, paramName.c_str(), num);
1034     napi_create_int32(env, num, &jsValue);
1035     napi_set_named_property(env, jsObject, paramName.c_str(), jsValue);
1036 
1037     return jsObject;
1038 }
1039 
CreateContinueAbilityCBCBInfo(napi_env env)1040 ContinueAbilityCB *CreateContinueAbilityCBCBInfo(napi_env env)
1041 {
1042     HILOG_INFO("%{public}s called.", __func__);
1043     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
1044     if (continueAbilityCB == nullptr) {
1045         HILOG_ERROR("%{public}s continueAbilityCB == nullptr", __func__);
1046         return nullptr;
1047     }
1048     continueAbilityCB->cbBase.cbInfo.env = env;
1049     continueAbilityCB->cbBase.asyncWork = nullptr;
1050     continueAbilityCB->cbBase.deferred = nullptr;
1051     continueAbilityCB->callbackRef = nullptr;
1052     HILOG_INFO("%{public}s end.", __func__);
1053     return continueAbilityCB;
1054 }
1055 
ContinueAbilityExecuteCB(napi_env env,void * data)1056 void ContinueAbilityExecuteCB(napi_env env, void *data)
1057 {
1058     HILOG_INFO("%{public}s called.", __func__);
1059     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1060     HILOG_INFO("create continueAbilityCB success.");
1061     sptr<NAPIMissionContinue> continuation(new (std::nothrow) NAPIMissionContinue());
1062     continueAbilityCB->abilityContinuation = continuation;
1063     if (continueAbilityCB->abilityContinuation == nullptr) {
1064         HILOG_ERROR("%{public}s abilityContinuation == nullptr.", __func__);
1065         return;
1066     }
1067     continueAbilityCB->abilityContinuation->SetContinueAbilityEnv(env);
1068     HILOG_INFO("set env success.");
1069     continueAbilityCB->abilityContinuation->
1070         SetContinueAbilityCBRef(continueAbilityCB->abilityContinuationCB.callback[0]);
1071     HILOG_INFO("set callback success.");
1072     continueAbilityCB->result = -1;
1073     continueAbilityCB->result = AAFwk::AbilityManagerClient::GetInstance()->
1074         ContinueMission(continueAbilityCB->srcDeviceId, continueAbilityCB->dstDeviceId,
1075         continueAbilityCB->missionId, continueAbilityCB->abilityContinuation,
1076         continueAbilityCB->wantParams);
1077     HILOG_INFO("%{public}s end. error:%{public}d ", __func__, continueAbilityCB->result);
1078 }
1079 
ContinueAbilityCallbackCompletedCB(napi_env env,napi_status status,void * data)1080 void ContinueAbilityCallbackCompletedCB(napi_env env, napi_status status, void *data)
1081 {
1082     HILOG_INFO("%{public}s called.", __func__);
1083     auto continueAbilityCB = static_cast<ContinueAbilityCB *>(data);
1084     // set result
1085     napi_value result[2] = { 0 };
1086     napi_get_undefined(env, &result[1]);
1087     if (continueAbilityCB->result == 0) {
1088         napi_get_undefined(env, &result[0]);
1089     } else {
1090         napi_value message = nullptr;
1091         napi_create_string_utf8(env, ("ContinueAbility failed, error : " +
1092             std::to_string(continueAbilityCB->result)).c_str(), NAPI_AUTO_LENGTH, &message);
1093         napi_create_error(env, nullptr, message, &result[0]);
1094     }
1095 
1096     if (continueAbilityCB->callbackRef == nullptr) { // promise
1097         if (continueAbilityCB->result == 0) {
1098             napi_resolve_deferred(env, continueAbilityCB->cbBase.deferred, result[1]);
1099         } else {
1100             napi_reject_deferred(env, continueAbilityCB->cbBase.deferred, result[0]);
1101         }
1102     } else { // AsyncCallback
1103         napi_value callback = nullptr;
1104         napi_get_reference_value(env, continueAbilityCB->callbackRef, &callback);
1105         napi_value callResult;
1106         napi_call_function(env, nullptr, callback, ARGS_TWO, &result[0], &callResult);
1107         napi_delete_reference(env, continueAbilityCB->callbackRef);
1108     }
1109     napi_delete_async_work(env, continueAbilityCB->cbBase.asyncWork);
1110     delete continueAbilityCB;
1111     continueAbilityCB = nullptr;
1112     HILOG_INFO("%{public}s end.", __func__);
1113 }
1114 
ContinueAbilityAsync(napi_env env,napi_value * args,ContinueAbilityCB * continueAbilityCB)1115 napi_value ContinueAbilityAsync(napi_env env, napi_value *args, ContinueAbilityCB *continueAbilityCB)
1116 {
1117     HILOG_INFO("%{public}s asyncCallback.", __func__);
1118     if (args == nullptr || continueAbilityCB == nullptr) {
1119         HILOG_ERROR("%{public}s, param == nullptr.", __func__);
1120         return nullptr;
1121     }
1122 
1123     napi_value result = nullptr;
1124     if (continueAbilityCB->callbackRef == nullptr) {
1125         napi_create_promise(env, &continueAbilityCB->cbBase.deferred, &result);
1126     } else {
1127         napi_get_undefined(env, &result);
1128     }
1129 
1130     napi_value resourceName = nullptr;
1131     napi_create_string_latin1(env, "ContinueAbilityAsyncForLauncher", NAPI_AUTO_LENGTH, &resourceName);
1132 
1133     napi_create_async_work(env,
1134         nullptr,
1135         resourceName,
1136         ContinueAbilityExecuteCB,
1137         ContinueAbilityCallbackCompletedCB,
1138         (void *)continueAbilityCB,
1139         &continueAbilityCB->cbBase.asyncWork);
1140     napi_queue_async_work(env, continueAbilityCB->cbBase.asyncWork);
1141     HILOG_INFO("%{public}s asyncCallback end.", __func__);
1142     return result;
1143 }
1144 
CheckContinueKeyExist(napi_env env,const napi_value & value)1145 bool CheckContinueKeyExist(napi_env env, const napi_value &value)
1146 {
1147     bool isSrcDeviceId = false;
1148     napi_has_named_property(env, value, "srcDeviceId", &isSrcDeviceId);
1149     bool isDstDeviceId = false;
1150     napi_has_named_property(env, value, "dstDeviceId", &isDstDeviceId);
1151     bool isMissionId = false;
1152     napi_has_named_property(env, value, "missionId", &isMissionId);
1153     bool isWantParam = false;
1154     napi_has_named_property(env, value, "wantParam", &isWantParam);
1155     if (!isSrcDeviceId && !isDstDeviceId && !isMissionId && !isWantParam) {
1156         HILOG_ERROR("%{public}s, Wrong argument key.", __func__);
1157         return false;
1158     }
1159     return true;
1160 }
1161 
CheckContinueFirstArgs(napi_env env,const napi_value & value,ContinueAbilityCB * continueAbilityCB)1162 bool CheckContinueFirstArgs(napi_env env, const napi_value &value, ContinueAbilityCB *continueAbilityCB)
1163 {
1164     HILOG_INFO("%{public}s called.", __func__);
1165     if (!CheckContinueKeyExist(env, value)) {
1166         HILOG_ERROR("%{public}s, Wrong argument key.", __func__);
1167         return false;
1168     }
1169     napi_value firstNApi = nullptr;
1170     napi_value secondNApi = nullptr;
1171     napi_value thirdNApi = nullptr;
1172     napi_value fourthNApi = nullptr;
1173     napi_valuetype valueType = napi_undefined;
1174     napi_typeof(env, value, &valueType);
1175     if (valueType != napi_object) {
1176         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1177         return false;
1178     }
1179     napi_get_named_property(env, value, "srcDeviceId", &firstNApi);
1180     napi_get_named_property(env, value, "dstDeviceId", &secondNApi);
1181     napi_get_named_property(env, value, "missionId", &thirdNApi);
1182     napi_get_named_property(env, value, "wantParam", &fourthNApi);
1183     if (firstNApi == nullptr || secondNApi == nullptr || thirdNApi == nullptr || fourthNApi == nullptr) {
1184         HILOG_ERROR("%{public}s, miss required parameters.", __func__);
1185         return false;
1186     }
1187     napi_typeof(env, firstNApi, &valueType);
1188     if (valueType != napi_string) {
1189         HILOG_ERROR("%{public}s, Wrong argument type srcDeviceId.", __func__);
1190         return false;
1191     }
1192     continueAbilityCB->srcDeviceId = AppExecFwk::UnwrapStringFromJS(env, firstNApi, "");
1193     napi_typeof(env, secondNApi, &valueType);
1194     if (valueType != napi_string) {
1195         HILOG_ERROR("%{public}s, Wrong argument type dstDeviceId.", __func__);
1196         return false;
1197     }
1198     continueAbilityCB->dstDeviceId = AppExecFwk::UnwrapStringFromJS(env, secondNApi, "");
1199     napi_typeof(env, thirdNApi, &valueType);
1200     if (valueType != napi_number) {
1201         HILOG_ERROR("%{public}s, Wrong argument type missionId.", __func__);
1202         return false;
1203     }
1204     continueAbilityCB->missionId = AppExecFwk::UnwrapInt32FromJS(env, thirdNApi, -1);
1205     napi_typeof(env, fourthNApi, &valueType);
1206     if (valueType != napi_object) {
1207         HILOG_ERROR("%{public}s, Wrong argument type wantParam.", __func__);
1208         return false;
1209     }
1210     AppExecFwk::UnwrapWantParams(env, fourthNApi, continueAbilityCB->wantParams);
1211     HILOG_INFO("%{public}s called end.", __func__);
1212     return true;
1213 }
1214 
CheckContinueCallback(napi_env env,const napi_value & value,ContinueAbilityCB * continueAbilityCB)1215 bool CheckContinueCallback(napi_env env, const napi_value &value, ContinueAbilityCB *continueAbilityCB)
1216 {
1217     HILOG_INFO("%{public}s called.", __func__);
1218     napi_value jsMethod = nullptr;
1219     napi_valuetype valuetype = napi_undefined;
1220     napi_typeof(env, value, &valuetype);
1221     if (valuetype != napi_object) {
1222         HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
1223         return false;
1224     }
1225     bool isFirstCallback = false;
1226     napi_has_named_property(env, value, "onContinueDone", &isFirstCallback);
1227     if (!isFirstCallback) {
1228         HILOG_ERROR("%{public}s, Wrong argument name for onContinueDone.", __func__);
1229         return false;
1230     }
1231     napi_get_named_property(env, value, "onContinueDone", &jsMethod);
1232     if (jsMethod == nullptr) {
1233         HILOG_ERROR("%{public}s, not find callback onContinueDone.", __func__);
1234         return false;
1235     }
1236     napi_typeof(env, jsMethod, &valuetype);
1237     if (valuetype != napi_function) {
1238         HILOG_ERROR("%{public}s, onContinueDone callback error type.", __func__);
1239         return false;
1240     }
1241     napi_create_reference(env, jsMethod, 1, &continueAbilityCB->abilityContinuationCB.callback[0]);
1242     HILOG_INFO("%{public}s called end.", __func__);
1243     return true;
1244 }
1245 
ContinueAbilityWrap(napi_env env,napi_callback_info info,ContinueAbilityCB * continueAbilityCB)1246 napi_value ContinueAbilityWrap(napi_env env, napi_callback_info info, ContinueAbilityCB *continueAbilityCB)
1247 {
1248     HILOG_INFO("%{public}s called.", __func__);
1249     size_t argcAsync = 3;
1250     napi_value args[ARGS_MAX_COUNT] = {nullptr};
1251     napi_value ret = nullptr;
1252 
1253     napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr);
1254     HILOG_INFO("argcAsync is %{public}zu", argcAsync);
1255     if (argcAsync != ARGS_TWO && argcAsync != ARGS_THREE) {
1256         HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
1257         return nullptr;
1258     }
1259 
1260     if (!CheckContinueFirstArgs(env, args[0], continueAbilityCB)) {
1261         HILOG_ERROR("%{public}s, check the first argument failed.", __func__);
1262         return nullptr;
1263     }
1264 
1265     if (argcAsync > 1) {
1266         if (!CheckContinueCallback(env, args[1], continueAbilityCB)) {
1267             HILOG_ERROR("%{public}s, check callback failed.", __func__);
1268             return nullptr;
1269         }
1270     }
1271 
1272     if (argcAsync == ARGS_THREE) {
1273         napi_valuetype valueType = napi_undefined;
1274         napi_typeof(env, args[ARGS_TWO], &valueType);
1275         if (valueType != napi_function) {
1276             HILOG_ERROR("%{public}s, callback error type.", __func__);
1277             return nullptr;
1278         }
1279         napi_create_reference(env, args[ARGS_TWO], 1, &continueAbilityCB->callbackRef);
1280     }
1281 
1282     ret = ContinueAbilityAsync(env, args, continueAbilityCB);
1283     HILOG_INFO("%{public}s called end.", __func__);
1284     return ret;
1285 }
1286 
NAPI_ContinueAbility(napi_env env,napi_callback_info info)1287 napi_value NAPI_ContinueAbility(napi_env env, napi_callback_info info)
1288 {
1289     HILOG_INFO("%{public}s called.", __func__);
1290     ContinueAbilityCB *continueAbilityCB = CreateContinueAbilityCBCBInfo(env);
1291     if (continueAbilityCB == nullptr) {
1292         HILOG_ERROR("%{public}s continueAbilityCB == nullptr", __func__);
1293         NAPI_ASSERT(env, false, "wrong arguments");
1294     }
1295 
1296     napi_value ret = ContinueAbilityWrap(env, info, continueAbilityCB);
1297     if (ret == nullptr) {
1298         HILOG_ERROR("%{public}s ret == nullptr", __func__);
1299         delete continueAbilityCB;
1300         continueAbilityCB = nullptr;
1301         NAPI_ASSERT(env, false, "wrong arguments");
1302     }
1303     HILOG_INFO("%{public}s end.", __func__);
1304     return ret;
1305 }
1306 
UvWorkOnContinueDone(uv_work_t * work,int status)1307 void UvWorkOnContinueDone(uv_work_t *work, int status)
1308 {
1309     HILOG_INFO("UvWorkOnCountinueDone, uv_queue_work");
1310     if (work == nullptr) {
1311         HILOG_ERROR("UvWorkOnCountinueDone, work is null");
1312         return;
1313     }
1314     ContinueAbilityCB *continueAbilityCB = static_cast<ContinueAbilityCB *>(work->data);
1315     if (continueAbilityCB == nullptr) {
1316         HILOG_ERROR("UvWorkOnCountinueDone, continueAbilityCB is null");
1317         delete work;
1318         return;
1319     }
1320     napi_value result = nullptr;
1321     HILOG_INFO("UvWorkOnCountinueDone, resultCode = %{public}d", continueAbilityCB->resultCode);
1322     result =
1323         WrapInt32(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->resultCode, "resultCode");
1324 
1325     napi_value callback = nullptr;
1326     napi_value undefined = nullptr;
1327     napi_get_undefined(continueAbilityCB->cbBase.cbInfo.env, &undefined);
1328     napi_value callResult = nullptr;
1329     napi_get_reference_value(continueAbilityCB->cbBase.cbInfo.env,
1330         continueAbilityCB->cbBase.cbInfo.callback, &callback);
1331 
1332     napi_call_function(continueAbilityCB->cbBase.cbInfo.env, undefined, callback, 1, &result, &callResult);
1333     if (continueAbilityCB->cbBase.cbInfo.callback != nullptr) {
1334         napi_delete_reference(continueAbilityCB->cbBase.cbInfo.env, continueAbilityCB->cbBase.cbInfo.callback);
1335     }
1336     delete continueAbilityCB;
1337     continueAbilityCB = nullptr;
1338     delete work;
1339     HILOG_INFO("UvWorkOnCountinueDone, uv_queue_work end");
1340 }
1341 
OnContinueDone(int32_t result)1342 void NAPIMissionContinue::OnContinueDone(int32_t result)
1343 {
1344     HILOG_INFO("%{public}s, called. result = %{public}d", __func__, result);
1345     uv_loop_s *loop = nullptr;
1346 
1347     napi_get_uv_event_loop(env_, &loop);
1348     if (loop == nullptr) {
1349         HILOG_ERROR("%{public}s, loop == nullptr.", __func__);
1350         return;
1351     }
1352 
1353     uv_work_t *work = new uv_work_t;
1354     if (work == nullptr) {
1355         HILOG_ERROR("%{public}s, work==nullptr.", __func__);
1356         return;
1357     }
1358 
1359     auto continueAbilityCB = new (std::nothrow) ContinueAbilityCB;
1360     if (continueAbilityCB == nullptr) {
1361         HILOG_ERROR("%{public}s, continueAbilityCB == nullptr.", __func__);
1362         delete work;
1363         return;
1364     }
1365     continueAbilityCB->cbBase.cbInfo.env = env_;
1366     continueAbilityCB->cbBase.cbInfo.callback = onContinueDoneRef_;
1367     continueAbilityCB->resultCode = result;
1368     work->data = (void *)continueAbilityCB;
1369 
1370     int rev = uv_queue_work(
1371         loop, work, [](uv_work_t *work) {}, UvWorkOnContinueDone);
1372     if (rev != 0) {
1373         delete continueAbilityCB;
1374         continueAbilityCB = nullptr;
1375         delete work;
1376     }
1377     HILOG_INFO("%{public}s, end.", __func__);
1378 }
1379 
SetContinueAbilityEnv(const napi_env & env)1380 void NAPIMissionContinue::SetContinueAbilityEnv(const napi_env &env)
1381 {
1382     env_ = env;
1383 }
1384 
SetContinueAbilityCBRef(const napi_ref & ref)1385 void NAPIMissionContinue::SetContinueAbilityCBRef(const napi_ref &ref)
1386 {
1387     onContinueDoneRef_ = ref;
1388 }
1389 
DistributedMissionManagerExport(napi_env env,napi_value exports)1390 napi_value DistributedMissionManagerExport(napi_env env, napi_value exports)
1391 {
1392     HILOG_INFO("%{public}s,called", __func__);
1393     napi_property_descriptor properties[] = {
1394         DECLARE_NAPI_FUNCTION("startSyncRemoteMissions", NAPI_StartSyncRemoteMissions),
1395         DECLARE_NAPI_FUNCTION("stopSyncRemoteMissions", NAPI_StopSyncRemoteMissions),
1396         DECLARE_NAPI_FUNCTION("registerMissionListener", NAPI_RegisterMissionListener),
1397         DECLARE_NAPI_FUNCTION("unRegisterMissionListener", NAPI_UnRegisterMissionListener),
1398         DECLARE_NAPI_FUNCTION("continueMission", NAPI_ContinueAbility),
1399     };
1400     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
1401     return exports;
1402 }
1403 
1404 static napi_module missionModule = {
1405     .nm_version = 1,
1406     .nm_flags = 0,
1407     .nm_filename = nullptr,
1408     .nm_register_func = DistributedMissionManagerExport,
1409     .nm_modname = "distributedMissionManager",
1410     .nm_priv = ((void*)0),
1411     .reserved = {0}
1412 };
1413 
AbilityRegister()1414 extern "C" __attribute__((constructor)) void AbilityRegister()
1415 {
1416     napi_module_register(&missionModule);
1417 }
1418 }
1419 }