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