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