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