1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "js_continuation_manager.h"
17
18 #include <memory>
19
20 #include "base/continuationmgr_log.h"
21 #include "distributed_ability_manager_client.h"
22 #include "js_runtime_utils.h"
23 #include "napi_common_util.h"
24 #include "napi_error_code.h"
25
26 namespace OHOS {
27 namespace DistributedSchedule {
28 using namespace OHOS::AbilityRuntime;
29 using namespace OHOS::AppExecFwk;
30 namespace {
31 const std::string TAG = "JsContinuationManager";
32 const std::string CODE_KEY_NAME = "code";
33 constexpr int32_t ERR_NOT_OK = -1;
34 constexpr int32_t ARG_COUNT_ONE = 1;
35 constexpr int32_t ARG_COUNT_TWO = 2;
36 constexpr int32_t ARG_COUNT_THREE = 3;
37 constexpr uint32_t MAX_JSPROCOUNT = 1000000;
38 constexpr int32_t ARG_COUNT_FOUR = 4;
39 }
40
Finalizer(napi_env env,void * data,void * hint)41 void JsContinuationManager::Finalizer(napi_env env, void* data, void* hint)
42 {
43 HILOGI("JsContinuationManager::Finalizer is called");
44 JsContinuationManager* jsContinuationManager = static_cast<JsContinuationManager*>(data);
45 if (jsContinuationManager != nullptr) {
46 delete jsContinuationManager;
47 jsContinuationManager = nullptr;
48 }
49 }
50
Register(napi_env env,napi_callback_info info)51 napi_value JsContinuationManager::Register(napi_env env, napi_callback_info info)
52 {
53 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
54 return (me != nullptr) ? me->OnRegister(env, info) : nullptr;
55 }
56
Unregister(napi_env env,napi_callback_info info)57 napi_value JsContinuationManager::Unregister(napi_env env, napi_callback_info info)
58 {
59 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
60 return (me != nullptr) ? me->OnUnregister(env, info) : nullptr;
61 }
62
RegisterDeviceSelectionCallback(napi_env env,napi_callback_info info)63 napi_value JsContinuationManager::RegisterDeviceSelectionCallback(napi_env env, napi_callback_info info)
64 {
65 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
66 return (me != nullptr) ? me->OnRegisterDeviceSelectionCallback(env, info) : nullptr;
67 }
68
UnregisterDeviceSelectionCallback(napi_env env,napi_callback_info info)69 napi_value JsContinuationManager::UnregisterDeviceSelectionCallback(napi_env env, napi_callback_info info)
70 {
71 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
72 return (me != nullptr) ? me->OnUnregisterDeviceSelectionCallback(env, info) : nullptr;
73 }
74
UpdateConnectStatus(napi_env env,napi_callback_info info)75 napi_value JsContinuationManager::UpdateConnectStatus(napi_env env, napi_callback_info info)
76 {
77 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
78 return (me != nullptr) ? me->OnUpdateConnectStatus(env, info) : nullptr;
79 }
80
StartDeviceManager(napi_env env,napi_callback_info info)81 napi_value JsContinuationManager::StartDeviceManager(napi_env env, napi_callback_info info)
82 {
83 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
84 return (me != nullptr) ? me->OnStartDeviceManager(env, info) : nullptr;
85 }
86
InitDeviceConnectStateObject(napi_env env,napi_callback_info info)87 napi_value JsContinuationManager::InitDeviceConnectStateObject(napi_env env, napi_callback_info info)
88 {
89 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
90 return (me != nullptr) ? me->OnInitDeviceConnectStateObject(env, info) : nullptr;
91 }
92
InitContinuationModeObject(napi_env env,napi_callback_info info)93 napi_value JsContinuationManager::InitContinuationModeObject(napi_env env, napi_callback_info info)
94 {
95 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
96 return (me != nullptr) ? me->OnInitContinuationModeObject(env, info) : nullptr;
97 }
98
RegisterContinuation(napi_env env,napi_callback_info info)99 napi_value JsContinuationManager::RegisterContinuation(napi_env env, napi_callback_info info)
100 {
101 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
102 return (me != nullptr) ? me->OnRegisterContinuation(env, info) : nullptr;
103 }
104
UnregisterContinuation(napi_env env,napi_callback_info info)105 napi_value JsContinuationManager::UnregisterContinuation(napi_env env, napi_callback_info info)
106 {
107 JsContinuationManager* me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
108 return (me != nullptr) ? me->OnUnregisterContinuation(env, info) : nullptr;
109 }
110
UpdateContinuationState(napi_env env,napi_callback_info info)111 napi_value JsContinuationManager::UpdateContinuationState(napi_env env, napi_callback_info info)
112 {
113 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
114 return (me != nullptr) ? me->OnUpdateContinuationState(env, info) : nullptr;
115 }
116
StartContinuationDeviceManager(napi_env env,napi_callback_info info)117 napi_value JsContinuationManager::StartContinuationDeviceManager(napi_env env, napi_callback_info info)
118 {
119 JsContinuationManager *me = CheckParamsAndGetThis<JsContinuationManager>(env, info);
120 return (me != nullptr) ? me->OnStartContinuationDeviceManager(env, info) : nullptr;
121 }
122
OnRegister(napi_env env,napi_callback_info info)123 napi_value JsContinuationManager::OnRegister(napi_env env, napi_callback_info info)
124 {
125 HILOGD("called.");
126 int32_t errCode = 0;
127 size_t unwrapArgc = 0;
128 size_t argc = ARG_COUNT_TWO;
129 napi_value argv[ARG_COUNT_TWO] = { 0 };
130 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
131 std::shared_ptr<ContinuationExtraParams> continuationExtraParams = std::make_shared<ContinuationExtraParams>();
132 napi_valuetype valuetype = napi_valuetype::napi_undefined;
133 if (argc > 0) {
134 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
135 }
136 if (valuetype == napi_valuetype::napi_object) {
137 HILOGI("register options is used.");
138 if (!UnWrapContinuationExtraParams(env, argv[0], continuationExtraParams)) {
139 HILOGE("Parse continuationExtraParams failed");
140 errCode = ERR_NOT_OK;
141 }
142 unwrapArgc++;
143 }
144 NapiAsyncTask::CompleteCallback complete =
145 [continuationExtraParams, unwrapArgc, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
146 napi_handle_scope scope = nullptr;
147 napi_open_handle_scope(env, &scope);
148 if (scope == nullptr) {
149 return;
150 }
151
152 if (errCode != 0) {
153 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
154 napi_close_handle_scope(env, scope);
155 return;
156 }
157 int32_t token = -1;
158 int32_t ret = (unwrapArgc == 0) ? DistributedAbilityManagerClient::GetInstance().Register(nullptr, token) :
159 DistributedAbilityManagerClient::GetInstance().Register(continuationExtraParams, token);
160 if (ret == ERR_OK) {
161 task.Resolve(env, CreateJsValue(env, token));
162 } else {
163 task.Reject(env, CreateJsError(env, ret, "Register failed."));
164 }
165
166 napi_close_handle_scope(env, scope);
167 };
168
169 napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
170 napi_value result = nullptr;
171 NapiAsyncTask::Schedule("JsContinuationManager::OnRegister",
172 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
173 return result;
174 }
175
GetErrorInforForRegisterContination(napi_env env,napi_callback_info info,size_t & unwrapArgc,std::shared_ptr<ContinuationExtraParams> & continuationExtraParams)176 std::string JsContinuationManager::GetErrorInforForRegisterContination(napi_env env, napi_callback_info info,
177 size_t &unwrapArgc, std::shared_ptr<ContinuationExtraParams> &continuationExtraParams)
178 {
179 size_t argc = ARG_COUNT_TWO;
180 napi_value argv[ARG_COUNT_TWO] = { 0 };
181 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
182 if (argc > ARG_COUNT_TWO) {
183 return "Parameter error. The type of \"number of parameters\" must be less than 3";
184 }
185 napi_valuetype valuetype = napi_valuetype::napi_undefined;
186 if (argc > 0) {
187 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
188 }
189 if (valuetype == napi_valuetype::napi_object) {
190 HILOGI("register options is used.");
191 continuationExtraParams = std::make_shared<ContinuationExtraParams>();
192 if (!UnWrapContinuationExtraParams(env, argv[0], continuationExtraParams)) {
193 return "Parameter error. The type of \"options\" must be ContinuationExtraParams";
194 }
195 unwrapArgc++;
196 }
197 return std::string();
198 }
199
OnRegisterContinuation(napi_env env,napi_callback_info info)200 napi_value JsContinuationManager::OnRegisterContinuation(napi_env env, napi_callback_info info)
201 {
202 HILOGD("called.");
203 size_t unwrapArgc = 0;
204 std::shared_ptr<ContinuationExtraParams> continuationExtraParams;
205 std::string errInfo = GetErrorInforForRegisterContination(env, info, unwrapArgc, continuationExtraParams);
206 if (!errInfo.empty()) {
207 HILOGE("%{public}s", errInfo.c_str());
208 napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
209 return CreateJsUndefined(env);
210 }
211 NapiAsyncTask::CompleteCallback complete =
212 [this, continuationExtraParams, unwrapArgc](napi_env env, NapiAsyncTask &task, int32_t status) {
213 napi_handle_scope scope = nullptr;
214 napi_open_handle_scope(env, &scope);
215 if (scope == nullptr) {
216 return;
217 }
218
219 int32_t token = -1;
220 int32_t errCode = (unwrapArgc == 0) ? DistributedAbilityManagerClient::GetInstance().Register(nullptr, token) :
221 DistributedAbilityManagerClient::GetInstance().Register(continuationExtraParams, token);
222 if (errCode == ERR_OK) {
223 task.Resolve(env, CreateJsValue(env, token));
224 } else {
225 errCode = ErrorCodeReturn(errCode);
226 task.Reject(env, CreateJsError(env, errCode, ErrorMessageReturn(errCode)));
227 }
228
229 napi_close_handle_scope(env, scope);
230 };
231 size_t argc = ARG_COUNT_TWO;
232 napi_value argv[ARG_COUNT_TWO] = { 0 };
233 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
234 napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
235 napi_value result = nullptr;
236 NapiAsyncTask::Schedule("JsContinuationManager::OnRegisterContinuation",
237 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
238 return result;
239 }
240
OnUnregister(napi_env env,napi_callback_info info)241 napi_value JsContinuationManager::OnUnregister(napi_env env, napi_callback_info info)
242 {
243 HILOGD("called.");
244 int32_t errCode = 0;
245 size_t argc = ARG_COUNT_TWO;
246 napi_value argv[ARG_COUNT_TWO] = { 0 };
247 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
248 if (argc == 0) {
249 HILOGE("Params not match");
250 errCode = ERR_NOT_OK;
251 }
252 int32_t token = -1;
253 if (!errCode && !ConvertFromJsValue(env, argv[0], token)) {
254 HILOGE("Parse token failed");
255 errCode = ERR_NOT_OK;
256 }
257
258 NapiAsyncTask::CompleteCallback complete =
259 [token, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
260 napi_handle_scope scope = nullptr;
261 napi_open_handle_scope(env, &scope);
262 if (scope == nullptr) {
263 return;
264 }
265
266 if (errCode != 0) {
267 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
268 napi_close_handle_scope(env, scope);
269 return;
270 }
271 int32_t ret = DistributedAbilityManagerClient::GetInstance().Unregister(token);
272 if (ret == ERR_OK) {
273 task.Resolve(env, CreateJsUndefined(env));
274 } else {
275 task.Reject(env, CreateJsError(env, ret, "Unregister failed."));
276 }
277
278 napi_close_handle_scope(env, scope);
279 };
280
281 napi_value lastParam = (argc <= ARG_COUNT_ONE) ? nullptr : argv[ARG_COUNT_ONE];
282 napi_value result = nullptr;
283 NapiAsyncTask::Schedule("JsContinuationManager::OnUnregister",
284 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
285 return result;
286 }
287
OnUnregisterContinuation(napi_env env,napi_callback_info info)288 napi_value JsContinuationManager::OnUnregisterContinuation(napi_env env, napi_callback_info info)
289 {
290 HILOGD("called.");
291 int32_t token = -1;
292 size_t argc = ARG_COUNT_TWO;
293 napi_value argv[ARG_COUNT_TWO] = { 0 };
294 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
295 std::string errInfo = [this, &env, &argc, argv, &token]() -> std::string {
296 if (argc == 0 || argc > ARG_COUNT_TWO) {
297 return "Parameter error. The type of \"number of parameters\" must be greater than 0 and less than 3";
298 }
299 if (!ConvertFromJsValue(env, argv[0], token)) {
300 return "Parameter error. The type of \"token\" must be number";
301 }
302 return std::string();
303 } ();
304 if (!errInfo.empty()) {
305 HILOGE("%{public}s", errInfo.c_str());
306 napi_throw(env, GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
307 return CreateJsUndefined(env);
308 }
309 NapiAsyncTask::CompleteCallback complete =
310 [this, token](napi_env env, NapiAsyncTask &task, int32_t status) {
311 napi_handle_scope scope = nullptr;
312 napi_open_handle_scope(env, &scope);
313 if (scope == nullptr) {
314 return;
315 }
316 int32_t errCode = DistributedAbilityManagerClient::GetInstance().Unregister(token);
317 if (errCode == ERR_OK) {
318 task.Resolve(env, CreateJsNull(env));
319 } else {
320 errCode = ErrorCodeReturn(errCode);
321 task.Reject(env, CreateJsError(env, errCode, ErrorMessageReturn(errCode)));
322 }
323
324 napi_close_handle_scope(env, scope);
325 };
326
327 napi_value lastParam = (argc == ARG_COUNT_ONE) ? nullptr : argv[ARG_COUNT_ONE];
328 napi_value result = nullptr;
329 NapiAsyncTask::Schedule("JsContinuationManager::OnUnregisterContinuation",
330 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
331 return result;
332 }
333
OnRegisterDeviceSelectionCallbackParameterCheck(napi_env env,napi_callback_info info,std::string & cbType,int32_t & token,napi_value * jsListenerObj)334 std::string JsContinuationManager::OnRegisterDeviceSelectionCallbackParameterCheck(napi_env env,
335 napi_callback_info info, std::string &cbType, int32_t &token, napi_value *jsListenerObj)
336 {
337 size_t argc = ARG_COUNT_THREE;
338 napi_value argv[ARG_COUNT_THREE] = { 0 };
339 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
340 if (argc != ARG_COUNT_THREE) {
341 return "Parameter error. The type of \"number of parameters\" must be 3";
342 }
343 if (!ConvertFromJsValue(env, argv[0], cbType)) {
344 return "Parameter error. The type of \"type\" must be string";
345 }
346 if (cbType != EVENT_CONNECT && cbType != EVENT_DISCONNECT) {
347 return "Parameter error. The type of \"type\" must be " +
348 std::string(EVENT_CONNECT) + " or " + std::string(EVENT_DISCONNECT);
349 }
350 if (!ConvertFromJsValue(env, argv[ARG_COUNT_ONE], token)) {
351 return "Parameter error. The type of \"token\" must be number";
352 }
353 *jsListenerObj = argv[ARG_COUNT_TWO];
354 if (!IsCallbackValid(env, *jsListenerObj)) {
355 return "Parameter error. The type of \"callback\" must be Callback<Array<ContinuationResult>>";
356 }
357 return std::string();
358 }
359
OnRegisterDeviceSelectionCallback(napi_env env,napi_callback_info info)360 napi_value JsContinuationManager::OnRegisterDeviceSelectionCallback(napi_env env, napi_callback_info info)
361 {
362 HILOGD("called.");
363 std::string cbType;
364 int32_t token = -1;
365 int32_t errCode = PARAMETER_CHECK_FAILED;
366 napi_value jsListenerObj = nullptr;
367 std::string errInfo = OnRegisterDeviceSelectionCallbackParameterCheck(env, info, cbType, token, &jsListenerObj);
368 if (errInfo.empty()) {
369 errInfo = [this, &env, &info, &cbType, &token, &jsListenerObj, &errCode]() -> std::string {
370 std::lock_guard<std::mutex> jsCbMapLock(jsCbMapMutex_);
371 if (IsCallbackRegistered(token, cbType)) {
372 errCode = REPEATED_REGISTRATION;
373 return ErrorMessageReturn(errCode);
374 }
375 napi_ref tempRef = nullptr;
376 napi_create_reference(env, jsListenerObj, 1, &tempRef);
377 std::unique_ptr<NativeReference> callbackRef;
378 callbackRef.reset(reinterpret_cast<NativeReference*>(tempRef));
379 sptr<JsDeviceSelectionListener> deviceSelectionListener = new JsDeviceSelectionListener(env);
380 if (deviceSelectionListener == nullptr) {
381 HILOGE("deviceSelectionListener is nullptr!");
382 errCode = SYSTEM_WORK_ABNORMALLY;
383 return ErrorMessageReturn(errCode);
384 }
385 errCode = DistributedAbilityManagerClient::GetInstance().RegisterDeviceSelectionCallback(
386 token, cbType, deviceSelectionListener);
387 if (errCode == ERR_OK) {
388 deviceSelectionListener->AddCallback(cbType, jsListenerObj);
389 CallbackPair callbackPair = std::make_pair(std::move(callbackRef), deviceSelectionListener);
390 jsCbMap_[token][cbType] = std::move(callbackPair); // move assignment
391 HILOGI("RegisterDeviceSelectionListener success");
392 } else {
393 deviceSelectionListener = nullptr;
394 errCode = ErrorCodeReturn(errCode);
395 return ErrorMessageReturn(errCode);
396 }
397 return std::string();
398 }();
399 }
400 if (!errInfo.empty()) {
401 HILOGE("%{public}s", errInfo.c_str());
402 napi_throw(env,
403 GenerateBusinessError(env, errCode, errInfo));
404 }
405 return CreateJsUndefined(env);
406 }
407
OnUnregisterDeviceSelectionCallback(napi_env env,napi_callback_info info)408 napi_value JsContinuationManager::OnUnregisterDeviceSelectionCallback(napi_env env, napi_callback_info info)
409 {
410 HILOGD("called.");
411 std::string cbType;
412 int32_t token = -1;
413 int32_t errCode = PARAMETER_CHECK_FAILED;
414 std::string errInfo = [this, &env, &info, &cbType, &token, &errCode]() -> std::string {
415 size_t argc = ARG_COUNT_TWO;
416 napi_value argv[ARG_COUNT_TWO] = { 0 };
417 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
418 if (argc != ARG_COUNT_TWO) {
419 return "Parameter error. The type of \"number of parameters\" must be 2";
420 }
421 if (!ConvertFromJsValue(env, argv[0], cbType)) {
422 return "Parameter error. The type of \"type\" must be string";
423 }
424 if (cbType != EVENT_CONNECT && cbType != EVENT_DISCONNECT) {
425 return "Parameter error. The type of \"type\" must be " +
426 std::string(EVENT_CONNECT) + " or " + std::string(EVENT_DISCONNECT);
427 }
428 if (!ConvertFromJsValue(env, argv[ARG_COUNT_ONE], token)) {
429 return "Parameter error. The type of \"token\" must be number";
430 }
431 {
432 std::lock_guard<std::mutex> jsCbMapLock(jsCbMapMutex_);
433 if (!IsCallbackRegistered(token, cbType)) {
434 errCode = CALLBACK_TOKEN_UNREGISTERED;
435 return ErrorMessageReturn(errCode);
436 }
437 errCode = DistributedAbilityManagerClient::GetInstance().UnregisterDeviceSelectionCallback(token, cbType);
438 if (errCode == ERR_OK) {
439 CallbackPair& callbackPair = jsCbMap_[token][cbType];
440 callbackPair.second->RemoveCallback(cbType);
441 jsCbMap_[token].erase(cbType);
442 if (jsCbMap_[token].empty()) {
443 jsCbMap_.erase(token);
444 }
445 HILOGI("UnregisterDeviceSelectionCallback success");
446 } else {
447 errCode = ErrorCodeReturn(errCode);
448 return ErrorMessageReturn(errCode);
449 }
450 }
451 return std::string();
452 } ();
453 if (!errInfo.empty()) {
454 HILOGE("%{public}s", errInfo.c_str());
455 napi_throw(env, GenerateBusinessError(env, errCode, errInfo));
456 }
457 return CreateJsUndefined(env);
458 }
459
GetInfoForUpdateConnectStatus(napi_env env,napi_value * argv,int32_t & token,std::string & deviceId,DeviceConnectStatus & deviceConnectStatus)460 int32_t JsContinuationManager::GetInfoForUpdateConnectStatus(napi_env env,
461 napi_value *argv, int32_t &token, std::string &deviceId, DeviceConnectStatus &deviceConnectStatus)
462 {
463 int32_t errCode = 0;
464 if (!errCode && !ConvertFromJsValue(env, argv[0], token)) {
465 HILOGE("Parse token failed");
466 errCode = ERR_NOT_OK;
467 }
468 if (!errCode && !ConvertFromJsValue(env, argv[ARG_COUNT_ONE], deviceId)) {
469 HILOGE("Parse deviceId failed");
470 errCode = ERR_NOT_OK;
471 }
472 if (!errCode && !ConvertFromJsValue(env, argv[ARG_COUNT_TWO], deviceConnectStatus)) {
473 HILOGE("Parse device connect status failed");
474 errCode = ERR_NOT_OK;
475 }
476 return errCode;
477 }
478
OnUpdateConnectStatus(napi_env env,napi_callback_info info)479 napi_value JsContinuationManager::OnUpdateConnectStatus(napi_env env, napi_callback_info info)
480 {
481 HILOGD("called.");
482 int32_t errCode = 0;
483 size_t argc = ARG_COUNT_FOUR;
484 napi_value argv[ARG_COUNT_FOUR] = { 0 };
485 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
486 if (argc < ARG_COUNT_THREE) {
487 HILOGE("Params not match");
488 errCode = ERR_NOT_OK;
489 }
490 int32_t token = -1;
491 std::string deviceId;
492 DeviceConnectStatus deviceConnectStatus = DeviceConnectStatus::IDLE;
493 errCode = GetInfoForUpdateConnectStatus(env, argv, token, deviceId, deviceConnectStatus);
494 NapiAsyncTask::CompleteCallback complete =
495 [token, deviceId, deviceConnectStatus, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
496 napi_handle_scope scope = nullptr;
497 napi_open_handle_scope(env, &scope);
498 if (scope == nullptr) {
499 return;
500 }
501
502 if (errCode != 0) {
503 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
504 napi_close_handle_scope(env, scope);
505 return;
506 }
507 int32_t ret = DistributedAbilityManagerClient::GetInstance().UpdateConnectStatus(
508 token, deviceId, deviceConnectStatus);
509 if (ret == ERR_OK) {
510 task.Resolve(env, CreateJsUndefined(env));
511 } else {
512 task.Reject(env, CreateJsError(env, ret, "UpdateConnectStatus failed."));
513 }
514 napi_close_handle_scope(env, scope);
515 };
516
517 napi_value lastParam = (argc <= ARG_COUNT_THREE) ? nullptr : argv[ARG_COUNT_THREE];
518 napi_value result = nullptr;
519 NapiAsyncTask::Schedule("JsContinuationManager::OnUpdateConnectStatus",
520 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
521 return result;
522 }
523
GetErrorInfo(napi_env env,napi_callback_info info,int32_t & token,std::string & deviceId,DeviceConnectStatus & deviceConnectStatus)524 std::string JsContinuationManager::GetErrorInfo(napi_env env, napi_callback_info info, int32_t &token,
525 std::string &deviceId, DeviceConnectStatus &deviceConnectStatus)
526 {
527 size_t argc = ARG_COUNT_FOUR;
528 napi_value argv[ARG_COUNT_FOUR] = { nullptr };
529 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
530 if (argc != ARG_COUNT_THREE && argc != ARG_COUNT_FOUR) {
531 return "Parameter error. The type of \"number of parameters\" must be 3 or 4";
532 }
533 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
534 if (!ConvertFromJsValue(env, argv[0], token)) {
535 return "Parameter error. The type of \"token\" must be number";
536 }
537 if (!ConvertFromJsValue(env, argv[ARG_COUNT_ONE], deviceId) || deviceId.empty()) {
538 return "Parameter error. The type of \"deviceId\" must be string and not empty";
539 }
540 deviceConnectStatus = DeviceConnectStatus::IDLE;
541 if (!ConvertFromJsValue(env, argv[ARG_COUNT_TWO], deviceConnectStatus)) {
542 return "Parameter error. The type of \"status\" must be DeviceConnectState";
543 }
544 if (static_cast<int32_t>(deviceConnectStatus) < static_cast<int32_t>(DeviceConnectStatus::IDLE) ||
545 static_cast<int32_t>(deviceConnectStatus) > static_cast<int32_t>(DeviceConnectStatus::DISCONNECTING)) {
546 HILOGE("deviceConnectStatus is invalid");
547 return "Parameter error. The type of \"status\" must be DeviceConnectState";
548 }
549 return std::string();
550 }
551
OnUpdateContinuationState(napi_env env,napi_callback_info info)552 napi_value JsContinuationManager::OnUpdateContinuationState(napi_env env, napi_callback_info info)
553 {
554 HILOGD("called.");
555 int32_t token = -1;
556 std::string deviceId;
557 DeviceConnectStatus deviceConnectStatus;
558 std::string errInfo = GetErrorInfo(env, info, token, deviceId, deviceConnectStatus);
559 if (!errInfo.empty()) {
560 HILOGE("%{public}s", errInfo.c_str());
561 napi_throw(env,
562 GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
563 return CreateJsUndefined(env);
564 }
565 NapiAsyncTask::CompleteCallback complete =
566 [this, token, deviceId, deviceConnectStatus](napi_env env, NapiAsyncTask &task, int32_t status) {
567 napi_handle_scope scope = nullptr;
568 napi_open_handle_scope(env, &scope);
569 if (scope == nullptr) {
570 return;
571 }
572
573 int32_t errCode = DistributedAbilityManagerClient::GetInstance().UpdateConnectStatus(
574 token, deviceId, deviceConnectStatus);
575 if (errCode == ERR_OK) {
576 task.Resolve(env, CreateJsNull(env));
577 } else {
578 errCode = ErrorCodeReturn(errCode);
579 task.Reject(env, CreateJsError(env, errCode, ErrorMessageReturn(errCode)));
580 }
581
582 napi_close_handle_scope(env, scope);
583 };
584
585 size_t argc = ARG_COUNT_FOUR;
586 napi_value argv[ARG_COUNT_FOUR] = { 0 };
587 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
588 napi_value lastParam = (argc == ARG_COUNT_THREE) ? nullptr : argv[ARG_COUNT_THREE];
589 napi_value result = nullptr;
590 NapiAsyncTask::Schedule("JsContinuationManager::OnUpdateContinuationState",
591 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
592 return result;
593 }
594
CheckParamAndGetToken(napi_env env,size_t argc,napi_value * argv,int32_t & token)595 int32_t JsContinuationManager::CheckParamAndGetToken(napi_env env, size_t argc, napi_value *argv, int32_t &token)
596 {
597 int32_t errCode = 0;
598 if (argc < ARG_COUNT_ONE) {
599 HILOGE("Params not match");
600 errCode = ERR_NOT_OK;
601 }
602 if (!errCode && !ConvertFromJsValue(env, argv[0], token)) {
603 HILOGE("Parse token failed");
604 errCode = ERR_NOT_OK;
605 }
606 return errCode;
607 }
608
OnStartDeviceManager(napi_env env,napi_callback_info info)609 napi_value JsContinuationManager::OnStartDeviceManager(napi_env env, napi_callback_info info)
610 {
611 HILOGD("called.");
612 int32_t token = -1;
613 size_t argc = ARG_COUNT_THREE;
614 napi_value argv[ARG_COUNT_THREE] = { 0 };
615 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
616 int32_t errCode = CheckParamAndGetToken(env, argc, argv, token);
617 size_t unwrapArgc = ARG_COUNT_ONE;
618 std::shared_ptr<ContinuationExtraParams> continuationExtraParams = std::make_shared<ContinuationExtraParams>();
619 napi_valuetype valuetype = napi_valuetype::napi_undefined;
620 if (argc > ARG_COUNT_ONE) {
621 NAPI_CALL(env, napi_typeof(env, argv[ARG_COUNT_ONE], &valuetype));
622 }
623 if (valuetype == napi_valuetype::napi_object) {
624 HILOGI("startDeviceManager options is used.");
625 if (!UnWrapContinuationExtraParams(env, argv[ARG_COUNT_ONE], continuationExtraParams)) {
626 HILOGE("Parse continuationExtraParams failed");
627 errCode = ERR_NOT_OK;
628 }
629 unwrapArgc++;
630 }
631 NapiAsyncTask::CompleteCallback complete =
632 [token, continuationExtraParams, unwrapArgc, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
633 napi_handle_scope scope = nullptr;
634 napi_open_handle_scope(env, &scope);
635 if (scope == nullptr) {
636 return;
637 }
638
639 if (errCode != 0) {
640 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
641 napi_close_handle_scope(env, scope);
642 return;
643 }
644 int32_t ret = (unwrapArgc == ARG_COUNT_ONE) ?
645 DistributedAbilityManagerClient::GetInstance().StartDeviceManager(token) :
646 DistributedAbilityManagerClient::GetInstance().StartDeviceManager(token, continuationExtraParams);
647 if (ret == ERR_OK) {
648 task.Resolve(env, CreateJsUndefined(env));
649 } else {
650 task.Reject(env, CreateJsError(env, ret, "StartDeviceManager failed."));
651 }
652
653 napi_close_handle_scope(env, scope);
654 };
655
656 napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
657 napi_value result = nullptr;
658 NapiAsyncTask::Schedule("JsContinuationManager::OnStartDeviceManager",
659 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
660 return result;
661 }
662
GetErrorForStartContinuation(napi_env env,napi_callback_info info,int32_t & token,int32_t & unwrapArgc,std::shared_ptr<ContinuationExtraParams> & continuationExtraParams)663 std::string JsContinuationManager::GetErrorForStartContinuation(napi_env env, napi_callback_info info,
664 int32_t &token, int32_t &unwrapArgc, std::shared_ptr<ContinuationExtraParams> &continuationExtraParams)
665 {
666 size_t argc = ARG_COUNT_THREE;
667 napi_value argv[ARG_COUNT_THREE] = { 0 };
668 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
669 if (argc < ARG_COUNT_ONE || argc > ARG_COUNT_THREE) {
670 return "Parameter error. The type of \"number of parameters\" must be greater than 1 and less than 3";
671 }
672 if (!ConvertFromJsValue(env, argv[0], token)) {
673 return "Parameter error. The type of \"token\" must be number";
674 }
675 continuationExtraParams = std::make_shared<ContinuationExtraParams>();
676 napi_valuetype valuetype = napi_valuetype::napi_undefined;
677 if (argc > ARG_COUNT_ONE) {
678 NAPI_CALL(env, napi_typeof(env, argv[ARG_COUNT_ONE], &valuetype));
679 }
680 if (valuetype == napi_valuetype::napi_object) {
681 HILOGI("StartContinuationDeviceManager options is used.");
682 if (!UnWrapContinuationExtraParams(env, argv[ARG_COUNT_ONE], continuationExtraParams)) {
683 return "Parameter error. The type of \"options\" must be ContinuationExtraParams";
684 }
685 unwrapArgc++;
686 }
687 return std::string();
688 }
689
OnStartContinuationDeviceManager(napi_env env,napi_callback_info info)690 napi_value JsContinuationManager::OnStartContinuationDeviceManager(napi_env env, napi_callback_info info)
691 {
692 HILOGD("called.");
693 int32_t token = -1;
694 int32_t argc = ARG_COUNT_ONE;
695 std::shared_ptr<ContinuationExtraParams> continuationExtraParams;
696 std::string errInfo = GetErrorForStartContinuation(env, info, token, argc, continuationExtraParams);
697 if (!errInfo.empty()) {
698 HILOGE("%{public}s", errInfo.c_str());
699 napi_throw(env,
700 GenerateBusinessError(env, PARAMETER_CHECK_FAILED, errInfo));
701 return CreateJsUndefined(env);
702 }
703 size_t unwrapArgc = argc;
704 NapiAsyncTask::CompleteCallback complete =
705 [this, token, continuationExtraParams, unwrapArgc](napi_env env, NapiAsyncTask &task, int32_t status) {
706 napi_handle_scope scope = nullptr;
707 napi_open_handle_scope(env, &scope);
708 if (scope == nullptr) {
709 return;
710 }
711 int32_t errCode = (unwrapArgc == ARG_COUNT_ONE) ?
712 DistributedAbilityManagerClient::GetInstance().StartDeviceManager(token) :
713 DistributedAbilityManagerClient::GetInstance().StartDeviceManager(token, continuationExtraParams);
714 if (errCode == ERR_OK) {
715 task.Resolve(env, CreateJsNull(env));
716 } else {
717 errCode = ErrorCodeReturn(errCode);
718 task.Reject(env, CreateJsError(env, errCode, ErrorMessageReturn(errCode)));
719 }
720 napi_close_handle_scope(env, scope);
721 };
722 size_t napiArgc = ARG_COUNT_THREE;
723 napi_value argv[ARG_COUNT_THREE] = { 0 };
724 NAPI_CALL(env, napi_get_cb_info(env, info, &napiArgc, argv, nullptr, nullptr));
725 napi_value lastParam = (napiArgc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
726 napi_value result = nullptr;
727 NapiAsyncTask::Schedule("JsContinuationManager::OnStartContinuationDeviceManager",
728 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
729 return result;
730 }
731
OnInitDeviceConnectStateObject(napi_env env,napi_callback_info info)732 napi_value JsContinuationManager::OnInitDeviceConnectStateObject(napi_env env, napi_callback_info info)
733 {
734 napi_value object;
735 NAPI_CALL(env, napi_create_object(env, &object));
736
737 NAPI_CALL(env, SetEnumItem(env, object, "IDLE",
738 static_cast<int32_t>(DeviceConnectStatus::IDLE)));
739 NAPI_CALL(env, SetEnumItem(env, object, "CONNECTING",
740 static_cast<int32_t>(DeviceConnectStatus::CONNECTING)));
741 NAPI_CALL(env, SetEnumItem(env, object, "CONNECTED",
742 static_cast<int32_t>(DeviceConnectStatus::CONNECTED)));
743 NAPI_CALL(env, SetEnumItem(env, object, "DISCONNECTING",
744 static_cast<int32_t>(DeviceConnectStatus::DISCONNECTING)));
745
746 return object;
747 }
748
OnInitContinuationModeObject(napi_env env,napi_callback_info info)749 napi_value JsContinuationManager::OnInitContinuationModeObject(napi_env env, napi_callback_info info)
750 {
751 napi_value object;
752 NAPI_CALL(env, napi_create_object(env, &object));
753
754 NAPI_CALL(env, SetEnumItem(env, object, "COLLABORATION_SINGLE",
755 static_cast<int32_t>(ContinuationMode::COLLABORATION_SINGLE)));
756 NAPI_CALL(env, SetEnumItem(env, object, "COLLABORATION_MULTIPLE",
757 static_cast<int32_t>(ContinuationMode::COLLABORATION_MUTIPLE)));
758
759 return object;
760 }
761
SetEnumItem(const napi_env & env,napi_value object,const char * name,int32_t value)762 napi_status JsContinuationManager::SetEnumItem(const napi_env &env, napi_value object, const char* name, int32_t value)
763 {
764 napi_status status;
765 napi_value itemName;
766 napi_value itemValue;
767
768 NAPI_CALL_BASE(env, status = napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &itemName), status);
769 NAPI_CALL_BASE(env, status = napi_create_int32(env, value, &itemValue), status);
770 NAPI_CALL_BASE(env, status = napi_set_property(env, object, itemName, itemValue), status);
771 NAPI_CALL_BASE(env, status = napi_set_property(env, object, itemValue, itemName), status);
772
773 return napi_ok;
774 }
775
IsCallbackValid(napi_env env,napi_value listenerObj)776 bool JsContinuationManager::IsCallbackValid(napi_env env, napi_value listenerObj)
777 {
778 if (listenerObj == nullptr) {
779 HILOGE("listenerObj is nullptr");
780 return false;
781 }
782 bool isCallable = false;
783 napi_is_callable(env, listenerObj, &isCallable);
784 return isCallable;
785 }
786
IsCallbackRegistered(int32_t token,const std::string & cbType)787 bool JsContinuationManager::IsCallbackRegistered(int32_t token, const std::string& cbType)
788 {
789 if (jsCbMap_.empty() || jsCbMap_.find(token) == jsCbMap_.end()) {
790 HILOGE("token %{public}d not registered callback!", token);
791 return false;
792 }
793 if (jsCbMap_[token].empty() || jsCbMap_[token].find(cbType) == jsCbMap_[token].end()) {
794 HILOGE("cbType %{public}s not registered callback!", cbType.c_str());
795 return false;
796 }
797 HILOGI("callback already registered, token: %{public}d, cbType %{public}s", token, cbType.c_str());
798 return true;
799 }
800
UnWrapContinuationExtraParams(const napi_env & env,const napi_value & options,std::shared_ptr<ContinuationExtraParams> & continuationExtraParams)801 bool JsContinuationManager::UnWrapContinuationExtraParams(const napi_env &env, const napi_value& options,
802 std::shared_ptr<ContinuationExtraParams>& continuationExtraParams)
803 {
804 HILOGD("called.");
805 if (!IsTypeForNapiValue(env, options, napi_object)) {
806 HILOGE("options is invalid.");
807 return false;
808 }
809 std::vector<std::string> deviceTypes;
810 if (UnwrapStringArrayByPropertyName(env, options, "deviceType", deviceTypes)) {
811 continuationExtraParams->SetDeviceType(deviceTypes);
812 }
813 std::string targetBundle("");
814 if (UnwrapStringByPropertyName(env, options, "targetBundle", targetBundle)) {
815 continuationExtraParams->SetTargetBundle(targetBundle);
816 }
817 std::string description("");
818 if (UnwrapStringByPropertyName(env, options, "description", description)) {
819 continuationExtraParams->SetDescription(description);
820 }
821 nlohmann::json filter;
822 if (!UnwrapJsonByPropertyName(env, options, "filter", filter)) {
823 return false;
824 }
825 continuationExtraParams->SetFilter(filter.dump());
826 int32_t continuationMode = 0;
827 if (UnwrapInt32ByPropertyName(env, options, "continuationMode", continuationMode)) {
828 continuationExtraParams->SetContinuationMode(static_cast<ContinuationMode>(continuationMode));
829 }
830 nlohmann::json authInfo;
831 if (UnwrapJsonByPropertyName(env, options, "authInfo", authInfo)) {
832 continuationExtraParams->SetAuthInfo(authInfo.dump());
833 }
834 return true;
835 }
836
UnwrapJsonByPropertyName(const napi_env & env,const napi_value & param,const std::string & field,nlohmann::json & jsonObj)837 bool JsContinuationManager::UnwrapJsonByPropertyName(const napi_env &env, const napi_value& param,
838 const std::string& field, nlohmann::json& jsonObj)
839 {
840 HILOGD("called.");
841 if (!IsTypeForNapiValue(env, param, napi_object)) {
842 HILOGE("param is invalid.");
843 return false;
844 }
845 napi_value jsonField = nullptr;
846 napi_get_named_property(env, param, field.c_str(), &jsonField);
847 napi_valuetype jsonFieldType = napi_undefined;
848 napi_typeof(env, jsonField, &jsonFieldType);
849 if (jsonFieldType != napi_object && jsonFieldType != napi_undefined) {
850 HILOGE("field: %{public}s is invalid json.", field.c_str());
851 return false;
852 }
853 napi_value jsProNameList = nullptr;
854 uint32_t jsProCount = 0;
855 napi_get_property_names(env, jsonField, &jsProNameList);
856 napi_get_array_length(env, jsProNameList, &jsProCount);
857 if (!PraseJson(env, jsonField, jsProNameList, jsProCount, jsonObj)) {
858 HILOGE("PraseJson failed.");
859 return false;
860 }
861 return true;
862 }
863
PraseJson(const napi_env & env,const napi_value & jsonField,const napi_value & jsProNameList,uint32_t jsProCount,nlohmann::json & jsonObj)864 bool JsContinuationManager::PraseJson(const napi_env &env, const napi_value& jsonField,
865 const napi_value& jsProNameList, uint32_t jsProCount, nlohmann::json& jsonObj)
866 {
867 napi_value jsProName = nullptr;
868 napi_value jsProValue = nullptr;
869 napi_valuetype jsValueType = napi_undefined;
870 if (jsProCount > MAX_JSPROCOUNT) {
871 HILOGE("value of jsProCount is larger than MAX_JSPROCOUNT");
872 return false;
873 }
874 for (uint32_t index = 0; index < jsProCount; index++) {
875 napi_get_element(env, jsProNameList, index, &jsProName);
876 std::string strProName = UnwrapStringFromJS(env, jsProName);
877 napi_get_named_property(env, jsonField, strProName.c_str(), &jsProValue);
878 napi_typeof(env, jsProValue, &jsValueType);
879 switch (jsValueType) {
880 case napi_string: {
881 std::string elementValue = UnwrapStringFromJS(env, jsProValue);
882 HILOGI("Property name=%{public}s, string, value=%{public}s", strProName.c_str(), elementValue.c_str());
883 jsonObj[strProName] = elementValue;
884 break;
885 }
886 case napi_boolean: {
887 bool elementValue = false;
888 napi_get_value_bool(env, jsProValue, &elementValue);
889 HILOGI("Property name=%{public}s, boolean, value=%{public}d.", strProName.c_str(), elementValue);
890 jsonObj[strProName] = elementValue;
891 break;
892 }
893 case napi_number: {
894 int32_t elementValue = 0;
895 if (napi_get_value_int32(env, jsProValue, &elementValue) != napi_ok) {
896 HILOGE("Property name=%{public}s, Property int32_t parse error", strProName.c_str());
897 } else {
898 HILOGI("Property name=%{public}s, number, value=%{public}d.", strProName.c_str(), elementValue);
899 jsonObj[strProName] = elementValue;
900 }
901 break;
902 }
903 default: {
904 HILOGE("Property name=%{public}s, value type not support.", strProName.c_str());
905 break;
906 }
907 }
908 }
909 return true;
910 }
911
ErrorCodeReturn(int32_t code)912 int32_t JsContinuationManager::ErrorCodeReturn(int32_t code)
913 {
914 switch (code) {
915 case DMS_PERMISSION_DENIED:
916 return PERMISSION_DENIED;
917 case ERR_NULL_OBJECT:
918 return SYSTEM_WORK_ABNORMALLY;
919 case ERR_FLATTEN_OBJECT:
920 return SYSTEM_WORK_ABNORMALLY;
921 case CONNECT_ABILITY_FAILED:
922 return SYSTEM_WORK_ABNORMALLY;
923 case INVALID_CONTINUATION_MODE:
924 return PARAMETER_CHECK_FAILED;
925 case UNKNOWN_CALLBACK_TYPE:
926 return PARAMETER_CHECK_FAILED;
927 case INVALID_CONNECT_STATUS:
928 return PARAMETER_CHECK_FAILED;
929 case CALLBACK_HAS_NOT_REGISTERED:
930 return CALLBACK_TOKEN_UNREGISTERED;
931 case TOKEN_HAS_NOT_REGISTERED:
932 return CALLBACK_TOKEN_UNREGISTERED;
933 case REGISTER_EXCEED_MAX_TIMES:
934 return OVER_MAX_REGISTERED_TIMES;
935 case CALLBACK_HAS_REGISTERED:
936 return REPEATED_REGISTRATION;
937 default:
938 return SYSTEM_WORK_ABNORMALLY;
939 };
940 }
941
ErrorMessageReturn(int32_t code)942 std::string JsContinuationManager::ErrorMessageReturn(int32_t code)
943 {
944 switch (code) {
945 case PARAMETER_CHECK_FAILED:
946 return "The parameter check failed.";
947 case SYSTEM_WORK_ABNORMALLY:
948 return "The system ability works abnormally.";
949 case CALLBACK_TOKEN_UNREGISTERED:
950 return "The specified token or callback is not registered.";
951 case OVER_MAX_REGISTERED_TIMES:
952 return "The number of token registration times has reached the upper limit.";
953 case REPEATED_REGISTRATION:
954 return "The specified callback has been registered.";
955 default:
956 return "The system ability works abnormally.";
957 };
958 }
959
GenerateBusinessError(const napi_env & env,int32_t errCode,const std::string & errMsg)960 napi_value JsContinuationManager::GenerateBusinessError(const napi_env &env, int32_t errCode, const std::string &errMsg)
961 {
962 napi_value code = nullptr;
963 napi_create_int32(env, errCode, &code);
964 napi_value message = nullptr;
965 napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
966 napi_value businessError = nullptr;
967 napi_create_error(env, nullptr, message, &businessError);
968 napi_set_named_property(env, businessError, CODE_KEY_NAME.c_str(), code);
969 return businessError;
970 }
971
JsContinuationManagerInit(napi_env env,napi_value exportObj)972 napi_value JsContinuationManagerInit(napi_env env, napi_value exportObj)
973 {
974 HILOGD("called.");
975 if (env == nullptr || exportObj == nullptr) {
976 HILOGE("Invalid input parameters");
977 return nullptr;
978 }
979
980 JsContinuationManager* jsContinuationManager = new JsContinuationManager();
981 napi_wrap(env, exportObj, jsContinuationManager, JsContinuationManager::Finalizer, nullptr, nullptr);
982 const char *moduleName = "JsContinuationManager";
983 BindNativeFunction(env, exportObj, "register", moduleName, JsContinuationManager::Register);
984 BindNativeFunction(env, exportObj, "unregister", moduleName, JsContinuationManager::Unregister);
985 BindNativeFunction(env, exportObj, "on", moduleName, JsContinuationManager::RegisterDeviceSelectionCallback);
986 BindNativeFunction(env, exportObj, "off", moduleName, JsContinuationManager::UnregisterDeviceSelectionCallback);
987 BindNativeFunction(env, exportObj, "updateConnectStatus", moduleName, JsContinuationManager::UpdateConnectStatus);
988 BindNativeFunction(env, exportObj, "startDeviceManager", moduleName, JsContinuationManager::StartDeviceManager);
989 BindNativeProperty(env, exportObj, "DeviceConnectState", JsContinuationManager::InitDeviceConnectStateObject);
990 BindNativeProperty(env, exportObj, "ContinuationMode", JsContinuationManager::InitContinuationModeObject);
991 BindNativeFunction(env, exportObj, "registerContinuation", moduleName,
992 JsContinuationManager::RegisterContinuation);
993 BindNativeFunction(env, exportObj, "unregisterContinuation", moduleName,
994 JsContinuationManager::UnregisterContinuation);
995 BindNativeFunction(env, exportObj, "updateContinuationState", moduleName,
996 JsContinuationManager::UpdateContinuationState);
997 BindNativeFunction(env, exportObj, "startContinuationDeviceManager", moduleName,
998 JsContinuationManager::StartContinuationDeviceManager);
999
1000 return CreateJsUndefined(env);
1001 }
1002 } // namespace DistributedSchedule
1003 } // namespace OHOS