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