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