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