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