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