• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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