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 "native_devicemanager_js.h"
17 
18 #include <securec.h>
19 #include <uv.h>
20 #include <mutex>
21 
22 #include "device_manager.h"
23 #include "dm_constants.h"
24 #include "dm_device_info.h"
25 #include "dm_log.h"
26 #include "ipc_skeleton.h"
27 #include "js_native_api.h"
28 #include "tokenid_kit.h"
29 #include "nlohmann/json.hpp"
30 
31 using namespace OHOS::DistributedHardware;
32 
33 namespace {
34 #define GET_PARAMS(env, info, num)    \
35     size_t argc = num;                \
36     napi_value argv[num] = {nullptr}; \
37     napi_value thisVar = nullptr;     \
38     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr))
39 
40 const std::string DM_NAPI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange";
41 const std::string DM_NAPI_EVENT_DEVICE_FOUND = "deviceFound";
42 const std::string DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL = "discoveryFail";
43 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS = "publishSuccess";
44 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL = "publishFail";
45 const std::string DM_NAPI_EVENT_DEVICE_SERVICE_DIE = "serviceDie";
46 const std::string DEVICE_MANAGER_NAPI_CLASS_NAME = "DeviceManager";
47 const std::string DM_NAPI_EVENT_UI_STATE_CHANGE = "uiStateChange";
48 
49 const int32_t DM_NAPI_ARGS_ZERO = 0;
50 const int32_t DM_NAPI_ARGS_ONE = 1;
51 const int32_t DM_NAPI_ARGS_TWO = 2;
52 const int32_t DM_NAPI_ARGS_THREE = 3;
53 const int32_t DM_NAPI_SUB_ID_MAX = 65535;
54 const int32_t DM_AUTH_DIRECTION_CLIENT = 1;
55 const int32_t DM_AUTH_REQUEST_SUCCESS_STATUS = 7;
56 
57 const int32_t DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP = 0;
58 const int32_t DM_NAPI_SUBSCRIBE_CAPABILITY_OSD = 1;
59 
60 napi_ref deviceTypeEnumConstructor_ = nullptr;
61 napi_ref deviceStateChangeActionEnumConstructor_ = nullptr;
62 napi_ref discoverModeEnumConstructor_ = nullptr;
63 napi_ref exchangeMediumEnumConstructor_ = nullptr;
64 napi_ref exchangeFreqEnumConstructor_ = nullptr;
65 napi_ref subscribeCapEnumConstructor_ = nullptr;
66 
67 std::map<std::string, DeviceManagerNapi *> g_deviceManagerMap;
68 std::map<std::string, std::shared_ptr<DmNapiInitCallback>> g_initCallbackMap;
69 std::map<std::string, std::shared_ptr<DmNapiDeviceStateCallback>> g_deviceStateCallbackMap;
70 std::map<std::string, std::shared_ptr<DmNapiDiscoveryCallback>> g_DiscoveryCallbackMap;
71 std::map<std::string, std::shared_ptr<DmNapiPublishCallback>> g_publishCallbackMap;
72 std::map<std::string, std::shared_ptr<DmNapiAuthenticateCallback>> g_authCallbackMap;
73 std::map<std::string, std::shared_ptr<DmNapiDeviceManagerUiCallback>> g_dmUiCallbackMap;
74 std::map<std::string, std::shared_ptr<DmNapiCredentialCallback>> g_creCallbackMap;
75 
76 std::mutex g_deviceManagerMapMutex;
77 std::mutex g_initCallbackMapMutex;
78 std::mutex g_deviceStateCallbackMapMutex;
79 std::mutex g_discoveryCallbackMapMutex;
80 std::mutex g_publishCallbackMapMutex;
81 std::mutex g_authCallbackMapMutex;
82 std::mutex g_dmUiCallbackMapMutex;
83 
84 enum DMBussinessErrorCode {
85     // Permission verify failed.
86     ERR_NO_PERMISSION = 201,
87     //The caller is not a system application.
88     ERR_NOT_SYSTEM_APP = 202,
89     // Input parameter error.
90     ERR_INVALID_PARAMS = 401,
91     // Failed to execute the function.
92     DM_ERR_FAILED = 11600101,
93     // Failed to obtain the service.
94     DM_ERR_OBTAIN_SERVICE = 11600102,
95     // Authentication invalid.
96     DM_ERR_AUTHENTICALTION_INVALID = 11600103,
97     // Discovery invalid.
98     DM_ERR_DISCOVERY_INVALID = 11600104,
99     // Publish invalid.
100     DM_ERR_PUBLISH_INVALID = 11600105,
101 };
102 
103 const std::string ERR_MESSAGE_NO_PERMISSION =
104     "Permission verification failed. The application does not have the permission required to call the API.";
105 const std::string ERR_MESSAGE_NOT_SYSTEM_APP =
106     "Permission verification failed. A non-system application calls a system API.";
107 const std::string ERR_MESSAGE_INVALID_PARAMS = "Parameter error.";
108 const std::string ERR_MESSAGE_FAILED = "Failed to execute the function.";
109 const std::string ERR_MESSAGE_OBTAIN_SERVICE = "Failed to obtain the service.";
110 const std::string ERR_MESSAGE_AUTHENTICALTION_INVALID = "Authentication unavailable.";
111 const std::string ERR_MESSAGE_DISCOVERY_INVALID = "Discovery unavailable.";
112 const std::string ERR_MESSAGE_PUBLISH_INVALID = "Publish unavailable.";
113 
GenerateBusinessError(napi_env env,int32_t err,const std::string & msg)114 napi_value GenerateBusinessError(napi_env env, int32_t err, const std::string &msg)
115 {
116     napi_value businessError = nullptr;
117     NAPI_CALL(env, napi_create_object(env, &businessError));
118     napi_value errorCode = nullptr;
119     NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
120     napi_value errorMessage = nullptr;
121     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
122     NAPI_CALL(env, napi_set_named_property(env, businessError, "code", errorCode));
123     NAPI_CALL(env, napi_set_named_property(env, businessError, "message", errorMessage));
124 
125     return businessError;
126 }
127 
CheckArgsVal(napi_env env,bool assertion,const std::string & param,const std::string & msg)128 bool CheckArgsVal(napi_env env, bool assertion, const std::string &param, const std::string &msg)
129 {
130     if (!(assertion)) {
131         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The value of " + param + ": " + msg;
132         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
133         return false;
134     }
135     return true;
136 }
137 
CheckArgsCount(napi_env env,bool assertion,const std::string & message)138 bool CheckArgsCount(napi_env env, bool assertion, const std::string &message)
139 {
140     if (!(assertion)) {
141         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + message;
142         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
143         return false;
144     }
145     return true;
146 }
147 
CheckArgsType(napi_env env,bool assertion,const std::string & paramName,const std::string & type)148 bool CheckArgsType(napi_env env, bool assertion, const std::string &paramName, const std::string &type)
149 {
150     if (!(assertion)) {
151         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The type of " + paramName +
152                 " must be " + type;
153         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
154         return false;
155     }
156     return true;
157 }
158 
CreateErrorForCall(napi_env env,int32_t code,const std::string & errMsg,bool isAsync=true)159 napi_value CreateErrorForCall(napi_env env, int32_t code, const std::string &errMsg, bool isAsync = true)
160 {
161     LOGI("CreateErrorForCall code:%{public}d, message:%{public}s", code, errMsg.c_str());
162     napi_value error = nullptr;
163     if (isAsync) {
164         napi_throw_error(env, std::to_string(code).c_str(), errMsg.c_str());
165     } else {
166         error = GenerateBusinessError(env, code, errMsg);
167     }
168     return error;
169 }
170 
CreateBusinessError(napi_env env,int32_t errCode,bool isAsync=true)171 napi_value CreateBusinessError(napi_env env, int32_t errCode, bool isAsync = true)
172 {
173     napi_value error = nullptr;
174     switch (errCode) {
175         case ERR_DM_NO_PERMISSION:
176             error = CreateErrorForCall(env, ERR_NO_PERMISSION, ERR_MESSAGE_NO_PERMISSION, isAsync);
177             break;
178         case ERR_DM_DISCOVERY_REPEATED:
179             error = CreateErrorForCall(env, DM_ERR_DISCOVERY_INVALID, ERR_MESSAGE_DISCOVERY_INVALID, isAsync);
180             break;
181         case ERR_DM_PUBLISH_REPEATED:
182             error = CreateErrorForCall(env, DM_ERR_PUBLISH_INVALID, ERR_MESSAGE_PUBLISH_INVALID, isAsync);
183             break;
184         case ERR_DM_AUTH_BUSINESS_BUSY:
185             error = CreateErrorForCall(env, DM_ERR_AUTHENTICALTION_INVALID,
186                 ERR_MESSAGE_AUTHENTICALTION_INVALID, isAsync);
187             break;
188         case ERR_DM_INPUT_PARA_INVALID:
189         case ERR_DM_UNSUPPORTED_AUTH_TYPE:
190             error = CreateErrorForCall(env, ERR_INVALID_PARAMS, ERR_MESSAGE_INVALID_PARAMS, isAsync);
191             break;
192         case ERR_DM_INIT_FAILED:
193             error = CreateErrorForCall(env, DM_ERR_OBTAIN_SERVICE, ERR_MESSAGE_OBTAIN_SERVICE, isAsync);
194             break;
195         case ERR_NOT_SYSTEM_APP:
196             error = CreateErrorForCall(env, ERR_NOT_SYSTEM_APP, ERR_MESSAGE_NOT_SYSTEM_APP, isAsync);
197             break;
198         default:
199             error = CreateErrorForCall(env, DM_ERR_FAILED, ERR_MESSAGE_FAILED, isAsync);
200             break;
201     }
202     return error;
203 }
204 
DeleteUvWork(uv_work_t * work)205 void DeleteUvWork(uv_work_t *work)
206 {
207     if (work == nullptr) {
208         return;
209     }
210     delete work;
211     work = nullptr;
212     LOGI("delete work!");
213 }
214 
DeleteDmNapiStateJsCallbackPtr(DmNapiStateJsCallback * pJsCallbackPtr)215 void DeleteDmNapiStateJsCallbackPtr(DmNapiStateJsCallback *pJsCallbackPtr)
216 {
217     if (pJsCallbackPtr == nullptr) {
218         return;
219     }
220     delete pJsCallbackPtr;
221     pJsCallbackPtr = nullptr;
222     LOGI("delete DmNapiStateJsCallback callbackPtr!");
223 }
224 
DeleteAsyncCallbackInfo(DeviceInfoListAsyncCallbackInfo * pAsynCallbackInfo)225 void DeleteAsyncCallbackInfo(DeviceInfoListAsyncCallbackInfo *pAsynCallbackInfo)
226 {
227     if (pAsynCallbackInfo == nullptr) {
228         return;
229     }
230     delete pAsynCallbackInfo;
231     pAsynCallbackInfo = nullptr;
232 }
233 
IsJSObjectType(napi_env env,napi_value value,const std::string & param)234 bool IsJSObjectType(napi_env env, napi_value value, const std::string &param)
235 {
236     napi_valuetype authparamType = napi_undefined;
237     napi_typeof(env, value, &authparamType);
238     return CheckArgsType(env, authparamType == napi_object, param, "object");
239 }
240 
IsFunctionType(napi_env env,napi_value value)241 bool IsFunctionType(napi_env env, napi_value value)
242 {
243     napi_valuetype eventHandleType = napi_undefined;
244     napi_typeof(env, value, &eventHandleType);
245     return CheckArgsType(env, eventHandleType == napi_function, "callback", "function");
246 }
247 
IsDeviceManagerNapiNull(napi_env env,napi_value thisVar,DeviceManagerNapi ** pDeviceManagerWrapper)248 bool IsDeviceManagerNapiNull(napi_env env, napi_value thisVar, DeviceManagerNapi **pDeviceManagerWrapper)
249 {
250     napi_unwrap(env, thisVar, reinterpret_cast<void **>(pDeviceManagerWrapper));
251     if (pDeviceManagerWrapper != nullptr && *pDeviceManagerWrapper != nullptr) {
252         return false;
253     }
254     CreateBusinessError(env, ERR_DM_POINT_NULL);
255     LOGE(" DeviceManagerNapi object is nullptr!");
256     return true;
257 }
258 } // namespace
259 
260 thread_local napi_ref DeviceManagerNapi::sConstructor_ = nullptr;
261 AuthAsyncCallbackInfo DeviceManagerNapi::authAsyncCallbackInfo_;
262 CredentialAsyncCallbackInfo DeviceManagerNapi::creAsyncCallbackInfo_;
263 std::mutex DeviceManagerNapi::creMapLocks_;
264 
OnRemoteDied()265 void DmNapiInitCallback::OnRemoteDied()
266 {
267     uv_loop_s *loop = nullptr;
268     napi_get_uv_event_loop(env_, &loop);
269     if (loop == nullptr) {
270         return;
271     }
272     uv_work_t *work = new (std::nothrow) uv_work_t;
273     if (work == nullptr) {
274         LOGE("DmNapiInitCallback: OnRemoteDied, No memory");
275         return;
276     }
277 
278     DmDeviceInfo info;
279     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, info);
280     if (jsCallback == nullptr) {
281         DeleteUvWork(work);
282         return;
283     }
284     work->data = reinterpret_cast<void *>(jsCallback);
285 
286     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
287         LOGD("OnRemoteDied uv_queue_work_with_qos");
288     }, [] (uv_work_t *work, int status) {
289         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
290         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
291         if (deviceManagerNapi == nullptr) {
292             LOGE("OnRemoteDied, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
293         } else {
294             deviceManagerNapi->OnEvent("serviceDie", 0, nullptr);
295         }
296         LOGI("OnRemoteDied, deviceManagerNapi bundleName %{public}s", callback->bundleName_.c_str());
297         DeleteDmNapiStateJsCallbackPtr(callback);
298         DeleteUvWork(work);
299     }, uv_qos_user_initiated);
300     if (ret != 0) {
301         LOGE("Failed to execute OnRemoteDied work queue");
302         DeleteDmNapiStateJsCallbackPtr(jsCallback);
303         DeleteUvWork(work);
304     }
305 }
306 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)307 void DmNapiDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
308 {
309     uv_loop_s *loop = nullptr;
310     napi_get_uv_event_loop(env_, &loop);
311     if (loop == nullptr) {
312         return;
313     }
314     uv_work_t *work = new (std::nothrow) uv_work_t;
315     if (work == nullptr) {
316         LOGE("DmNapiDeviceStateCallback: OnDeviceOnline, No memory");
317         return;
318     }
319 
320     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
321     if (jsCallback == nullptr) {
322         DeleteUvWork(work);
323         return;
324     }
325     work->data = reinterpret_cast<void *>(jsCallback);
326 
327     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
328         LOGD("OnDeviceOnline uv_queue_work_with_qos");
329     }, [] (uv_work_t *work, int status) {
330         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
331         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
332         if (deviceManagerNapi == nullptr) {
333             LOGE("OnDeviceOnline, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
334         } else {
335             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::ONLINE, callback->deviceInfo_);
336         }
337         DeleteDmNapiStateJsCallbackPtr(callback);
338         DeleteUvWork(work);
339     }, uv_qos_user_initiated);
340     if (ret != 0) {
341         LOGE("Failed to execute OnDeviceOnline work queue");
342         DeleteDmNapiStateJsCallbackPtr(jsCallback);
343         DeleteUvWork(work);
344     }
345 }
346 
OnDeviceReady(const DmDeviceInfo & deviceInfo)347 void DmNapiDeviceStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
348 {
349     uv_loop_s *loop = nullptr;
350     napi_get_uv_event_loop(env_, &loop);
351     if (loop == nullptr) {
352         return;
353     }
354     uv_work_t *work = new (std::nothrow) uv_work_t;
355     if (work == nullptr) {
356         LOGE("DmNapiDeviceStateCallback: OnDeviceReady, No memory");
357         return;
358     }
359 
360     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
361     if (jsCallback == nullptr) {
362         DeleteUvWork(work);
363         return;
364     }
365     work->data = reinterpret_cast<void *>(jsCallback);
366 
367     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
368         LOGD("OnDeviceReady uv_queue_work_with_qos");
369     }, [] (uv_work_t *work, int status) {
370         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
371         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
372         if (deviceManagerNapi == nullptr) {
373             LOGE("OnDeviceReady, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
374         } else {
375             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::READY, callback->deviceInfo_);
376         }
377         DeleteDmNapiStateJsCallbackPtr(callback);
378         DeleteUvWork(work);
379     }, uv_qos_user_initiated);
380     if (ret != 0) {
381         LOGE("Failed to execute OnDeviceReady work queue");
382         DeleteDmNapiStateJsCallbackPtr(jsCallback);
383         DeleteUvWork(work);
384     }
385 }
386 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)387 void DmNapiDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
388 {
389     uv_loop_s *loop = nullptr;
390     napi_get_uv_event_loop(env_, &loop);
391     if (loop == nullptr) {
392         return;
393     }
394     uv_work_t *work = new (std::nothrow) uv_work_t;
395     if (work == nullptr) {
396         LOGE("DmNapiDeviceStateCallback: OnDeviceOffline, No memory");
397         return;
398     }
399 
400     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
401     if (jsCallback == nullptr) {
402         DeleteUvWork(work);
403         return;
404     }
405     work->data = reinterpret_cast<void *>(jsCallback);
406 
407     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
408         LOGD("OnDeviceOffline uv_queue_work_with_qos");
409     }, [] (uv_work_t *work, int status) {
410         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
411         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
412         if (deviceManagerNapi == nullptr) {
413             LOGE("OnDeviceOffline, deviceManagerNapi not find for bundleName %{public}s",
414                 callback->bundleName_.c_str());
415         } else {
416             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::OFFLINE, callback->deviceInfo_);
417         }
418         DeleteDmNapiStateJsCallbackPtr(callback);
419         DeleteUvWork(work);
420     }, uv_qos_user_initiated);
421     if (ret != 0) {
422         LOGE("Failed to execute OnDeviceOffline work queue");
423         DeleteDmNapiStateJsCallbackPtr(jsCallback);
424         DeleteUvWork(work);
425     }
426 }
427 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)428 void DmNapiDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
429 {
430     uv_loop_s *loop = nullptr;
431     napi_get_uv_event_loop(env_, &loop);
432     if (loop == nullptr) {
433         return;
434     }
435     uv_work_t *work = new (std::nothrow) uv_work_t;
436     if (work == nullptr) {
437         LOGE("DmNapiDeviceStateCallback: OnDeviceChanged, No memory");
438         return;
439     }
440 
441     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
442     if (jsCallback == nullptr) {
443         DeleteUvWork(work);
444         return;
445     }
446     work->data = reinterpret_cast<void *>(jsCallback);
447 
448     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
449         LOGD("OnDeviceChanged uv_queue_work_with_qos");
450     }, [] (uv_work_t *work, int status) {
451         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
452         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
453         if (deviceManagerNapi == nullptr) {
454             LOGE("OnDeviceChanged, deviceManagerNapi not find for bundleName %{public}s",
455                 callback->bundleName_.c_str());
456         } else {
457             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::CHANGE, callback->deviceInfo_);
458         }
459         DeleteDmNapiStateJsCallbackPtr(callback);
460         DeleteUvWork(work);
461     }, uv_qos_user_initiated);
462     if (ret != 0) {
463         LOGE("Failed to execute OnDeviceChanged work queue");
464         DeleteDmNapiStateJsCallbackPtr(jsCallback);
465         DeleteUvWork(work);
466     }
467 }
468 
OnDeviceFound(uint16_t subscribeId,const DmDeviceInfo & deviceInfo)469 void DmNapiDiscoveryCallback::OnDeviceFound(uint16_t subscribeId, const DmDeviceInfo &deviceInfo)
470 {
471     LOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
472 
473     uv_loop_s *loop = nullptr;
474     napi_get_uv_event_loop(env_, &loop);
475     if (loop == nullptr) {
476         return;
477     }
478     uv_work_t *work = new (std::nothrow) uv_work_t;
479     if (work == nullptr) {
480         LOGE("DmNapiDiscoveryCallback: OnDeviceFound, No memory");
481         return;
482     }
483 
484     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, subscribeId, 0, deviceInfo);
485     if (jsCallback == nullptr) {
486         DeleteUvWork(work);
487         return;
488     }
489     work->data = reinterpret_cast<void *>(jsCallback);
490 
491     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
492         LOGD("OnDeviceFound uv_queue_work_with_qos");
493     }, [] (uv_work_t *work, int status) {
494         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
495         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
496         if (deviceManagerNapi == nullptr) {
497             LOGE("OnDeviceFound, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
498         } else {
499             deviceManagerNapi->OnDeviceFound(callback->subscribeId_, callback->deviceInfo_);
500         }
501         DeleteDmNapiStateJsCallbackPtr(callback);
502         DeleteUvWork(work);
503     }, uv_qos_user_initiated);
504     if (ret != 0) {
505         LOGE("Failed to execute OnDeviceFound work queue");
506         DeleteDmNapiStateJsCallbackPtr(jsCallback);
507         DeleteUvWork(work);
508     }
509 }
510 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)511 void DmNapiDiscoveryCallback::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
512 {
513     LOGI("OnDiscoveryFailed for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
514 
515     uv_loop_s *loop = nullptr;
516     napi_get_uv_event_loop(env_, &loop);
517     if (loop == nullptr) {
518         return;
519     }
520     uv_work_t *work = new (std::nothrow) uv_work_t;
521     if (work == nullptr) {
522         LOGE("DmNapiDiscoveryCallback: OnDiscoveryFailed, No memory");
523         return;
524     }
525 
526     DmDeviceInfo info;
527     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, subscribeId,
528         failedReason, info);
529     if (jsCallback == nullptr) {
530         DeleteUvWork(work);
531         return;
532     }
533     work->data = reinterpret_cast<void *>(jsCallback);
534 
535     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
536         LOGD("OnDiscoveryFailed uv_queue_work_with_qos");
537     }, [] (uv_work_t *work, int status) {
538         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
539         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
540         if (deviceManagerNapi == nullptr) {
541             LOGE("OnDiscoveryFailed, deviceManagerNapi not find for bundleName %{public}s",
542                 callback->bundleName_.c_str());
543         } else {
544             deviceManagerNapi->OnDiscoveryFailed(callback->subscribeId_, callback->reason_);
545         }
546         DeleteDmNapiStateJsCallbackPtr(callback);
547         DeleteUvWork(work);
548     }, uv_qos_user_initiated);
549     if (ret != 0) {
550         LOGE("Failed to execute OnDiscoveryFailed work queue");
551         DeleteDmNapiStateJsCallbackPtr(jsCallback);
552         DeleteUvWork(work);
553     }
554 }
555 
OnDiscoverySuccess(uint16_t subscribeId)556 void DmNapiDiscoveryCallback::OnDiscoverySuccess(uint16_t subscribeId)
557 {
558     DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_);
559     if (deviceManagerNapi == nullptr) {
560         LOGE("OnDiscoverySuccess, deviceManagerNapi not find for bundleName %{public}s", bundleName_.c_str());
561         return;
562     }
563     LOGI("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
564 }
565 
IncreaseRefCount()566 void DmNapiDiscoveryCallback::IncreaseRefCount()
567 {
568     refCount_++;
569 }
570 
DecreaseRefCount()571 void DmNapiDiscoveryCallback::DecreaseRefCount()
572 {
573     refCount_--;
574 }
575 
GetRefCount()576 int32_t DmNapiDiscoveryCallback::GetRefCount()
577 {
578     return refCount_;
579 }
580 
OnPublishResult(int32_t publishId,int32_t publishResult)581 void DmNapiPublishCallback::OnPublishResult(int32_t publishId, int32_t publishResult)
582 {
583     LOGI("OnPublishResult for %{public}s, publishId %{public}d, publishResult %{public}d", bundleName_.c_str(),
584         publishId, publishResult);
585     uv_loop_s *loop = nullptr;
586     napi_get_uv_event_loop(env_, &loop);
587     if (loop == nullptr) {
588         return;
589     }
590     uv_work_t *work = new (std::nothrow) uv_work_t;
591     if (work == nullptr) {
592         LOGE("DmNapiPublishCallback: OnPublishResult, No memory");
593         return;
594     }
595 
596     DmNapiPublishJsCallback *jsCallback = new DmNapiPublishJsCallback(bundleName_, publishId, publishResult);
597     if (jsCallback == nullptr) {
598         DeleteUvWork(work);
599         return;
600     }
601     work->data = reinterpret_cast<void *>(jsCallback);
602 
603     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
604         LOGD("OnPublishResult uv_queue_work_with_qos");
605     }, [] (uv_work_t *work, int status) {
606         DmNapiPublishJsCallback *callback = reinterpret_cast<DmNapiPublishJsCallback *>(work->data);
607         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
608         if (deviceManagerNapi == nullptr) {
609             LOGE("OnPublishResult, deviceManagerNapi failed for bundleName %{public}s", callback->bundleName_.c_str());
610         } else {
611             deviceManagerNapi->OnPublishResult(callback->publishId_, callback->reason_);
612         }
613         delete callback;
614         callback = nullptr;
615         DeleteUvWork(work);
616     }, uv_qos_user_initiated);
617     if (ret != 0) {
618         LOGE("Failed to execute OnPublishResult work queue");
619         delete jsCallback;
620         jsCallback = nullptr;
621         DeleteUvWork(work);
622     }
623 }
624 
IncreaseRefCount()625 void DmNapiPublishCallback::IncreaseRefCount()
626 {
627     refCount_++;
628 }
629 
DecreaseRefCount()630 void DmNapiPublishCallback::DecreaseRefCount()
631 {
632     refCount_--;
633 }
634 
GetRefCount()635 int32_t DmNapiPublishCallback::GetRefCount()
636 {
637     return refCount_;
638 }
639 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)640 void DmNapiAuthenticateCallback::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
641                                               int32_t reason)
642 {
643     uv_loop_s *loop = nullptr;
644     napi_get_uv_event_loop(env_, &loop);
645     if (loop == nullptr) {
646         return;
647     }
648     uv_work_t *work = new (std::nothrow) uv_work_t;
649     if (work == nullptr) {
650         LOGE("js DmNapiAuthenticateCallback::OnAuthResult, No memory");
651         return;
652     }
653 
654     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, deviceId, token, status, reason);
655     if (jsCallback == nullptr) {
656         DeleteUvWork(work);
657         return;
658     }
659     work->data = reinterpret_cast<void *>(jsCallback);
660 
661     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
662         LOGD("OnAuthResult uv_queue_work_with_qos");
663     }, [] (uv_work_t *work, int status) {
664         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
665         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
666         if (deviceManagerNapi == nullptr) {
667             LOGE("OnAuthResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
668         } else {
669             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
670                 callback->status_, callback->reason_);
671         }
672         delete callback;
673         callback = nullptr;
674         DeleteUvWork(work);
675     }, uv_qos_user_initiated);
676     if (ret != 0) {
677         LOGE("Failed to execute OnAuthResult work queue");
678         delete jsCallback;
679         jsCallback = nullptr;
680         DeleteUvWork(work);
681     }
682 }
683 
OnCredentialResult(int32_t & action,const std::string & credentialResult)684 void DmNapiCredentialCallback::OnCredentialResult(int32_t &action, const std::string &credentialResult)
685 {
686     uv_loop_s *loop = nullptr;
687     napi_get_uv_event_loop(env_, &loop);
688     if (loop == nullptr) {
689         return;
690     }
691     uv_work_t *work = new (std::nothrow) uv_work_t;
692     if (work == nullptr) {
693         LOGE("js DmNapiAuthenticateCallback::OnAuthResult, No memory");
694         return;
695     }
696 
697     DmNapiCredentialJsCallback *jsCallback = new DmNapiCredentialJsCallback(bundleName_, action, credentialResult);
698     if (jsCallback == nullptr) {
699         delete work;
700         work = nullptr;
701         return;
702     }
703     work->data = reinterpret_cast<void *>(jsCallback);
704 
705     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
706         LOGD("OnCredentialResult uv_queue_work_with_qos");
707     }, [] (uv_work_t *work, int status) {
708         DmNapiCredentialJsCallback *callback = reinterpret_cast<DmNapiCredentialJsCallback *>(work->data);
709         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
710         if (deviceManagerNapi == nullptr) {
711             LOGE("OnCredentialResult, deviceManagerNapi not find for bundleName %{public}s",
712                 callback->bundleName_.c_str());
713         } else {
714             deviceManagerNapi->OnCredentialResult(callback->action_, callback->credentialResult_);
715         }
716         delete callback;
717         callback = nullptr;
718         delete work;
719         work = nullptr;
720     }, uv_qos_user_initiated);
721     if (ret != 0) {
722         LOGE("Failed to execute OnCredentialResult work queue");
723         delete jsCallback;
724         jsCallback = nullptr;
725         delete work;
726         work = nullptr;
727     }
728 }
729 
DeviceManagerNapi(napi_env env,napi_value thisVar)730 DeviceManagerNapi::DeviceManagerNapi(napi_env env, napi_value thisVar) : DmNativeEvent(env, thisVar)
731 {
732     env_ = env;
733 }
734 
~DeviceManagerNapi()735 DeviceManagerNapi::~DeviceManagerNapi()
736 {
737 }
738 
GetDeviceManagerNapi(std::string & bundleName)739 DeviceManagerNapi *DeviceManagerNapi::GetDeviceManagerNapi(std::string &bundleName)
740 {
741     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
742     auto iter = g_deviceManagerMap.find(bundleName);
743     if (iter == g_deviceManagerMap.end()) {
744         return nullptr;
745     }
746     return iter->second;
747 }
748 
OnDeviceStateChange(DmNapiDevStateChangeAction action,const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)749 void DeviceManagerNapi::OnDeviceStateChange(DmNapiDevStateChangeAction action,
750                                             const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
751 {
752     napi_handle_scope scope;
753     napi_open_handle_scope(env_, &scope);
754     napi_value result = nullptr;
755     napi_create_object(env_, &result);
756     SetValueInt32(env_, "action", (int)action, result);
757 
758     napi_value device = nullptr;
759     napi_create_object(env_, &device);
760     SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device);
761     SetValueUtf8String(env_, "networkId", deviceInfo.networkId, device);
762     SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device);
763     SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device);
764     SetValueInt32(env_, "authForm", (int)deviceInfo.authForm, device);
765 
766     napi_set_named_property(env_, result, "device", device);
767     OnEvent("deviceStateChange", DM_NAPI_ARGS_ONE, &result);
768     napi_close_handle_scope(env_, scope);
769 }
770 
OnDeviceFound(uint16_t subscribeId,const DmDeviceInfo & deviceInfo)771 void DeviceManagerNapi::OnDeviceFound(uint16_t subscribeId, const DmDeviceInfo &deviceInfo)
772 {
773     LOGI("OnDeviceFound for subscribeId %{public}d, range : %{public}d", (int32_t)subscribeId, deviceInfo.range);
774     napi_handle_scope scope;
775     napi_open_handle_scope(env_, &scope);
776     napi_value result = nullptr;
777     napi_create_object(env_, &result);
778     SetValueInt32(env_, "subscribeId", (int)subscribeId, result);
779 
780     napi_value device = nullptr;
781     napi_create_object(env_, &device);
782     SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device);
783     SetValueUtf8String(env_, "networkId", deviceInfo.networkId, device);
784     SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device);
785     SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device);
786     SetValueInt32(env_, "authForm", (int)deviceInfo.authForm, device);
787     SetValueInt32(env_, "range", deviceInfo.range, device);
788 
789     napi_set_named_property(env_, result, "device", device);
790     OnEvent("deviceFound", DM_NAPI_ARGS_ONE, &result);
791     napi_close_handle_scope(env_, scope);
792 }
793 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)794 void DeviceManagerNapi::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
795 {
796     LOGI("OnDiscoveryFailed for subscribeId %{public}d", (int32_t)subscribeId);
797     napi_handle_scope scope;
798     napi_open_handle_scope(env_, &scope);
799     napi_value result = nullptr;
800     napi_create_object(env_, &result);
801     SetValueInt32(env_, "subscribeId", (int)subscribeId, result);
802     SetValueInt32(env_, "reason", (int)failedReason, result);
803     std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)failedReason);
804     SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
805     OnEvent("discoverFail", DM_NAPI_ARGS_ONE, &result);
806     napi_close_handle_scope(env_, scope);
807 }
808 
OnPublishResult(int32_t publishId,int32_t publishResult)809 void DeviceManagerNapi::OnPublishResult(int32_t publishId, int32_t publishResult)
810 {
811     LOGI("OnPublishResult for publishId %{public}d, publishResult %{public}d", publishId, publishResult);
812     napi_handle_scope scope;
813     napi_open_handle_scope(env_, &scope);
814     napi_value result = nullptr;
815     napi_create_object(env_, &result);
816     SetValueInt32(env_, "publishId", publishId, result);
817     if (publishResult == 0) {
818         OnEvent("publishSuccess", DM_NAPI_ARGS_ONE, &result);
819     } else {
820         SetValueInt32(env_, "reason", publishResult, result);
821         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString(publishResult);
822         SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
823         OnEvent("publishFail", DM_NAPI_ARGS_ONE, &result);
824     }
825     NAPI_CALL_RETURN_VOID(env_, napi_close_handle_scope(env_, scope));
826 }
827 
OnCredentialResult(int32_t & action,const std::string & credentialResult)828 void DeviceManagerNapi::OnCredentialResult(int32_t &action, const std::string &credentialResult)
829 {
830     LOGI("OnCredentialResult for action: %{public}d", action);
831     napi_handle_scope scope = nullptr;
832     napi_open_handle_scope(env_, &scope);
833     if (scope == nullptr) {
834         LOGE("scope is nullptr");
835         return;
836     }
837     napi_value result = nullptr;
838     napi_create_object(env_, &result);
839     SetValueUtf8String(env_, "resultInfo", credentialResult, result);
840 
841     napi_value callResult = nullptr;
842     napi_value handler = nullptr;
843     napi_get_reference_value(env_, creAsyncCallbackInfo_.callback, &handler);
844     if (handler != nullptr) {
845         napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_ONE, &result, &callResult);
846         napi_delete_reference(env_, creAsyncCallbackInfo_.callback);
847     } else {
848         LOGE("handler is nullptr");
849     }
850     napi_close_handle_scope(env_, scope);
851     DeviceManager::GetInstance().UnRegisterCredentialCallback(bundleName_);
852     {
853         std::lock_guard<std::mutex> autoLock(creMapLocks_);
854         g_creCallbackMap.erase(bundleName_);
855     }
856 }
857 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)858 void DeviceManagerNapi::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
859                                      int32_t reason)
860 {
861     LOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason);
862     napi_handle_scope scope;
863     napi_open_handle_scope(env_, &scope);
864     napi_value thisVar = nullptr;
865     napi_get_reference_value(env_, thisVarRef_, &thisVar);
866     napi_value result[DM_NAPI_ARGS_TWO] = {0};
867 
868     if (status == DM_AUTH_REQUEST_SUCCESS_STATUS && reason == 0) {
869         LOGI("OnAuthResult success");
870         napi_get_undefined(env_, &result[0]);
871         napi_create_object(env_, &result[1]);
872         SetValueUtf8String(env_, "deviceId", deviceId, result[1]);
873     } else {
874         LOGI("OnAuthResult failed");
875         napi_create_object(env_, &result[0]);
876         SetValueInt32(env_, "code", status, result[0]);
877         SetValueInt32(env_, "reason", reason, result[0]);
878         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)reason);
879         SetValueUtf8String(env_, "errInfo", errCodeInfo, result[0]);
880         napi_get_undefined(env_, &result[1]);
881     }
882 
883     napi_value callResult = nullptr;
884     napi_value handler = nullptr;
885     napi_get_reference_value(env_, authAsyncCallbackInfo_.callback, &handler);
886     if (handler != nullptr) {
887         if (reason == DM_OK && (status <= STATUS_DM_CLOSE_PIN_INPUT_UI && status >= STATUS_DM_SHOW_AUTHORIZE_UI)) {
888             LOGI("update ui change, status: %{public}d, reason: %{public}d", status, reason);
889         } else {
890             napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_TWO, &result[0], &callResult);
891             napi_delete_reference(env_, authAsyncCallbackInfo_.callback);
892         }
893     } else {
894         LOGE("handler is nullptr");
895     }
896     napi_close_handle_scope(env_, scope);
897     std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
898     g_authCallbackMap.erase(bundleName_);
899 }
900 
SetValueUtf8String(const napi_env & env,const std::string & fieldStr,const std::string & str,napi_value & result)901 void DeviceManagerNapi::SetValueUtf8String(const napi_env &env, const std::string &fieldStr, const std::string &str,
902                                            napi_value &result)
903 {
904     napi_value value = nullptr;
905     napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value);
906     napi_set_named_property(env, result, fieldStr.c_str(), value);
907 }
908 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int32_t intValue,napi_value & result)909 void DeviceManagerNapi::SetValueInt32(const napi_env &env, const std::string &fieldStr, const int32_t intValue,
910                                       napi_value &result)
911 {
912     napi_value value = nullptr;
913     napi_create_int32(env, intValue, &value);
914     napi_set_named_property(env, result, fieldStr.c_str(), value);
915 }
916 
DeviceInfoToJsArray(const napi_env & env,const std::vector<DmDeviceInfo> & vecDevInfo,const int32_t idx,napi_value & arrayResult)917 void DeviceManagerNapi::DeviceInfoToJsArray(const napi_env &env, const std::vector<DmDeviceInfo> &vecDevInfo,
918                                             const int32_t idx, napi_value &arrayResult)
919 {
920     napi_value result = nullptr;
921     napi_create_object(env, &result);
922 
923     SetValueUtf8String(env, "deviceId", vecDevInfo[idx].deviceId, result);
924     SetValueUtf8String(env, "networkId", vecDevInfo[idx].networkId, result);
925     SetValueUtf8String(env, "deviceName", vecDevInfo[idx].deviceName, result);
926     SetValueInt32(env, "deviceType", (int)vecDevInfo[idx].deviceTypeId, result);
927     SetValueInt32(env, "authForm", (int)vecDevInfo[idx].authForm, result);
928 
929     napi_status status = napi_set_element(env, arrayResult, idx, result);
930     if (status != napi_ok) {
931         LOGE("DmDeviceInfo To JsArray set element error: %{public}d", status);
932     }
933 }
934 
DmAuthParamDetection(const DmAuthParam & authParam)935 bool DeviceManagerNapi::DmAuthParamDetection(const DmAuthParam &authParam)
936 {
937     LOGI("DeviceManagerNapi::DmAuthParamDetection");
938     const uint32_t maxIntValueLen = 10;
939     const std::string maxAuthToken = "2147483647";
940     if (authParam.authToken.length() > maxIntValueLen) {
941         LOGE("The authToken is illegal");
942         return false;
943     } else {
944         if (!IsNumberString(authParam.authToken)) {
945             LOGE("The authToken is Error");
946             return false;
947         } else {
948             if (authParam.authToken > maxAuthToken) {
949                 LOGE("The authToken is Cross the border");
950                 return false;
951             }
952         }
953     }
954     return true;
955 }
956 
DmAuthParamToJsAuthParam(const napi_env & env,const DmAuthParam & authParam,napi_value & paramResult)957 void DeviceManagerNapi::DmAuthParamToJsAuthParam(const napi_env &env, const DmAuthParam &authParam,
958                                                  napi_value &paramResult)
959 {
960     LOGI("DeviceManagerNapi::DmAuthParamToJsAuthParam");
961     if (!DmAuthParamDetection(authParam)) {
962         LOGE("The authToken is Error");
963         return;
964     }
965     napi_value extraInfo = nullptr;
966     napi_create_object(env, &extraInfo);
967     SetValueInt32(env, "direction", authParam.direction, extraInfo);
968     SetValueInt32(env, "authType", authParam.authType, paramResult);
969     SetValueInt32(env, "pinToken", atoi(authParam.authToken.c_str()), extraInfo);
970 
971     if (authParam.direction == DM_AUTH_DIRECTION_CLIENT) {
972         napi_set_named_property(env, paramResult, "extraInfo", extraInfo);
973         return;
974     }
975 
976     SetValueUtf8String(env, "packageName", authParam.packageName, extraInfo);
977     SetValueUtf8String(env, "appName", authParam.appName, extraInfo);
978     SetValueUtf8String(env, "appDescription", authParam.appDescription, extraInfo);
979     SetValueInt32(env, "business", authParam.business, extraInfo);
980     SetValueInt32(env, "pinCode", authParam.pincode, extraInfo);
981     napi_set_named_property(env, paramResult, "extraInfo", extraInfo);
982 
983     size_t appIconLen = static_cast<size_t>(authParam.imageinfo.GetAppIconLen());
984     if (appIconLen > 0) {
985         void *appIcon = nullptr;
986         napi_value appIconBuffer = nullptr;
987         napi_create_arraybuffer(env, appIconLen, &appIcon, &appIconBuffer);
988         if (appIcon != nullptr &&
989             memcpy_s(appIcon, appIconLen, reinterpret_cast<const void *>(authParam.imageinfo.GetAppIcon()),
990                      appIconLen) == 0) {
991             napi_value appIconArray = nullptr;
992             napi_create_typedarray(env, napi_uint8_array, appIconLen, appIconBuffer, 0, &appIconArray);
993             napi_set_named_property(env, paramResult, "appIcon", appIconArray);
994         }
995     }
996 
997     size_t appThumbnailLen = static_cast<size_t>(authParam.imageinfo.GetAppThumbnailLen());
998     if (appThumbnailLen > 0) {
999         void *appThumbnail = nullptr;
1000         napi_value appThumbnailBuffer = nullptr;
1001         napi_create_arraybuffer(env, appThumbnailLen, &appThumbnail, &appThumbnailBuffer);
1002         if (appThumbnail != nullptr &&
1003             memcpy_s(appThumbnail, appThumbnailLen,
1004                      reinterpret_cast<const void *>(authParam.imageinfo.GetAppThumbnail()), appThumbnailLen) == 0) {
1005             napi_value appThumbnailArray = nullptr;
1006             napi_create_typedarray(env, napi_uint8_array, appThumbnailLen, appThumbnailBuffer, 0, &appThumbnailArray);
1007             napi_set_named_property(env, paramResult, "appThumbnail", appThumbnailArray);
1008         }
1009     }
1010     return;
1011 }
1012 
JsObjectToString(const napi_env & env,const napi_value & object,const std::string & fieldStr,char * dest,const int32_t destLen)1013 void DeviceManagerNapi::JsObjectToString(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1014                                          char *dest, const int32_t destLen)
1015 {
1016     bool hasProperty = false;
1017     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1018     if (hasProperty) {
1019         napi_value field = nullptr;
1020         napi_valuetype valueType = napi_undefined;
1021 
1022         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1023         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1024         if (!CheckArgsType(env, valueType == napi_string, fieldStr.c_str(), "string")) {
1025             return;
1026         }
1027         size_t result = 0;
1028         NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, field, dest, destLen, &result));
1029     } else {
1030         LOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str());
1031     }
1032 }
1033 
JsObjectToString(const napi_env & env,const napi_value & param)1034 std::string DeviceManagerNapi::JsObjectToString(const napi_env &env, const napi_value &param)
1035 {
1036     LOGI("JsObjectToString in.");
1037     size_t size = 0;
1038     if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
1039         return "";
1040     }
1041     if (size == 0) {
1042         return "";
1043     }
1044     char *buf = new (std::nothrow) char[size + 1];
1045     if (buf == nullptr) {
1046         return "";
1047     }
1048     int32_t ret = memset_s(buf, (size + 1), 0, (size + 1));
1049     if (ret != 0) {
1050         LOGE("devicemanager memset_s error.");
1051         delete[] buf;
1052         buf = nullptr;
1053         return "";
1054     }
1055     bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
1056 
1057     std::string value;
1058     if (rev) {
1059         value = buf;
1060     } else {
1061         value = "";
1062     }
1063     delete[] buf;
1064     buf = nullptr;
1065     return value;
1066 }
1067 
JsObjectToInt(const napi_env & env,const napi_value & object,const std::string & fieldStr,int32_t & fieldRef)1068 void DeviceManagerNapi::JsObjectToInt(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1069                                       int32_t &fieldRef)
1070 {
1071     bool hasProperty = false;
1072     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1073     if (hasProperty) {
1074         napi_value field = nullptr;
1075         napi_valuetype valueType = napi_undefined;
1076 
1077         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1078         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1079         if (!CheckArgsType(env, valueType == napi_number, fieldStr.c_str(), "number")) {
1080             return;
1081         }
1082         napi_get_value_int32(env, field, &fieldRef);
1083     } else {
1084         LOGE("devicemanager napi js to int no property: %{public}s", fieldStr.c_str());
1085     }
1086 }
1087 
JsObjectToBool(const napi_env & env,const napi_value & object,const std::string & fieldStr,bool & fieldRef)1088 void DeviceManagerNapi::JsObjectToBool(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1089                                        bool &fieldRef)
1090 {
1091     bool hasProperty = false;
1092     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1093     if (hasProperty) {
1094         napi_value field = nullptr;
1095         napi_valuetype valueType = napi_undefined;
1096 
1097         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1098         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1099         if (!CheckArgsType(env, valueType == napi_boolean, fieldStr.c_str(), "bool")) {
1100             return;
1101         }
1102         napi_get_value_bool(env, field, &fieldRef);
1103     } else {
1104         LOGE("devicemanager napi js to bool no property: %{public}s", fieldStr.c_str());
1105     }
1106 }
1107 
JsToDmPublishInfo(const napi_env & env,const napi_value & object,DmPublishInfo & info)1108 void DeviceManagerNapi::JsToDmPublishInfo(const napi_env &env, const napi_value &object, DmPublishInfo &info)
1109 {
1110     int32_t publishId = -1;
1111     JsObjectToInt(env, object, "publishId", publishId);
1112     info.publishId = publishId;
1113 
1114     int32_t mode = -1;
1115     JsObjectToInt(env, object, "mode", mode);
1116     info.mode = static_cast<DmDiscoverMode>(mode);
1117 
1118     int32_t freq = -1;
1119     JsObjectToInt(env, object, "freq", freq);
1120     info.freq = static_cast<DmExchangeFreq>(freq);
1121 
1122     JsObjectToBool(env, object, "ranging", info.ranging);
1123     return;
1124 }
1125 
JsToDmSubscribeInfo(const napi_env & env,const napi_value & object,DmSubscribeInfo & info)1126 int32_t DeviceManagerNapi::JsToDmSubscribeInfo(const napi_env &env, const napi_value &object, DmSubscribeInfo &info)
1127 {
1128     int32_t subscribeId = -1;
1129     JsObjectToInt(env, object, "subscribeId", subscribeId);
1130     if (subscribeId < 0 || subscribeId > DM_NAPI_SUB_ID_MAX) {
1131         LOGE("DeviceManagerNapi::JsToDmSubscribeInfo, subscribeId error, subscribeId: %{public}d ", subscribeId);
1132         return -1;
1133     }
1134 
1135     info.subscribeId = static_cast<uint16_t>(subscribeId);
1136 
1137     int32_t mode = -1;
1138     JsObjectToInt(env, object, "mode", mode);
1139     info.mode = static_cast<DmDiscoverMode>(mode);
1140 
1141     int32_t medium = -1;
1142     JsObjectToInt(env, object, "medium", medium);
1143     info.medium = static_cast<DmExchangeMedium>(medium);
1144 
1145     int32_t freq = -1;
1146     JsObjectToInt(env, object, "freq", freq);
1147     info.freq = static_cast<DmExchangeFreq>(freq);
1148 
1149     JsObjectToBool(env, object, "isSameAccount", info.isSameAccount);
1150     JsObjectToBool(env, object, "isWakeRemote", info.isWakeRemote);
1151 
1152     int32_t capability = -1;
1153     JsObjectToInt(env, object, "capability", capability);
1154     if (capability == DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP || capability == DM_NAPI_SUBSCRIBE_CAPABILITY_OSD) {
1155         (void)strncpy_s(info.capability, sizeof(info.capability), DM_CAPABILITY_OSD, strlen(DM_CAPABILITY_OSD));
1156     }
1157     return 0;
1158 }
1159 
JsToDmDeviceInfo(const napi_env & env,const napi_value & object,DmDeviceInfo & info)1160 void DeviceManagerNapi::JsToDmDeviceInfo(const napi_env &env, const napi_value &object, DmDeviceInfo &info)
1161 {
1162     JsObjectToString(env, object, "deviceId", info.deviceId, sizeof(info.deviceId));
1163     JsObjectToString(env, object, "deviceName", info.deviceName, sizeof(info.deviceName));
1164     JsObjectToString(env, object, "networkId", info.networkId, sizeof(info.networkId));
1165     int32_t deviceType = -1;
1166     JsObjectToInt(env, object, "deviceType", deviceType);
1167     info.deviceTypeId = static_cast<DmDeviceType>(deviceType);
1168     JsObjectToInt(env, object, "range", info.range);
1169 }
1170 
JsToDmExtra(const napi_env & env,const napi_value & object,std::string & extra,int32_t & authType)1171 void DeviceManagerNapi::JsToDmExtra(const napi_env &env, const napi_value &object, std::string &extra,
1172                                     int32_t &authType)
1173 {
1174     LOGI("JsToDmExtra in.");
1175     int32_t authTypeTemp = -1;
1176     JsObjectToInt(env, object, "authType", authTypeTemp);
1177     authType = authTypeTemp;
1178 
1179     char appOperation[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
1180     JsObjectToString(env, object, "appOperation", appOperation, sizeof(appOperation));
1181     std::string appOperationStr = appOperation;
1182 
1183     char customDescription[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
1184     JsObjectToString(env, object, "customDescription", customDescription, sizeof(customDescription));
1185     std::string customDescriptionStr = customDescription;
1186 
1187     int32_t bindLevel = 0;
1188     JsObjectToInt(env, object, "bindLevel", bindLevel);
1189 
1190     nlohmann::json jsonObj;
1191     jsonObj[AUTH_TYPE] = authType;
1192     jsonObj[APP_OPERATION] = appOperationStr;
1193     jsonObj[CUSTOM_DESCRIPTION] = customDescriptionStr;
1194     jsonObj[BIND_LEVEL] = bindLevel;
1195     jsonObj[TOKENID] = OHOS::IPCSkeleton::GetSelfTokenID();
1196     JsToJsonObject(env, object, "extraInfo", jsonObj);
1197     extra = jsonObj.dump();
1198     LOGI("appOperationLen %{public}zu, customDescriptionLen %{public}zu", appOperationStr.size(),
1199         customDescriptionStr.size());
1200 }
1201 
JsToJsonObject(const napi_env & env,const napi_value & object,const std::string & fieldStr,nlohmann::json & jsonObj)1202 void DeviceManagerNapi::JsToJsonObject(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1203                                        nlohmann::json &jsonObj)
1204 {
1205     bool hasProperty = false;
1206     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1207     if (!hasProperty) {
1208         LOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str());
1209         return;
1210     }
1211 
1212     napi_value jsonField = nullptr;
1213     napi_get_named_property(env, object, fieldStr.c_str(), &jsonField);
1214     napi_valuetype jsValueType = napi_undefined;
1215     napi_value jsProNameList = nullptr;
1216     uint32_t jsProCount = 0;
1217     napi_get_property_names(env, jsonField, &jsProNameList);
1218     napi_get_array_length(env, jsProNameList, &jsProCount);
1219 
1220     napi_value jsProName = nullptr;
1221     napi_value jsProValue = nullptr;
1222     for (uint32_t index = 0; index < jsProCount; index++) {
1223         napi_get_element(env, jsProNameList, index, &jsProName);
1224         std::string strProName = JsObjectToString(env, jsProName);
1225         napi_get_named_property(env, jsonField, strProName.c_str(), &jsProValue);
1226         napi_typeof(env, jsProValue, &jsValueType);
1227         int32_t numberValue = 0;
1228         bool boolValue = false;
1229         std::string stringValue = "";
1230         switch (jsValueType) {
1231             case napi_string:
1232                 stringValue = JsObjectToString(env, jsProValue);
1233                 LOGI("Property name = %{public}s, string, value = %{public}s", strProName.c_str(), stringValue.c_str());
1234                 jsonObj[strProName] = stringValue;
1235                 break;
1236             case napi_boolean:
1237                 napi_get_value_bool(env, jsProValue, &boolValue);
1238                 LOGI("Property name = %{public}s, boolean, value = %{public}d.", strProName.c_str(), boolValue);
1239                 jsonObj[strProName] = boolValue;
1240                 break;
1241             case napi_number:
1242                 if (napi_get_value_int32(env, jsProValue, &numberValue) != napi_ok) {
1243                     LOGE("Property name = %{public}s, Property int32_t parse error", strProName.c_str());
1244                 } else {
1245                     jsonObj[strProName] = numberValue;
1246                     LOGI("Property name = %{public}s, number, value = %{public}d.", strProName.c_str(), numberValue);
1247                 }
1248                 break;
1249             default:
1250                 LOGE("Property name = %{public}s, value type not support.", strProName.c_str());
1251                 break;
1252         }
1253     }
1254 }
1255 
JsToDmAuthInfo(const napi_env & env,const napi_value & object,std::string & extra)1256 void DeviceManagerNapi::JsToDmAuthInfo(const napi_env &env, const napi_value &object, std::string &extra)
1257 {
1258     LOGI("%{public}s called.", __func__);
1259     int32_t authType = -1;
1260     int32_t token = -1;
1261 
1262     JsObjectToInt(env, object, "authType", authType);
1263     JsObjectToInt(env, object, "token", token);
1264     nlohmann::json jsonObj;
1265     jsonObj[AUTH_TYPE] = authType;
1266     jsonObj[PIN_TOKEN] = token;
1267     JsToJsonObject(env, object, "extraInfo", jsonObj);
1268     extra = jsonObj.dump();
1269 }
1270 
JsToDmDiscoveryExtra(const napi_env & env,const napi_value & object,std::string & extra)1271 void DeviceManagerNapi::JsToDmDiscoveryExtra(const napi_env &env, const napi_value &object, std::string &extra)
1272 {
1273     napi_valuetype valueType1 = napi_undefined;
1274     napi_typeof(env, object, &valueType1);
1275     if (valueType1 == napi_undefined) {
1276         extra = "";
1277         return;
1278     }
1279     char filterOption[DM_NAPI_BUF_LENGTH] = {0};
1280     size_t typeLen = 0;
1281     NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, object, nullptr, 0, &typeLen));
1282     if (!CheckArgsVal(env, typeLen > 0, "extra", "typeLen == 0")) {
1283         return;
1284     }
1285 
1286     if (!CheckArgsVal(env, typeLen < DM_NAPI_BUF_LENGTH, "extra", "typeLen >= BUF_MAX_LENGTH")) {
1287         return;
1288     }
1289     NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, object, filterOption, typeLen + 1, &typeLen));
1290     extra = filterOption;
1291     LOGI("JsToDmDiscoveryExtra, extra :%{public}s, typeLen : %{public}zu", extra.c_str(), typeLen);
1292 }
1293 
IsSystemApp()1294 bool DeviceManagerNapi::IsSystemApp()
1295 {
1296     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1297     return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1298 }
1299 
DmDeviceInfotoJsDeviceInfo(const napi_env & env,const DmDeviceInfo & vecDevInfo,napi_value & result)1300 void DeviceManagerNapi::DmDeviceInfotoJsDeviceInfo(const napi_env &env, const DmDeviceInfo &vecDevInfo,
1301                                                    napi_value &result)
1302 {
1303     napi_create_object(env, &result);
1304 
1305     SetValueUtf8String(env, "deviceId", vecDevInfo.deviceId, result);
1306     SetValueUtf8String(env, "networkId", vecDevInfo.networkId, result);
1307     SetValueUtf8String(env, "deviceName", vecDevInfo.deviceName, result);
1308     SetValueInt32(env, "deviceType", (int)vecDevInfo.deviceTypeId, result);
1309 }
1310 
RegisterDevStateCallback(napi_env env,std::string & bundleName)1311 void DeviceManagerNapi::RegisterDevStateCallback(napi_env env, std::string &bundleName)
1312 {
1313     LOGI("RegisterDevStateCallback start bundleName %{public}s", bundleName.c_str());
1314     auto callback = std::make_shared<DmNapiDeviceStateCallback>(env, bundleName);
1315     std::string extra = "";
1316     int32_t ret = DeviceManager::GetInstance().RegisterDevStateCallback(bundleName, extra, callback);
1317     if (ret != 0) {
1318         LOGE("RegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1319         return;
1320     }
1321     {
1322         std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1323         g_deviceStateCallbackMap[bundleName] = callback;
1324     }
1325     return;
1326 }
1327 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType)1328 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType)
1329 {
1330     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s", bundleName.c_str(), eventType.c_str());
1331     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1332         RegisterDevStateCallback(env, bundleName);
1333         return;
1334     }
1335 
1336     if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL) {
1337         auto callback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
1338         {
1339             std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1340             g_DiscoveryCallbackMap[bundleName] = callback;
1341         }
1342         std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = callback;
1343         discoveryCallback->IncreaseRefCount();
1344         return;
1345     }
1346 
1347     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
1348         auto callback = std::make_shared<DmNapiPublishCallback>(env, bundleName);
1349         {
1350             std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1351             g_publishCallbackMap[bundleName] = callback;
1352         }
1353         std::shared_ptr<DmNapiPublishCallback> publishCallback = callback;
1354         publishCallback->IncreaseRefCount();
1355         return;
1356     }
1357 
1358     if (eventType == DM_NAPI_EVENT_UI_STATE_CHANGE) {
1359         auto callback = std::make_shared<DmNapiDeviceManagerUiCallback>(env, bundleName);
1360         int32_t ret = DeviceManager::GetInstance().RegisterDeviceManagerFaCallback(bundleName, callback);
1361         if (ret != 0) {
1362             LOGE("RegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
1363             return;
1364         }
1365         {
1366             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1367             g_dmUiCallbackMap[bundleName] = callback;
1368         }
1369     }
1370 }
1371 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType,std::string & extra)1372 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName,
1373                                          std::string &eventType, std::string &extra)
1374 {
1375     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s extra = %{public}s",
1376          bundleName.c_str(), eventType.c_str(), extra.c_str());
1377     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1378         auto callback = std::make_shared<DmNapiDeviceStateCallback>(env, bundleName);
1379         int32_t ret = DeviceManager::GetInstance().RegisterDevStateCallback(bundleName, extra, callback);
1380         if (ret != 0) {
1381             LOGE("RegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1382             return;
1383         }
1384         {
1385             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1386             g_deviceStateCallbackMap[bundleName] = callback;
1387         }
1388     }
1389 }
1390 
ReleasePublishCallback(std::string & bundleName)1391 void DeviceManagerNapi::ReleasePublishCallback(std::string &bundleName)
1392 {
1393     LOGI("ReleasePublishCallback for bundleName %{public}s", bundleName.c_str());
1394     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
1395     {
1396         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1397         auto iter = g_publishCallbackMap.find(bundleName);
1398         if (iter == g_publishCallbackMap.end()) {
1399             return;
1400         }
1401         publishCallback = iter->second;
1402     }
1403     publishCallback->DecreaseRefCount();
1404     if (publishCallback->GetRefCount() == 0) {
1405         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1406         g_publishCallbackMap.erase(bundleName);
1407     }
1408     return;
1409 }
1410 
ReleaseDiscoveryCallback(std::string & bundleName)1411 void DeviceManagerNapi::ReleaseDiscoveryCallback(std::string &bundleName)
1412 {
1413     LOGI("ReleaseDiscoveryCallback for bundleName %{public}s", bundleName.c_str());
1414     std::shared_ptr<DmNapiDiscoveryCallback> DiscoveryCallback = nullptr;
1415     {
1416         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1417         auto iter = g_DiscoveryCallbackMap.find(bundleName);
1418         if (iter == g_DiscoveryCallbackMap.end()) {
1419             return;
1420         }
1421         DiscoveryCallback = iter->second;
1422     }
1423     DiscoveryCallback->DecreaseRefCount();
1424     if (DiscoveryCallback->GetRefCount() == 0) {
1425         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1426         g_DiscoveryCallbackMap.erase(bundleName);
1427     }
1428     return;
1429 }
1430 
ReleaseDmCallback(std::string & bundleName,std::string & eventType)1431 void DeviceManagerNapi::ReleaseDmCallback(std::string &bundleName, std::string &eventType)
1432 {
1433     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1434         {
1435             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1436             auto iter = g_deviceStateCallbackMap.find(bundleName);
1437             if (iter == g_deviceStateCallbackMap.end()) {
1438                 LOGE("ReleaseDmCallback: cannot find stateCallback for bundleName %{public}s", bundleName.c_str());
1439                 return;
1440             }
1441         }
1442         int32_t ret = DeviceManager::GetInstance().UnRegisterDevStateCallback(bundleName);
1443         if (ret != 0) {
1444             LOGE("UnRegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1445             return;
1446         }
1447         {
1448             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1449             g_deviceStateCallbackMap.erase(bundleName);
1450         }
1451         return;
1452     }
1453 
1454     if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL) {
1455         ReleaseDiscoveryCallback(bundleName);
1456         return;
1457     }
1458 
1459     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
1460         ReleasePublishCallback(bundleName);
1461         return;
1462     }
1463 
1464     if (eventType == DM_NAPI_EVENT_UI_STATE_CHANGE) {
1465         {
1466             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1467             auto iter = g_dmUiCallbackMap.find(bundleName);
1468             if (iter == g_dmUiCallbackMap.end()) {
1469                 LOGE("cannot find dmFaCallback for bundleName %{public}s", bundleName.c_str());
1470                 return;
1471             }
1472         }
1473         int32_t ret = DeviceManager::GetInstance().UnRegisterDeviceManagerFaCallback(bundleName);
1474         if (ret != 0) {
1475             LOGE("UnRegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
1476             return;
1477         }
1478         std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1479         g_dmUiCallbackMap.erase(bundleName);
1480         return;
1481     }
1482 }
1483 
SetUserOperationSync(napi_env env,napi_callback_info info)1484 napi_value DeviceManagerNapi::SetUserOperationSync(napi_env env, napi_callback_info info)
1485 {
1486     LOGI("SetUserOperationSync in");
1487     if (!IsSystemApp()) {
1488         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1489         return nullptr;
1490     }
1491     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1492     napi_valuetype valueType;
1493     napi_typeof(env, argv[0], &valueType);
1494     if (!CheckArgsType(env, valueType == napi_number, "action", "number")) {
1495         return nullptr;
1496     }
1497 
1498     napi_valuetype strType;
1499     napi_typeof(env, argv[1], &strType);
1500     NAPI_ASSERT(env, strType == napi_string, "Wrong argument type, string expected.");
1501 
1502     int32_t action = 0;
1503     napi_get_value_int32(env, argv[0], &action);
1504 
1505     size_t typeLen = 0;
1506     napi_get_value_string_utf8(env, argv[1], nullptr, 0, &typeLen);
1507     NAPI_ASSERT(env, typeLen > 0, "typeLen == 0");
1508     NAPI_ASSERT(env, typeLen < DM_NAPI_BUF_LENGTH, "typeLen >= MAXLEN");
1509     char type[DM_NAPI_BUF_LENGTH] = {0};
1510     napi_get_value_string_utf8(env, argv[1], type, typeLen + 1, &typeLen);
1511 
1512     std::string params = type;
1513     napi_value result = nullptr;
1514     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1515     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1516         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1517         return result;
1518     }
1519     int32_t ret = DeviceManager::GetInstance().SetUserOperation(deviceManagerWrapper->bundleName_, action, params);
1520     if (ret != 0) {
1521         LOGE("SetUserOperation for bundleName %{public}s failed, ret %{public}d",
1522             deviceManagerWrapper->bundleName_.c_str(), ret);
1523         CreateBusinessError(env, ret);
1524     }
1525     napi_get_undefined(env, &result);
1526     return result;
1527 }
1528 
CallGetTrustedDeviceListStatusSync(napi_env env,napi_status & status,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1529 void DeviceManagerNapi::CallGetTrustedDeviceListStatusSync(napi_env env, napi_status &status,
1530     DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1531 {
1532     for (unsigned int i = 0; i < deviceInfoListAsyncCallbackInfo->devList.size(); i++) {
1533         LOGI("DeviceManager::GetTrustedDeviceList deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1534              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1535              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1536              deviceInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1537     }
1538 
1539     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1540     if (deviceInfoListAsyncCallbackInfo->status == 0) {
1541         bool isArray = false;
1542         napi_create_array(env, &array[1]);
1543         napi_is_array(env, array[1], &isArray);
1544         if (!isArray) {
1545             LOGE("napi_create_array fail");
1546         }
1547         if (deviceInfoListAsyncCallbackInfo->devList.size() > 0) {
1548             for (unsigned int i = 0; i != deviceInfoListAsyncCallbackInfo->devList.size(); ++i) {
1549                 DeviceInfoToJsArray(env, deviceInfoListAsyncCallbackInfo->devList, (int32_t)i, array[1]);
1550             }
1551             LOGI("devList is OK");
1552         } else {
1553             LOGE("devList is null");
1554         }
1555         napi_resolve_deferred(env, deviceInfoListAsyncCallbackInfo->deferred, array[1]);
1556     } else {
1557         array[0] = CreateBusinessError(env, deviceInfoListAsyncCallbackInfo->ret, false);
1558         napi_reject_deferred(env, deviceInfoListAsyncCallbackInfo->deferred, array[0]);
1559     }
1560 }
1561 
OnCall(const std::string & paramJson)1562 void DmNapiDeviceManagerUiCallback::OnCall(const std::string &paramJson)
1563 {
1564     uv_loop_s *loop = nullptr;
1565     napi_get_uv_event_loop(env_, &loop);
1566     if (loop == nullptr) {
1567         return;
1568     }
1569     uv_work_t *work = new (std::nothrow) uv_work_t;
1570     if (work == nullptr) {
1571         LOGE("DmNapiDeviceManagerUiCallback: OnCall, No memory");
1572         return;
1573     }
1574 
1575     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, "", paramJson, 0, 0);
1576     if (jsCallback == nullptr) {
1577         DeleteUvWork(work);
1578         return;
1579     }
1580     work->data = reinterpret_cast<void *>(jsCallback);
1581 
1582     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
1583         LOGD("OnCall uv_queue_work_with_qos");
1584     }, [] (uv_work_t *work, int status) {
1585         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
1586         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
1587         if (deviceManagerNapi == nullptr) {
1588             LOGE("OnCall, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
1589         } else {
1590             deviceManagerNapi->OnDmUiCall(callback->token_);
1591         }
1592         delete callback;
1593         callback = nullptr;
1594         DeleteUvWork(work);
1595     }, uv_qos_user_initiated);
1596     if (ret != 0) {
1597         LOGE("Failed to execute OnCall work queue");
1598         delete jsCallback;
1599         jsCallback = nullptr;
1600         DeleteUvWork(work);
1601     }
1602 }
1603 
OnDmUiCall(const std::string & paramJson)1604 void DeviceManagerNapi::OnDmUiCall(const std::string &paramJson)
1605 {
1606     LOGI("OnCall for paramJson");
1607     napi_handle_scope scope;
1608     napi_open_handle_scope(env_, &scope);
1609     napi_value result;
1610     napi_create_object(env_, &result);
1611     SetValueUtf8String(env_, "param", paramJson, result);
1612     OnEvent(DM_NAPI_EVENT_UI_STATE_CHANGE, DM_NAPI_ARGS_ONE, &result);
1613     napi_close_handle_scope(env_, scope);
1614 }
1615 
CallGetTrustedDeviceListStatus(napi_env env,napi_status & status,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1616 void DeviceManagerNapi::CallGetTrustedDeviceListStatus(napi_env env, napi_status &status,
1617                                                        DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1618 {
1619     for (unsigned int i = 0; i < deviceInfoListAsyncCallbackInfo->devList.size(); i++) {
1620         LOGI("DeviceManager::GetTrustedDeviceList deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1621              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1622              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1623              deviceInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1624     }
1625     napi_value callResult = nullptr;
1626     napi_value handler = nullptr;
1627     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1628 
1629     if (deviceInfoListAsyncCallbackInfo->status == 0) {
1630         if (deviceInfoListAsyncCallbackInfo->devList.size() > 0) {
1631             bool isArray = false;
1632             NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &array[1]));
1633             NAPI_CALL_RETURN_VOID(env, napi_is_array(env, array[1], &isArray));
1634             if (!isArray) {
1635                 LOGE("napi_create_array fail");
1636             }
1637             for (size_t i = 0; i != deviceInfoListAsyncCallbackInfo->devList.size(); ++i) {
1638                 DeviceInfoToJsArray(env, deviceInfoListAsyncCallbackInfo->devList, i, array[1]);
1639             }
1640             LOGI("devList is OK");
1641         } else {
1642             LOGE("devList is null");
1643         }
1644     } else {
1645         array[0] = CreateBusinessError(env, deviceInfoListAsyncCallbackInfo->ret, false);
1646     }
1647 
1648     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceInfoListAsyncCallbackInfo->callback, &handler));
1649     if (handler != nullptr) {
1650         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO, &array[0], &callResult));
1651         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceInfoListAsyncCallbackInfo->callback));
1652     } else {
1653         LOGE("handler is nullptr");
1654     }
1655 }
1656 
CallRequestCreInfoStatus(napi_env env,napi_status & status,CredentialAsyncCallbackInfo * creAsyncCallbackInfo)1657 void DeviceManagerNapi::CallRequestCreInfoStatus(napi_env env, napi_status &status,
1658                                                  CredentialAsyncCallbackInfo *creAsyncCallbackInfo)
1659 {
1660     LOGI("DeviceManager::RequestCredential");
1661     napi_value callResult = nullptr;
1662     napi_value handler = nullptr;
1663     napi_value result = nullptr;
1664     napi_create_object(env, &result);
1665 
1666     if (creAsyncCallbackInfo->status == 0) {
1667         if (creAsyncCallbackInfo->returnJsonStr == "") {
1668             LOGE("creAsyncCallbackInfo returnJsonStr is null");
1669         }
1670         SetValueUtf8String(env, "registerInfo", creAsyncCallbackInfo->returnJsonStr, result);
1671     } else {
1672         result = CreateBusinessError(env, creAsyncCallbackInfo->ret, false);
1673     }
1674 
1675     napi_get_reference_value(env, creAsyncCallbackInfo->callback, &handler);
1676     if (handler != nullptr) {
1677         napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_ONE, &result, &callResult);
1678         napi_delete_reference(env, creAsyncCallbackInfo->callback);
1679     } else {
1680         LOGE("handler is nullptr");
1681     }
1682 }
1683 
CallGetLocalDeviceInfoSync(napi_env env,napi_status & status,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1684 void DeviceManagerNapi::CallGetLocalDeviceInfoSync(napi_env env, napi_status &status,
1685                                                    DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1686 {
1687     napi_value result[DM_NAPI_ARGS_TWO] = {0};
1688 
1689     LOGI("DeviceManager::CallGetLocalDeviceInfoSync deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1690          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceId).c_str(),
1691          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
1692          deviceInfoAsyncCallbackInfo->deviceInfo.deviceTypeId);
1693 
1694     if (deviceInfoAsyncCallbackInfo->status == 0) {
1695         DmDeviceInfotoJsDeviceInfo(env, deviceInfoAsyncCallbackInfo->deviceInfo, result[1]);
1696         napi_resolve_deferred(env, deviceInfoAsyncCallbackInfo->deferred, result[1]);
1697     } else {
1698         result[0] = CreateBusinessError(env, deviceInfoAsyncCallbackInfo->ret, false);
1699         napi_reject_deferred(env, deviceInfoAsyncCallbackInfo->deferred, result[0]);
1700     }
1701 }
1702 
CallGetLocalDeviceInfo(napi_env env,napi_status & status,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1703 void DeviceManagerNapi::CallGetLocalDeviceInfo(napi_env env, napi_status &status,
1704                                                DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1705 {
1706     napi_value result[DM_NAPI_ARGS_TWO] = {0};
1707     LOGI("DeviceManager::CallGetLocalDeviceInfo deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1708          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceId).c_str(),
1709          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
1710          deviceInfoAsyncCallbackInfo->deviceInfo.deviceTypeId);
1711     napi_value callResult = nullptr;
1712     napi_value handler = nullptr;
1713 
1714     if (deviceInfoAsyncCallbackInfo->status == 0) {
1715         DmDeviceInfotoJsDeviceInfo(env, deviceInfoAsyncCallbackInfo->deviceInfo, result[1]);
1716     } else {
1717         result[0] = CreateBusinessError(env, deviceInfoAsyncCallbackInfo->ret, false);
1718     }
1719 
1720     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceInfoAsyncCallbackInfo->callback, &handler));
1721     if (handler != nullptr) {
1722         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO,
1723             &result[0], &callResult));
1724         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceInfoAsyncCallbackInfo->callback));
1725     } else {
1726         LOGE("handler is nullptr");
1727     }
1728 }
1729 
CallAsyncWorkSync(napi_env env,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1730 void DeviceManagerNapi::CallAsyncWorkSync(napi_env env, DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1731 {
1732     napi_value resourceName;
1733     napi_create_string_latin1(env, "GetLocalDeviceInfo", NAPI_AUTO_LENGTH, &resourceName);
1734     napi_create_async_work(
1735         env, nullptr, resourceName,
1736         [](napi_env env, void *data) {
1737             (void)env;
1738             DeviceInfoAsyncCallbackInfo *devInfoAsyncCallbackInfo =
1739                 reinterpret_cast<DeviceInfoAsyncCallbackInfo *>(data);
1740             int32_t ret = 0;
1741             ret = DeviceManager::GetInstance().GetLocalDeviceInfo(devInfoAsyncCallbackInfo->bundleName,
1742                                                                   devInfoAsyncCallbackInfo->deviceInfo);
1743             if (ret != 0) {
1744                 LOGE("CallAsyncWorkSync for bundleName %{public}s failed, ret %{public}d",
1745                      devInfoAsyncCallbackInfo->bundleName.c_str(), ret);
1746                 devInfoAsyncCallbackInfo->status = -1;
1747                 devInfoAsyncCallbackInfo->ret = ret;
1748             } else {
1749                 devInfoAsyncCallbackInfo->status = 0;
1750                 LOGI("CallAsyncWorkSync status %{public}d", devInfoAsyncCallbackInfo->status);
1751             }
1752         },
1753         [](napi_env env, napi_status status, void *data) {
1754             (void)status;
1755             DeviceInfoAsyncCallbackInfo *dInfoAsyncCallbackInfo =
1756                 reinterpret_cast<DeviceInfoAsyncCallbackInfo *>(data);
1757             CallGetLocalDeviceInfoSync(env, status, dInfoAsyncCallbackInfo);
1758             napi_delete_async_work(env, dInfoAsyncCallbackInfo->asyncWork);
1759             delete dInfoAsyncCallbackInfo;
1760         },
1761         (void *)deviceInfoAsyncCallbackInfo, &deviceInfoAsyncCallbackInfo->asyncWork);
1762     napi_queue_async_work_with_qos(env, deviceInfoAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1763 }
1764 
CallAsyncWork(napi_env env,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1765 void DeviceManagerNapi::CallAsyncWork(napi_env env, DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1766 {
1767     napi_value resourceName;
1768     napi_create_string_latin1(env, "GetLocalDeviceInfo", NAPI_AUTO_LENGTH, &resourceName);
1769     napi_create_async_work(
1770         env, nullptr, resourceName,
1771         [](napi_env env, void *data) {
1772             DeviceInfoAsyncCallbackInfo *devInfoAsyncCallbackInfo =
1773                 reinterpret_cast<DeviceInfoAsyncCallbackInfo *>(data);
1774             int32_t ret = 0;
1775             ret = DeviceManager::GetInstance().GetLocalDeviceInfo(devInfoAsyncCallbackInfo->bundleName,
1776                                                                   devInfoAsyncCallbackInfo->deviceInfo);
1777             if (ret != 0) {
1778                 LOGE("CallAsyncWork for bundleName %{public}s failed, ret %{public}d",
1779                      devInfoAsyncCallbackInfo->bundleName.c_str(), ret);
1780                 devInfoAsyncCallbackInfo->status = -1;
1781                 devInfoAsyncCallbackInfo->ret = ret;
1782             } else {
1783                 devInfoAsyncCallbackInfo->status = 0;
1784                 LOGI("CallAsyncWork status %{public}d", devInfoAsyncCallbackInfo->status);
1785             }
1786         },
1787         [](napi_env env, napi_status status, void *data) {
1788             (void)status;
1789             DeviceInfoAsyncCallbackInfo *dInfoAsyncCallbackInfo =
1790                 reinterpret_cast<DeviceInfoAsyncCallbackInfo *>(data);
1791             CallGetLocalDeviceInfo(env, status, dInfoAsyncCallbackInfo);
1792             napi_delete_async_work(env, dInfoAsyncCallbackInfo->asyncWork);
1793             delete dInfoAsyncCallbackInfo;
1794         },
1795         (void *)deviceInfoAsyncCallbackInfo, &deviceInfoAsyncCallbackInfo->asyncWork);
1796     napi_queue_async_work_with_qos(env, deviceInfoAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1797 }
1798 
CallAsyncWorkSync(napi_env env,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1799 void DeviceManagerNapi::CallAsyncWorkSync(napi_env env,
1800                                           DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1801 {
1802     napi_value resourceName;
1803     napi_create_string_latin1(env, "GetTrustListInfo", NAPI_AUTO_LENGTH, &resourceName);
1804     napi_create_async_work(
1805         env, nullptr, resourceName,
1806         [](napi_env env, void *data) {
1807             (void)env;
1808             DeviceInfoListAsyncCallbackInfo *devInfoListAsyncCallbackInfo =
1809                 reinterpret_cast<DeviceInfoListAsyncCallbackInfo *>(data);
1810             int32_t ret = 0;
1811             ret = DeviceManager::GetInstance().GetTrustedDeviceList(devInfoListAsyncCallbackInfo->bundleName,
1812                                                                     devInfoListAsyncCallbackInfo->extra,
1813                                                                     devInfoListAsyncCallbackInfo->devList);
1814             if (ret != 0) {
1815                 LOGE("CallAsyncWorkSync for bundleName %{public}s failed, ret %{public}d",
1816                      devInfoListAsyncCallbackInfo->bundleName.c_str(), ret);
1817                      devInfoListAsyncCallbackInfo->status = -1;
1818                      devInfoListAsyncCallbackInfo->ret = ret;
1819             } else {
1820                 devInfoListAsyncCallbackInfo->status = 0;
1821             }
1822             LOGI("CallAsyncWorkSync status %{public}d", devInfoListAsyncCallbackInfo->status);
1823         },
1824         [](napi_env env, napi_status status, void *data) {
1825             (void)status;
1826             DeviceInfoListAsyncCallbackInfo *dInfoListAsyncCallbackInfo =
1827                 reinterpret_cast<DeviceInfoListAsyncCallbackInfo *>(data);
1828             CallGetTrustedDeviceListStatusSync(env, status, dInfoListAsyncCallbackInfo);
1829             napi_delete_async_work(env, dInfoListAsyncCallbackInfo->asyncWork);
1830             delete dInfoListAsyncCallbackInfo;
1831         },
1832         (void *)deviceInfoListAsyncCallbackInfo, &deviceInfoListAsyncCallbackInfo->asyncWork);
1833     napi_queue_async_work_with_qos(env, deviceInfoListAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1834 }
1835 
CallAsyncWork(napi_env env,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1836 void DeviceManagerNapi::CallAsyncWork(napi_env env, DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1837 {
1838     napi_value resourceName;
1839     napi_create_string_latin1(env, "GetTrustListInfo", NAPI_AUTO_LENGTH, &resourceName);
1840     napi_create_async_work(
1841         env, nullptr, resourceName,
1842         [](napi_env env, void *data) {
1843             DeviceInfoListAsyncCallbackInfo *devInfoListAsyncCallbackInfo =
1844                 reinterpret_cast<DeviceInfoListAsyncCallbackInfo *>(data);
1845             int32_t ret = 0;
1846             ret = DeviceManager::GetInstance().GetTrustedDeviceList(devInfoListAsyncCallbackInfo->bundleName,
1847                                                                     devInfoListAsyncCallbackInfo->extra,
1848                                                                     devInfoListAsyncCallbackInfo->devList);
1849             if (ret != 0) {
1850                 LOGE("CallAsyncWork for bundleName %{public}s failed, ret %{public}d",
1851                     devInfoListAsyncCallbackInfo->bundleName.c_str(), ret);
1852                 devInfoListAsyncCallbackInfo->status = -1;
1853                 devInfoListAsyncCallbackInfo->ret = ret;
1854             } else {
1855                 devInfoListAsyncCallbackInfo->status = 0;
1856             }
1857             LOGI("CallAsyncWork status %{public}d", devInfoListAsyncCallbackInfo->status);
1858         },
1859         [](napi_env env, napi_status status, void *data) {
1860             (void)status;
1861             DeviceInfoListAsyncCallbackInfo *dInfoListAsyncCallbackInfo =
1862                 reinterpret_cast<DeviceInfoListAsyncCallbackInfo *>(data);
1863             CallGetTrustedDeviceListStatus(env, status, dInfoListAsyncCallbackInfo);
1864             napi_delete_async_work(env, dInfoListAsyncCallbackInfo->asyncWork);
1865             delete dInfoListAsyncCallbackInfo;
1866             dInfoListAsyncCallbackInfo = nullptr;
1867         },
1868         (void *)deviceInfoListAsyncCallbackInfo, &deviceInfoListAsyncCallbackInfo->asyncWork);
1869     napi_queue_async_work_with_qos(env, deviceInfoListAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1870 }
1871 
AsyncTaskCallback(napi_env env,void * data)1872 void DeviceManagerNapi::AsyncTaskCallback(napi_env env, void *data)
1873 {
1874     CredentialAsyncCallbackInfo *creAsyncCallbackInfo = reinterpret_cast<CredentialAsyncCallbackInfo *>(data);
1875     int32_t ret = DeviceManager::GetInstance().RequestCredential(creAsyncCallbackInfo->bundleName,
1876         creAsyncCallbackInfo->reqInfo, creAsyncCallbackInfo->returnJsonStr);
1877     if (ret != 0) {
1878         LOGE("CallCredentialAsyncWork for bundleName %{public}s failed, ret %{public}d",
1879             creAsyncCallbackInfo->bundleName.c_str(), ret);
1880         creAsyncCallbackInfo->status = -1;
1881         creAsyncCallbackInfo->ret = ret;
1882     } else {
1883         creAsyncCallbackInfo->status = 0;
1884     }
1885     LOGI("CallCredentialAsyncWork status %{public}d", creAsyncCallbackInfo->status);
1886 }
1887 
AsyncAfterTaskCallback(napi_env env,napi_status status,void * data)1888 void DeviceManagerNapi::AsyncAfterTaskCallback(napi_env env, napi_status status, void *data)
1889 {
1890     (void)status;
1891     CredentialAsyncCallbackInfo *creAsyncCallbackInfo = reinterpret_cast<CredentialAsyncCallbackInfo *>(data);
1892     CallRequestCreInfoStatus(env, status, creAsyncCallbackInfo);
1893     napi_delete_async_work(env, creAsyncCallbackInfo->asyncWork);
1894     delete creAsyncCallbackInfo;
1895 }
1896 
CallCredentialAsyncWork(napi_env env,CredentialAsyncCallbackInfo * creAsyncCallbackInfo)1897 void DeviceManagerNapi::CallCredentialAsyncWork(napi_env env, CredentialAsyncCallbackInfo *creAsyncCallbackInfo)
1898 {
1899     napi_value resourceName;
1900     napi_create_string_latin1(env, "RequestCreInfo", NAPI_AUTO_LENGTH, &resourceName);
1901 
1902     napi_create_async_work(env, nullptr, resourceName, AsyncTaskCallback, AsyncAfterTaskCallback,
1903         (void *)creAsyncCallbackInfo, &creAsyncCallbackInfo->asyncWork);
1904     napi_queue_async_work_with_qos(env, creAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1905 }
1906 
CallDeviceList(napi_env env,napi_callback_info info,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1907 napi_value DeviceManagerNapi::CallDeviceList(napi_env env, napi_callback_info info,
1908                                              DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1909 {
1910     napi_value result = nullptr;
1911     std::string extra = "";
1912     deviceInfoListAsyncCallbackInfo->extra = extra;
1913     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1914     napi_valuetype eventHandleType = napi_undefined;
1915     napi_typeof(env, argv[0], &eventHandleType);
1916     if (eventHandleType == napi_function) {
1917         LOGI("CallDeviceList for argc %{public}zu Type = %{public}d", argc, (int)eventHandleType);
1918         napi_create_reference(env, argv[0], 1, &deviceInfoListAsyncCallbackInfo->callback);
1919         CallAsyncWork(env, deviceInfoListAsyncCallbackInfo);
1920         napi_get_undefined(env, &result);
1921         return result;
1922     } else {
1923         LOGI("CallDeviceList for argc %{public}zu Type = %{public}d", argc, (int)eventHandleType);
1924         napi_deferred deferred;
1925         napi_value promise = 0;
1926         napi_create_promise(env, &deferred, &promise);
1927         deviceInfoListAsyncCallbackInfo->deferred = deferred;
1928         char extraString[20];
1929         JsObjectToString(env, argv[0], "extra", extraString, sizeof(extraString));
1930         deviceInfoListAsyncCallbackInfo->extra = extraString;
1931         CallAsyncWorkSync(env, deviceInfoListAsyncCallbackInfo);
1932         return promise;
1933     }
1934 }
1935 
GetTrustedDeviceListSync(napi_env env,napi_callback_info info)1936 napi_value DeviceManagerNapi::GetTrustedDeviceListSync(napi_env env, napi_callback_info info)
1937 {
1938     LOGI("GetTrustedDeviceListSync in");
1939     if (!CheckPermissions(env)) {
1940         return nullptr;
1941     }
1942     napi_value result = nullptr;
1943     napi_value thisVar = nullptr;
1944     size_t argc = 0;
1945     bool isArray = false;
1946     napi_create_array(env, &result);
1947     napi_is_array(env, result, &isArray);
1948     if (!isArray) {
1949         LOGE("napi_create_array fail");
1950     }
1951     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1952     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1953     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1954         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1955         return result;
1956     }
1957     std::vector<OHOS::DistributedHardware::DmDeviceInfo> devList;
1958     int32_t ret = 0;
1959     if (argc == DM_NAPI_ARGS_ZERO) {
1960         std::string extra = "";
1961         ret = DeviceManager::GetInstance().GetTrustedDeviceList(deviceManagerWrapper->bundleName_, extra, devList);
1962     } else if (argc == DM_NAPI_ARGS_ONE) {
1963         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1964         napi_valuetype valueType;
1965         napi_typeof(env, argv[0], &valueType);
1966         if (!CheckArgsType(env, valueType == napi_boolean, "refreshList", "bool")) {
1967             return nullptr;
1968         }
1969         bool isRefresh = false;
1970         napi_get_value_bool(env, argv[0], &isRefresh);
1971         std::string extra = "";
1972         ret = DeviceManager::GetInstance().GetTrustedDeviceList(deviceManagerWrapper->bundleName_, extra, isRefresh,
1973             devList);
1974     }
1975     if (ret != 0) {
1976         LOGE("GetTrustedDeviceList for bundleName %{public}s failed, ret %{public}d",
1977             deviceManagerWrapper->bundleName_.c_str(), ret);
1978         CreateBusinessError(env, ret);
1979         return result;
1980     }
1981     if (devList.size() > 0) {
1982         for (size_t i = 0; i != devList.size(); ++i) {
1983             DeviceInfoToJsArray(env, devList, (int32_t)i, result);
1984         }
1985     }
1986     return result;
1987 }
1988 
GetTrustedDeviceListPromise(napi_env env,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1989 napi_value DeviceManagerNapi::GetTrustedDeviceListPromise(napi_env env,
1990     DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1991 {
1992     std::string extra = "";
1993     deviceInfoListAsyncCallbackInfo->extra = extra;
1994     napi_deferred deferred;
1995     napi_value promise = 0;
1996     napi_create_promise(env, &deferred, &promise);
1997     deviceInfoListAsyncCallbackInfo->deferred = deferred;
1998     CallAsyncWorkSync(env, deviceInfoListAsyncCallbackInfo);
1999     return promise;
2000 }
2001 
GetTrustedDeviceListByFilter(napi_env env,napi_callback_info info,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)2002 napi_value DeviceManagerNapi::GetTrustedDeviceListByFilter(napi_env env, napi_callback_info info,
2003     DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
2004 {
2005     napi_value result = nullptr;
2006     napi_get_undefined(env, &result);
2007     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2008     napi_valuetype valueType;
2009     napi_typeof(env, argv[0], &valueType);
2010     if (!CheckArgsType(env, valueType == napi_string, "extra", "string")) {
2011         DeleteAsyncCallbackInfo(deviceInfoListAsyncCallbackInfo);
2012         return nullptr;
2013     }
2014 
2015     if (!IsFunctionType(env, argv[1])) {
2016         DeleteAsyncCallbackInfo(deviceInfoListAsyncCallbackInfo);
2017         return result;
2018     }
2019     char extra[DM_NAPI_BUF_LENGTH];
2020     JsObjectToString(env, argv[0], "extra", extra, sizeof(extra));
2021     deviceInfoListAsyncCallbackInfo->extra = extra;
2022     napi_create_reference(env, argv[1], 1, &deviceInfoListAsyncCallbackInfo->callback);
2023     CallAsyncWork(env, deviceInfoListAsyncCallbackInfo);
2024     return result;
2025 }
2026 
GetTrustedDeviceList(napi_env env,napi_callback_info info)2027 napi_value DeviceManagerNapi::GetTrustedDeviceList(napi_env env, napi_callback_info info)
2028 {
2029     if (!IsSystemApp()) {
2030         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2031         return nullptr;
2032     }
2033     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2034     if (ret != 0) {
2035         CreateBusinessError(env, ret);
2036         return nullptr;
2037     }
2038     napi_value result = nullptr;
2039     napi_value thisVar = nullptr;
2040     size_t argc = 0;
2041     std::vector<DmDeviceInfo> devList;
2042     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2043 
2044     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2045     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2046         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2047         return result;
2048     }
2049 
2050     auto *deviceInfoListAsyncCallbackInfo = new DeviceInfoListAsyncCallbackInfo();
2051     if (deviceInfoListAsyncCallbackInfo == nullptr) {
2052         return nullptr;
2053     }
2054     deviceInfoListAsyncCallbackInfo->env = env;
2055     deviceInfoListAsyncCallbackInfo->devList = devList;
2056     deviceInfoListAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
2057     if (argc == 0) {
2058         return GetTrustedDeviceListPromise(env, deviceInfoListAsyncCallbackInfo);
2059     } else if (argc == 1) {
2060         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2061         if (!IsFunctionType(env, argv[0])) {
2062             DeleteAsyncCallbackInfo(deviceInfoListAsyncCallbackInfo);
2063             return nullptr;
2064         }
2065         return CallDeviceList(env, info, deviceInfoListAsyncCallbackInfo);
2066     } else if (argc == DM_NAPI_ARGS_TWO) {
2067         return GetTrustedDeviceListByFilter(env, info, deviceInfoListAsyncCallbackInfo);
2068     }
2069     napi_get_undefined(env, &result);
2070     return result;
2071 }
2072 
GetLocalDeviceInfoSync(napi_env env,napi_callback_info info)2073 napi_value DeviceManagerNapi::GetLocalDeviceInfoSync(napi_env env, napi_callback_info info)
2074 {
2075     LOGI("GetLocalDeviceInfoSync in");
2076     if (!IsSystemApp()) {
2077         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2078         return nullptr;
2079     }
2080     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2081     if (ret != 0) {
2082         CreateBusinessError(env, ret);
2083         return nullptr;
2084     }
2085     napi_value result = nullptr;
2086     napi_value thisVar = nullptr;
2087     DmDeviceInfo deviceInfo;
2088     size_t argc = 0;
2089 
2090     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2091     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2092     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2093         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2094         return result;
2095     }
2096 
2097     ret = DeviceManager::GetInstance().GetLocalDeviceInfo(deviceManagerWrapper->bundleName_, deviceInfo);
2098     if (ret != 0) {
2099         LOGE("GetLocalDeviceInfoSync for failed, ret %{public}d", ret);
2100         CreateBusinessError(env, ret);
2101         return result;
2102     }
2103     LOGI("DeviceManager::GetLocalDeviceInfoSync deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
2104          GetAnonyString(std::string(deviceInfo.deviceId)).c_str(),
2105          GetAnonyString(std::string(deviceInfo.deviceName)).c_str(),
2106          deviceInfo.deviceTypeId);
2107     DmDeviceInfotoJsDeviceInfo(env, deviceInfo, result);
2108     return result;
2109 }
2110 
GetLocalDeviceInfo(napi_env env,napi_callback_info info)2111 napi_value DeviceManagerNapi::GetLocalDeviceInfo(napi_env env, napi_callback_info info)
2112 {
2113     LOGI("GetLocalDeviceInfo in");
2114     if (!IsSystemApp()) {
2115         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2116         return nullptr;
2117     }
2118     if (DeviceManager::GetInstance().CheckAPIAccessPermission() != 0) {
2119         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
2120         return nullptr;
2121     }
2122     napi_value result = nullptr;
2123     napi_value thisVar = nullptr;
2124     size_t argc = 0;
2125     DmDeviceInfo deviceInfo;
2126     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2127     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2128     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2129         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2130         return result;
2131     }
2132     auto *deviceInfoAsyncCallbackInfo = new DeviceInfoAsyncCallbackInfo();
2133     if (deviceInfoAsyncCallbackInfo == nullptr) {
2134         return nullptr;
2135     }
2136     deviceInfoAsyncCallbackInfo->env = env;
2137     deviceInfoAsyncCallbackInfo->deviceInfo = deviceInfo;
2138     deviceInfoAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
2139     if (argc == 0) {
2140         std::string extra = "";
2141         deviceInfoAsyncCallbackInfo->extra = extra;
2142         napi_deferred deferred;
2143         napi_value promise = 0;
2144         napi_create_promise(env, &deferred, &promise);
2145         deviceInfoAsyncCallbackInfo->deferred = deferred;
2146         CallAsyncWorkSync(env, deviceInfoAsyncCallbackInfo);
2147         return promise;
2148     } else if (argc == 1) {
2149         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2150         if (!IsFunctionType(env, argv[0])) {
2151             delete deviceInfoAsyncCallbackInfo;
2152             deviceInfoAsyncCallbackInfo = nullptr;
2153             return nullptr;
2154         }
2155         deviceInfoAsyncCallbackInfo->extra = "";
2156         napi_create_reference(env, argv[0], 1, &deviceInfoAsyncCallbackInfo->callback);
2157         CallAsyncWork(env, deviceInfoAsyncCallbackInfo);
2158     }
2159     napi_get_undefined(env, &result);
2160     return result;
2161 }
2162 
UnAuthenticateDevice(napi_env env,napi_callback_info info)2163 napi_value DeviceManagerNapi::UnAuthenticateDevice(napi_env env, napi_callback_info info)
2164 {
2165     LOGI("UnAuthenticateDevice");
2166     if (!IsSystemApp()) {
2167         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2168         return nullptr;
2169     }
2170     napi_value result = nullptr;
2171     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2172     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
2173         return nullptr;
2174     }
2175     napi_valuetype deviceInfoType = napi_undefined;
2176     napi_typeof(env, argv[0], &deviceInfoType);
2177     if (!CheckArgsType(env, deviceInfoType == napi_object, "deviceInfo", "object")) {
2178         return nullptr;
2179     }
2180 
2181     DmDeviceInfo deviceInfo;
2182     JsToDmDeviceInfo(env, argv[0], deviceInfo);
2183     LOGI("UnAuthenticateDevice deviceId = %{public}s", GetAnonyString(deviceInfo.deviceId).c_str());
2184     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2185     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2186         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2187         return result;
2188     }
2189 
2190     int32_t ret = DeviceManager::GetInstance().UnAuthenticateDevice(deviceManagerWrapper->bundleName_, deviceInfo);
2191     if (ret != 0) {
2192         LOGE("UnAuthenticateDevice for bundleName %{public}s failed, ret %{public}d",
2193             deviceManagerWrapper->bundleName_.c_str(), ret);
2194         CreateBusinessError(env, ret);
2195     }
2196 
2197     napi_create_int32(env, ret, &result);
2198     return result;
2199 }
2200 
StartArgCheck(napi_env env,napi_value & argv,OHOS::DistributedHardware::DmSubscribeInfo & subInfo)2201 bool DeviceManagerNapi::StartArgCheck(napi_env env, napi_value &argv,
2202     OHOS::DistributedHardware::DmSubscribeInfo &subInfo)
2203 {
2204     napi_valuetype valueType = napi_undefined;
2205     napi_typeof(env, argv, &valueType);
2206     if (!CheckArgsType(env, valueType == napi_object, "subscribeInfo", "object")) {
2207         return false;
2208     }
2209     int32_t res = JsToDmSubscribeInfo(env, argv, subInfo);
2210     if (!CheckArgsVal(env, res == 0, "subscribeId", "Wrong subscribeId")) {
2211         return false;
2212     }
2213     return true;
2214 }
2215 
CheckPermissions(napi_env env)2216 bool DeviceManagerNapi::CheckPermissions(napi_env env)
2217 {
2218     LOGI("CheckPermissions in");
2219     if (!IsSystemApp()) {
2220         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2221         return false;
2222     }
2223     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2224     if (ret != 0) {
2225         CreateBusinessError(env, ret);
2226         return false;
2227     }
2228     return true;
2229 }
2230 
LockDiscoveryCallbackMutex(napi_env env,DmSubscribeInfo subInfo,std::string & bundleName,std::string & extra)2231 void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, DmSubscribeInfo subInfo, std::string &bundleName,
2232     std::string &extra)
2233 {
2234     std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = nullptr;
2235     {
2236         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
2237         auto iter = g_DiscoveryCallbackMap.find(bundleName);
2238         if (iter == g_DiscoveryCallbackMap.end()) {
2239             discoveryCallback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
2240             g_DiscoveryCallbackMap[bundleName] = discoveryCallback;
2241         } else {
2242             discoveryCallback = iter->second;
2243         }
2244     }
2245     int32_t ret = DeviceManager::GetInstance().StartDeviceDiscovery(bundleName, subInfo, extra, discoveryCallback);
2246     if (ret != 0) {
2247         LOGE("Discovery failed, bundleName %{public}s, ret %{public}d", bundleName.c_str(), ret);
2248         CreateBusinessError(env, ret);
2249         discoveryCallback->OnDiscoveryFailed(subInfo.subscribeId, ret);
2250     }
2251     return;
2252 }
2253 
StartDeviceDiscoverSync(napi_env env,napi_callback_info info)2254 napi_value DeviceManagerNapi::StartDeviceDiscoverSync(napi_env env, napi_callback_info info)
2255 {
2256     LOGI("StartDeviceDiscoverSync in");
2257     if (!IsSystemApp()) {
2258         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2259         return nullptr;
2260     }
2261     std::string extra = "";
2262     DmSubscribeInfo subInfo;
2263     napi_value result = nullptr;
2264     napi_value thisVar = nullptr;
2265     size_t argcNum = 0;
2266     NAPI_CALL(env, napi_get_cb_info(env, info, &argcNum, nullptr, &thisVar, nullptr));
2267     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2268     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2269         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2270         return result;
2271     }
2272     if (argcNum >= DM_NAPI_ARGS_ONE) {
2273         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2274         if (!StartArgCheck(env, argv[0], subInfo)) {
2275             return nullptr;
2276         }
2277         if (argcNum == DM_NAPI_ARGS_TWO) {
2278             napi_valuetype valueType1 = napi_undefined;
2279             napi_typeof(env, argv[1], &valueType1);
2280             if (!(CheckArgsType(env, (valueType1 == napi_undefined || valueType1 == napi_string), "filterOptions",
2281                 "string or undefined"))) {
2282                 return nullptr;
2283             }
2284             JsToDmDiscoveryExtra(env, argv[1], extra);
2285         }
2286     }
2287     LockDiscoveryCallbackMutex(env, subInfo, deviceManagerWrapper->bundleName_, extra);
2288     napi_get_undefined(env, &result);
2289     return result;
2290 }
2291 
StopDeviceDiscoverSync(napi_env env,napi_callback_info info)2292 napi_value DeviceManagerNapi::StopDeviceDiscoverSync(napi_env env, napi_callback_info info)
2293 {
2294     LOGI("StopDeviceDiscoverSync in");
2295     if (!IsSystemApp()) {
2296         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2297         return nullptr;
2298     }
2299     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2300     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
2301         return nullptr;
2302     }
2303 
2304     napi_value result = nullptr;
2305     napi_valuetype valueType = napi_undefined;
2306     napi_typeof(env, argv[0], &valueType);
2307     if (!CheckArgsType(env, valueType == napi_number, "subscribeId", "number")) {
2308         return nullptr;
2309     }
2310 
2311     int32_t subscribeId = 0;
2312     napi_get_value_int32(env, argv[0], &subscribeId);
2313     if (!CheckArgsVal(env, subscribeId <= DM_NAPI_SUB_ID_MAX, "subscribeId", "Wrong argument. subscribeId Too Big")) {
2314         return nullptr;
2315     }
2316     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2317     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2318         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2319         return result;
2320     }
2321     int32_t ret = DeviceManager::GetInstance().StopDeviceDiscovery(deviceManagerWrapper->bundleName_,
2322                                                                    static_cast<int16_t>(subscribeId));
2323     if (ret != 0) {
2324         LOGE("StopDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
2325             deviceManagerWrapper->bundleName_.c_str(), ret);
2326         CreateBusinessError(env, ret);
2327         return result;
2328     }
2329 
2330     napi_get_undefined(env, &result);
2331     return result;
2332 }
2333 
PublishDeviceDiscoverySync(napi_env env,napi_callback_info info)2334 napi_value DeviceManagerNapi::PublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
2335 {
2336     LOGI("PublishDeviceDiscoverySync in");
2337     if (!IsSystemApp()) {
2338         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2339         return nullptr;
2340     }
2341     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2342     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
2343         return nullptr;
2344     }
2345 
2346     napi_value result = nullptr;
2347     napi_valuetype valueType = napi_undefined;
2348     napi_typeof(env, argv[0], &valueType);
2349     if (!CheckArgsType(env, valueType == napi_object, "publishInfo", "object")) {
2350         return nullptr;
2351     }
2352     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2353     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2354         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2355         return result;
2356     }
2357 
2358     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
2359     {
2360         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
2361         auto iter = g_publishCallbackMap.find(deviceManagerWrapper->bundleName_);
2362         if (iter == g_publishCallbackMap.end()) {
2363             publishCallback = std::make_shared<DmNapiPublishCallback>(env, deviceManagerWrapper->bundleName_);
2364             g_publishCallbackMap[deviceManagerWrapper->bundleName_] = publishCallback;
2365         } else {
2366             publishCallback = iter->second;
2367         }
2368     }
2369     DmPublishInfo publishInfo;
2370     JsToDmPublishInfo(env, argv[0], publishInfo);
2371     int32_t ret = DeviceManager::GetInstance().PublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishInfo,
2372         publishCallback);
2373     if (ret != 0) {
2374         LOGE("PublishDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
2375             deviceManagerWrapper->bundleName_.c_str(), ret);
2376         CreateBusinessError(env, ret);
2377         publishCallback->OnPublishResult(publishInfo.publishId, ret);
2378         return result;
2379     }
2380 
2381     napi_get_undefined(env, &result);
2382     return result;
2383 }
2384 
UnPublishDeviceDiscoverySync(napi_env env,napi_callback_info info)2385 napi_value DeviceManagerNapi::UnPublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
2386 {
2387     LOGI("UnPublishDeviceDiscoverySync in");
2388     if (!IsSystemApp()) {
2389         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2390         return nullptr;
2391     }
2392     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2393     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
2394         return nullptr;
2395     }
2396 
2397     napi_value result = nullptr;
2398     napi_valuetype valueType = napi_undefined;
2399     napi_typeof(env, argv[0], &valueType);
2400     if (!CheckArgsType(env, valueType == napi_number, "publishId", "number")) {
2401         return nullptr;
2402     }
2403     int32_t publishId = 0;
2404     napi_get_value_int32(env, argv[0], &publishId);
2405 
2406     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2407     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2408         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2409         return result;
2410     }
2411 
2412     int32_t ret = DeviceManager::GetInstance().UnPublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishId);
2413     if (ret != 0) {
2414         LOGE("UnPublishDeviceDiscovery bundleName %{public}s failed, ret %{public}d",
2415             deviceManagerWrapper->bundleName_.c_str(), ret);
2416         CreateBusinessError(env, ret);
2417         return result;
2418     }
2419 
2420     napi_get_undefined(env, &result);
2421     return result;
2422 }
2423 
AuthenticateDevice(napi_env env,napi_callback_info info)2424 napi_value DeviceManagerNapi::AuthenticateDevice(napi_env env, napi_callback_info info)
2425 {
2426     if (!IsSystemApp()) {
2427         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2428         return nullptr;
2429     }
2430     GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
2431     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE,  "Wrong number of arguments, required 3")) {
2432         return nullptr;
2433     }
2434     napi_value result = nullptr;
2435     if (!IsJSObjectType(env, argv[0], "deviceInfo")) {
2436         return nullptr;
2437     }
2438     if (!IsJSObjectType(env, argv[DM_NAPI_ARGS_ONE], "authParam")) {
2439         return nullptr;
2440     }
2441     if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
2442         return nullptr;
2443     }
2444 
2445     authAsyncCallbackInfo_.env = env;
2446     napi_create_reference(env, argv[DM_NAPI_ARGS_TWO], 1, &authAsyncCallbackInfo_.callback);
2447     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2448     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2449         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2450         return result;
2451     }
2452 
2453     std::shared_ptr<DmNapiAuthenticateCallback> authCallback = nullptr;
2454     {
2455         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
2456         auto iter = g_authCallbackMap.find(deviceManagerWrapper->bundleName_);
2457         if (iter == g_authCallbackMap.end()) {
2458             authCallback = std::make_shared<DmNapiAuthenticateCallback>(env, deviceManagerWrapper->bundleName_);
2459             g_authCallbackMap[deviceManagerWrapper->bundleName_] = authCallback;
2460         } else {
2461             authCallback = iter->second;
2462         }
2463     }
2464     DmDeviceInfo deviceInfo;
2465     JsToDmDeviceInfo(env, argv[0], deviceInfo);
2466     std::string extraString;
2467     JsToDmExtra(env, argv[DM_NAPI_ARGS_ONE], extraString, authAsyncCallbackInfo_.authType);
2468     int32_t ret = DeviceManager::GetInstance().AuthenticateDevice(deviceManagerWrapper->bundleName_,
2469         authAsyncCallbackInfo_.authType, deviceInfo, extraString, authCallback);
2470     if (ret != 0) {
2471         LOGE("AuthDevice failed bundleName %{public}s, ret %{public}d", deviceManagerWrapper->bundleName_.c_str(), ret);
2472         CreateBusinessError(env, ret);
2473     }
2474     napi_get_undefined(env, &result);
2475     return result;
2476 }
2477 
RequestCredential(napi_env env,napi_callback_info info)2478 napi_value DeviceManagerNapi::RequestCredential(napi_env env, napi_callback_info info)
2479 {
2480     LOGI("RequestCredential function has been discarded");
2481     return nullptr;
2482     if (!IsSystemApp()) {
2483         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2484         return nullptr;
2485     }
2486     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2487 
2488     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2489         return nullptr;
2490     }
2491 
2492     napi_value result = nullptr;
2493     napi_valuetype requestInfoValueType = napi_undefined;
2494     napi_typeof(env, argv[0], &requestInfoValueType);
2495     if (!CheckArgsType(env, requestInfoValueType == napi_string, "requestInfo", "string")) {
2496         return nullptr;
2497     }
2498 
2499     napi_valuetype funcValueType = napi_undefined;
2500     napi_typeof(env, argv[1], &funcValueType);
2501     if (!CheckArgsType(env, funcValueType == napi_function, "callback", "function")) {
2502         return nullptr;
2503     }
2504 
2505     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2506     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&deviceManagerWrapper));
2507     if (deviceManagerWrapper == nullptr) {
2508         LOGE(" DeviceManagerNapi object is nullptr!");
2509         return result;
2510     }
2511 
2512     size_t typeLen = 0;
2513     napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
2514     NAPI_ASSERT(env, typeLen < DM_NAPI_BUF_LENGTH, "typeLen >= MAXLEN");
2515     char type[DM_NAPI_BUF_LENGTH] = {0};
2516     napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
2517 
2518     auto *creAsyncCallbackInfo = new CredentialAsyncCallbackInfo();
2519     creAsyncCallbackInfo->env = env;
2520     creAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
2521     creAsyncCallbackInfo->reqInfo = type;
2522 
2523     napi_create_reference(env, argv[1], 1, &creAsyncCallbackInfo->callback);
2524     CallCredentialAsyncWork(env, creAsyncCallbackInfo);
2525     napi_get_undefined(env, &result);
2526     return result;
2527 }
2528 
RegisterCredentialCallback(napi_env env,const std::string & pkgName)2529 int32_t DeviceManagerNapi::RegisterCredentialCallback(napi_env env, const std::string &pkgName)
2530 {
2531     std::shared_ptr<DmNapiCredentialCallback> creCallback = nullptr;
2532     {
2533         std::lock_guard<std::mutex> autoLock(creMapLocks_);
2534         auto iter = g_creCallbackMap.find(pkgName);
2535         if (iter == g_creCallbackMap.end()) {
2536             creCallback = std::make_shared<DmNapiCredentialCallback>(env, pkgName);
2537             g_creCallbackMap[pkgName] = creCallback;
2538         } else {
2539             creCallback = iter->second;
2540         }
2541     }
2542     int32_t ret = DeviceManager::GetInstance().RegisterCredentialCallback(pkgName,
2543         creCallback);
2544     if (ret != 0) {
2545         LOGE("RegisterCredentialCallback for bundleName %{public}s failed, ret %{public}d", pkgName.c_str(), ret);
2546         CreateBusinessError(env, ret);
2547     }
2548     return ret;
2549 }
2550 
ImportCredential(napi_env env,napi_callback_info info)2551 napi_value DeviceManagerNapi::ImportCredential(napi_env env, napi_callback_info info)
2552 {
2553     LOGI("ImportCredential start.");
2554     if (!IsSystemApp()) {
2555         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2556         return nullptr;
2557     }
2558     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2559     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2560         return nullptr;
2561     }
2562     napi_value result = nullptr;
2563     napi_valuetype importInfoValueType = napi_undefined;
2564     napi_typeof(env, argv[0], &importInfoValueType);
2565     if (!CheckArgsType(env, importInfoValueType == napi_string, "credentialInfo", "string")) {
2566         return nullptr;
2567     }
2568     if (!IsFunctionType(env, argv[1])) {
2569         return nullptr;
2570     }
2571 
2572     creAsyncCallbackInfo_.env = env;
2573     napi_create_reference(env, argv[1], 1, &creAsyncCallbackInfo_.callback);
2574 
2575     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2576     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&deviceManagerWrapper));
2577     if (deviceManagerWrapper == nullptr) {
2578         LOGE(" DeviceManagerNapi object is nullptr!");
2579         return result;
2580     }
2581     if (RegisterCredentialCallback(env, deviceManagerWrapper->bundleName_) != 0) {
2582         LOGE("RegisterCredentialCallback failed!");
2583         return result;
2584     }
2585 
2586     size_t typeLen = 0;
2587     napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
2588     NAPI_ASSERT(env, typeLen > 0, "typeLen == 0");
2589     NAPI_ASSERT(env, typeLen < DM_NAPI_CREDENTIAL_BUF_LENGTH, "typeLen >= MAXLEN");
2590     char type[DM_NAPI_CREDENTIAL_BUF_LENGTH] = {0};
2591     napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
2592     std::string credentialInfo = type;
2593     int32_t ret = DeviceManager::GetInstance().ImportCredential(deviceManagerWrapper->bundleName_, credentialInfo);
2594     if (ret != 0) {
2595         LOGE("ImportCredential for bundleName %{public}s failed, ret %{public}d",
2596             deviceManagerWrapper->bundleName_.c_str(), ret);
2597         CreateBusinessError(env, ret);
2598     }
2599     napi_get_undefined(env, &result);
2600     return result;
2601 }
2602 
DeleteCredential(napi_env env,napi_callback_info info)2603 napi_value DeviceManagerNapi::DeleteCredential(napi_env env, napi_callback_info info)
2604 {
2605     LOGE("DeleteCredential function has been discarded");
2606     return nullptr;
2607     if (!IsSystemApp()) {
2608         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2609         return nullptr;
2610     }
2611     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2612     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2613         return nullptr;
2614     }
2615 
2616     napi_value result = nullptr;
2617     napi_valuetype queryInfoValueType = napi_undefined;
2618     napi_typeof(env, argv[0], &queryInfoValueType);
2619     if (!CheckArgsType(env, queryInfoValueType == napi_string, "queryInfo", "string")) {
2620         return nullptr;
2621     }
2622     if (!IsFunctionType(env, argv[1])) {
2623         return nullptr;
2624     }
2625 
2626     creAsyncCallbackInfo_.env = env;
2627     napi_create_reference(env, argv[1], 1, &creAsyncCallbackInfo_.callback);
2628     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2629     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&deviceManagerWrapper));
2630     if (deviceManagerWrapper == nullptr) {
2631         LOGE(" DeviceManagerNapi object is nullptr!");
2632         return result;
2633     }
2634     if (RegisterCredentialCallback(env, deviceManagerWrapper->bundleName_) != 0) {
2635         LOGE("RegisterCredentialCallback failed!");
2636         return result;
2637     }
2638 
2639     size_t typeLen = 0;
2640     napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
2641     NAPI_ASSERT(env, typeLen > 0, "typeLen == 0");
2642     NAPI_ASSERT(env, typeLen < DM_NAPI_CREDENTIAL_BUF_LENGTH, "typeLen >= MAXLEN");
2643     char type[DM_NAPI_CREDENTIAL_BUF_LENGTH] = {0};
2644     napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
2645     std::string queryInfo = type;
2646     int32_t ret = DeviceManager::GetInstance().DeleteCredential(deviceManagerWrapper->bundleName_, queryInfo);
2647     if (ret != 0) {
2648         LOGE("DeleteCredential for bundleName %{public}s failed, ret %{public}d",
2649             deviceManagerWrapper->bundleName_.c_str(), ret);
2650         CreateBusinessError(env, ret);
2651     }
2652     napi_get_undefined(env, &result);
2653     return result;
2654 }
2655 
JsOnFrench(napi_env env,int32_t num,napi_value thisVar,napi_value argv[])2656 napi_value DeviceManagerNapi::JsOnFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
2657 {
2658     size_t typeLen = 0;
2659     napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
2660 
2661     if (!CheckArgsVal(env, typeLen > 0, "type", "typeLen == 0")) {
2662         return nullptr;
2663     }
2664     if (!CheckArgsVal(env, typeLen < DM_NAPI_BUF_LENGTH, "type", "typeLen >= MAXLEN")) {
2665         return nullptr;
2666     }
2667     char type[DM_NAPI_BUF_LENGTH] = {0};
2668     napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
2669 
2670     std::string eventType = type;
2671     napi_value result = nullptr;
2672     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2673     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2674         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2675         return result;
2676     }
2677 
2678     LOGI("JsOn for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
2679         eventType.c_str());
2680     deviceManagerWrapper->On(eventType, argv[num + 1]);
2681 
2682     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
2683         if (num == 1) {
2684             size_t extraLen = 0;
2685             napi_get_value_string_utf8(env, argv[1], nullptr, 0, &extraLen);
2686             if (!CheckArgsVal(env, extraLen < DM_NAPI_BUF_LENGTH, "extra", "extraLen >= MAXLEN")) {
2687                 return nullptr;
2688             }
2689             char extra[DM_NAPI_BUF_LENGTH] = {0};
2690             napi_get_value_string_utf8(env, argv[1], extra, extraLen + 1, &extraLen);
2691             std::string extraString = extra;
2692             LOGI("extra = %{public}s", extraString.c_str());
2693             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType, extraString);
2694         } else {
2695             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
2696         }
2697     } else {
2698         CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
2699     }
2700 
2701     napi_get_undefined(env, &result);
2702     return result;
2703 }
2704 
JsOn(napi_env env,napi_callback_info info)2705 napi_value DeviceManagerNapi::JsOn(napi_env env, napi_callback_info info)
2706 {
2707     if (!IsSystemApp()) {
2708         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2709         return nullptr;
2710     }
2711     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2712     if (ret != 0) {
2713         CreateBusinessError(env, ret);
2714         return nullptr;
2715     }
2716     size_t argc = 0;
2717     napi_value thisVar = nullptr;
2718     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2719     if (argc == DM_NAPI_ARGS_THREE) {
2720         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
2721         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE, "Wrong number of arguments, required 3")) {
2722             return nullptr;
2723         }
2724         napi_valuetype eventValueType = napi_undefined;
2725         napi_typeof(env, argv[0], &eventValueType);
2726         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2727             return nullptr;
2728         }
2729         napi_valuetype valueType;
2730         napi_typeof(env, argv[1], &valueType);
2731         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object),
2732             "extra", "string | object")) {
2733             return nullptr;
2734         }
2735         if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
2736             return nullptr;
2737         }
2738         return JsOnFrench(env, 1, thisVar, argv);
2739     } else {
2740         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2741         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2742             return nullptr;
2743         }
2744         napi_valuetype eventValueType = napi_undefined;
2745         napi_typeof(env, argv[0], &eventValueType);
2746         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2747             return nullptr;
2748         }
2749         if (!IsFunctionType(env, argv[1])) {
2750             return nullptr;
2751         }
2752         return JsOnFrench(env, 0, thisVar, argv);
2753     }
2754 }
2755 
JsOffFrench(napi_env env,int32_t num,napi_value thisVar,napi_value argv[])2756 napi_value DeviceManagerNapi::JsOffFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
2757 {
2758     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2759     if (ret != 0) {
2760         CreateBusinessError(env, ret);
2761         return nullptr;
2762     }
2763     size_t typeLen = 0;
2764     napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
2765     if (!CheckArgsVal(env, typeLen > 0, "type", "typeLen == 0")) {
2766         return nullptr;
2767     }
2768     if (!CheckArgsVal(env, typeLen < DM_NAPI_BUF_LENGTH, "type", "typeLen >= MAXLEN")) {
2769         return nullptr;
2770     }
2771     char type[DM_NAPI_BUF_LENGTH] = {0};
2772     napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
2773 
2774     napi_value result = nullptr;
2775     std::string eventType = type;
2776     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2777     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2778         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2779         return result;
2780     }
2781 
2782     LOGI("JsOff for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
2783         eventType.c_str());
2784     deviceManagerWrapper->Off(eventType);
2785     ReleaseDmCallback(deviceManagerWrapper->bundleName_, eventType);
2786 
2787     napi_get_undefined(env, &result);
2788     return result;
2789 }
2790 
JsOff(napi_env env,napi_callback_info info)2791 napi_value DeviceManagerNapi::JsOff(napi_env env, napi_callback_info info)
2792 {
2793     if (!IsSystemApp()) {
2794         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2795         return nullptr;
2796     }
2797     size_t argc = 0;
2798     napi_value thisVar = nullptr;
2799     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2800     if (argc == DM_NAPI_ARGS_THREE) {
2801         LOGI("JsOff in argc == 3");
2802         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
2803         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2804             return nullptr;
2805         }
2806         napi_valuetype eventValueType = napi_undefined;
2807         napi_typeof(env, argv[0], &eventValueType);
2808         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2809             return nullptr;
2810         }
2811         napi_valuetype valueType;
2812         napi_typeof(env, argv[1], &valueType);
2813         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object), "extra", "string or object")) {
2814             return nullptr;
2815         }
2816         if (argc > DM_NAPI_ARGS_ONE) {
2817             if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
2818                 return nullptr;
2819             }
2820         }
2821         return JsOffFrench(env, 1, thisVar, argv);
2822     } else {
2823         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2824         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2825             return nullptr;
2826         }
2827         napi_valuetype eventValueType = napi_undefined;
2828         napi_typeof(env, argv[0], &eventValueType);
2829         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2830             return nullptr;
2831         }
2832         if (argc > DM_NAPI_ARGS_ONE) {
2833             if (!IsFunctionType(env, argv[1])) {
2834                 return nullptr;
2835             }
2836         }
2837         return JsOffFrench(env, 0, thisVar, argv);
2838     }
2839 }
ClearBundleCallbacks(std::string & bundleName)2840 void DeviceManagerNapi::ClearBundleCallbacks(std::string &bundleName)
2841 {
2842     LOGI("ClearBundleCallbacks start for bundleName %{public}s", bundleName.c_str());
2843     {
2844         std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
2845         g_deviceManagerMap.erase(bundleName);
2846     }
2847     {
2848         std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
2849         g_initCallbackMap.erase(bundleName);
2850     }
2851     {
2852         std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
2853         g_deviceStateCallbackMap.erase(bundleName);
2854     }
2855     {
2856         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
2857         g_DiscoveryCallbackMap.erase(bundleName);
2858     }
2859     {
2860         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
2861         g_publishCallbackMap.erase(bundleName);
2862     }
2863     {
2864         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
2865         g_authCallbackMap.erase(bundleName);
2866     }
2867     {
2868         std::lock_guard<std::mutex> autoLock(creMapLocks_);
2869         g_creCallbackMap.erase(bundleName);
2870     }
2871 }
ReleaseDeviceManager(napi_env env,napi_callback_info info)2872 napi_value DeviceManagerNapi::ReleaseDeviceManager(napi_env env, napi_callback_info info)
2873 {
2874     LOGI("ReleaseDeviceManager in");
2875     if (!IsSystemApp()) {
2876         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2877         return nullptr;
2878     }
2879     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2880     if (ret != 0) {
2881         CreateBusinessError(env, ret);
2882         return nullptr;
2883     }
2884     size_t argc = 0;
2885     napi_value thisVar = nullptr;
2886     napi_value result = nullptr;
2887     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2888     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2889     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2890         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2891         return result;
2892     }
2893     LOGI("ReleaseDeviceManager for bundleName %{public}s", deviceManagerWrapper->bundleName_.c_str());
2894     ret = DeviceManager::GetInstance().UnInitDeviceManager(deviceManagerWrapper->bundleName_);
2895     if (ret != 0) {
2896         LOGE("ReleaseDeviceManager for bundleName %{public}s failed, ret %{public}d",
2897             deviceManagerWrapper->bundleName_.c_str(), ret);
2898         CreateBusinessError(env, ret);
2899         napi_create_uint32(env, static_cast<uint32_t>(ret), &result);
2900         return result;
2901     }
2902     ClearBundleCallbacks(deviceManagerWrapper->bundleName_);
2903     napi_get_undefined(env, &result);
2904     NAPI_CALL(env, napi_remove_wrap(env, thisVar, (void**)&deviceManagerWrapper));
2905     return result;
2906 }
2907 
HandleCreateDmCallBackCompletedCB(napi_env env,napi_status status,void * data)2908 void DeviceManagerNapi::HandleCreateDmCallBackCompletedCB(napi_env env, napi_status status, void *data)
2909 {
2910     (void)status;
2911     AsyncCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(data);
2912     napi_value result[DM_NAPI_ARGS_TWO] = {0};
2913     if (asyncCallbackInfo->status == 0) {
2914         napi_value ctor = nullptr;
2915         napi_value argv = nullptr;
2916         napi_get_reference_value(env, sConstructor_, &ctor);
2917         napi_create_string_utf8(env, asyncCallbackInfo->bundleName, NAPI_AUTO_LENGTH, &argv);
2918         napi_status ret = napi_new_instance(env, ctor, DM_NAPI_ARGS_ONE, &argv, &result[1]);
2919         if (ret != napi_ok) {
2920                 LOGE("Create DeviceManagerNapi for bundleName %{public}s failed", asyncCallbackInfo->bundleName);
2921         } else {
2922                 LOGI("InitDeviceManager for bundleName %{public}s success", asyncCallbackInfo->bundleName);
2923                 napi_get_undefined(env, &result[0]);
2924         }
2925     } else {
2926         LOGI("InitDeviceManager for bundleName %{public}s failed", asyncCallbackInfo->bundleName);
2927         result[0] = CreateBusinessError(env, asyncCallbackInfo->ret, false);
2928     }
2929     napi_value callback = nullptr;
2930     napi_value callResult = nullptr;
2931     napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
2932     if (callback != nullptr) {
2933         napi_call_function(env, nullptr, callback, DM_NAPI_ARGS_TWO, &result[0], &callResult);
2934         napi_delete_reference(env, asyncCallbackInfo->callback);
2935     }
2936 
2937     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
2938     delete asyncCallbackInfo;
2939     asyncCallbackInfo = nullptr;
2940 }
2941 
HandleCreateDmCallBack(const napi_env & env,AsyncCallbackInfo * asCallbackInfo)2942 void DeviceManagerNapi::HandleCreateDmCallBack(const napi_env &env, AsyncCallbackInfo *asCallbackInfo)
2943 {
2944     napi_value resourceName;
2945     napi_create_string_latin1(env, "createDeviceManagerCallback", NAPI_AUTO_LENGTH, &resourceName);
2946     napi_create_async_work(
2947         env, nullptr, resourceName,
2948         [](napi_env env, void *data) {
2949             (void)env;
2950             AsyncCallbackInfo *asyCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(data);
2951             std::string bundleName = std::string(asyCallbackInfo->bundleName);
2952             std::shared_ptr<DmNapiInitCallback> initCallback = std::make_shared<DmNapiInitCallback>(env, bundleName);
2953             int32_t ret = DeviceManager::GetInstance().InitDeviceManager(bundleName, initCallback);
2954             if (ret == 0) {
2955                 std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
2956                 g_initCallbackMap[bundleName] = initCallback;
2957                 asyCallbackInfo->status = 0;
2958             } else {
2959                 asyCallbackInfo->status = 1;
2960                 asyCallbackInfo->ret = ret;
2961             }
2962         }, HandleCreateDmCallBackCompletedCB, (void *)asCallbackInfo, &asCallbackInfo->asyncWork);
2963     napi_queue_async_work_with_qos(env, asCallbackInfo->asyncWork, napi_qos_user_initiated);
2964 }
2965 
CallGetDeviceInfo(napi_env env,NetworkIdAsyncCallbackInfo * networkIdAsyncCallbackInfo)2966 void DeviceManagerNapi::CallGetDeviceInfo(napi_env env, NetworkIdAsyncCallbackInfo *networkIdAsyncCallbackInfo)
2967 {
2968     napi_value resourceName;
2969     napi_create_string_latin1(env, "GetLocalDeviceInfo", NAPI_AUTO_LENGTH, &resourceName);
2970     napi_create_async_work(
2971         env, nullptr, resourceName,
2972         GetDeviceInfoCB,
2973         CompleteGetDeviceInfoCB,
2974         (void *)networkIdAsyncCallbackInfo, &networkIdAsyncCallbackInfo->asyncWork);
2975     napi_queue_async_work_with_qos(env, networkIdAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
2976 }
2977 
GetDeviceInfoCB(napi_env env,void * data)2978 void DeviceManagerNapi::GetDeviceInfoCB(napi_env env, void *data)
2979 {
2980     if (!data) {
2981         LOGE("Invalid async callback data");
2982         return;
2983     }
2984     (void)env;
2985     NetworkIdAsyncCallbackInfo *networkIdAsyncCallbackInfo = reinterpret_cast<NetworkIdAsyncCallbackInfo *>(data);
2986     int32_t ret = DeviceManager::GetInstance().GetDeviceInfo(networkIdAsyncCallbackInfo->bundleName,
2987                                                              networkIdAsyncCallbackInfo->networkId,
2988                                                              networkIdAsyncCallbackInfo->deviceInfo);
2989     if (ret != 0) {
2990         LOGE("GetDeviceInfoCB for bundleName %{public}s networkId %{public}s failed, ret %{public}d",
2991              networkIdAsyncCallbackInfo->bundleName.c_str(),
2992              GetAnonyString(networkIdAsyncCallbackInfo->networkId).c_str(), ret);
2993         networkIdAsyncCallbackInfo->status = -1;
2994         networkIdAsyncCallbackInfo->ret = ret;
2995     } else {
2996         networkIdAsyncCallbackInfo->status = 0;
2997         LOGI("GetDeviceInfoCB status %{public}d", networkIdAsyncCallbackInfo->status);
2998     }
2999 }
3000 
CompleteGetDeviceInfoCB(napi_env env,napi_status status,void * data)3001 void DeviceManagerNapi::CompleteGetDeviceInfoCB(napi_env env, napi_status status, void *data)
3002 {
3003     if (!data) {
3004         LOGE("Invalid async callback data");
3005         return;
3006     }
3007     (void)status;
3008     NetworkIdAsyncCallbackInfo *networkIdAsyncCallbackInfo = reinterpret_cast<NetworkIdAsyncCallbackInfo *>(data);
3009     if (networkIdAsyncCallbackInfo->deferred != nullptr) {
3010         CallGetDeviceInfoPromise(env, status, networkIdAsyncCallbackInfo);    // promise
3011     } else {
3012         CallGetDeviceInfoCB(env, status, networkIdAsyncCallbackInfo);         // callback
3013     }
3014     napi_delete_async_work(env, networkIdAsyncCallbackInfo->asyncWork);
3015     delete networkIdAsyncCallbackInfo;
3016 }
3017 
3018 // promise function
CallGetDeviceInfoPromise(napi_env env,napi_status & status,NetworkIdAsyncCallbackInfo * networkIdAsyncCallbackInfo)3019 void DeviceManagerNapi::CallGetDeviceInfoPromise(napi_env env, napi_status &status,
3020                                                  NetworkIdAsyncCallbackInfo *networkIdAsyncCallbackInfo)
3021 {
3022     napi_value result[DM_NAPI_ARGS_TWO] = {0};
3023 
3024     LOGI("DeviceManager::CallGetDeviceInfoSync deviceName:%{public}s deviceTypeId:%{public}d ",
3025          GetAnonyString(networkIdAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
3026          networkIdAsyncCallbackInfo->deviceInfo.deviceTypeId);
3027 
3028     if (networkIdAsyncCallbackInfo->status == 0) {
3029         DeviceInfotoJsByNetworkId(env, networkIdAsyncCallbackInfo->deviceInfo, result[1]);
3030         napi_resolve_deferred(env, networkIdAsyncCallbackInfo->deferred, result[1]);
3031     } else {
3032         result[0] = CreateBusinessError(env, networkIdAsyncCallbackInfo->ret, false);
3033         napi_reject_deferred(env, networkIdAsyncCallbackInfo->deferred, result[0]);
3034     }
3035 }
3036 
3037 // callback function
CallGetDeviceInfoCB(napi_env env,napi_status & status,NetworkIdAsyncCallbackInfo * networkIdAsyncCallbackInfo)3038 void DeviceManagerNapi::CallGetDeviceInfoCB(napi_env env, napi_status &status,
3039                                             NetworkIdAsyncCallbackInfo *networkIdAsyncCallbackInfo)
3040 {
3041     napi_value result[DM_NAPI_ARGS_TWO] = {0};
3042     LOGI("DeviceManager::CallGetDeviceInfo deviceName:%{public}s deviceTypeId:%{public}d ",
3043          GetAnonyString(networkIdAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
3044          networkIdAsyncCallbackInfo->deviceInfo.deviceTypeId);
3045     napi_value callResult = nullptr;
3046     napi_value handler = nullptr;
3047 
3048     if (networkIdAsyncCallbackInfo->status == 0) {
3049         DeviceInfotoJsByNetworkId(env, networkIdAsyncCallbackInfo->deviceInfo, result[1]);
3050     } else {
3051         result[0] = CreateBusinessError(env, networkIdAsyncCallbackInfo->ret, false);
3052     }
3053 
3054     napi_get_reference_value(env, networkIdAsyncCallbackInfo->callback, &handler);
3055     if (handler != nullptr) {
3056         napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO, &result[0], &callResult);
3057         napi_delete_reference(env, networkIdAsyncCallbackInfo->callback);
3058     } else {
3059         LOGE("handler is nullptr");
3060     }
3061 }
3062 
DeviceInfotoJsByNetworkId(const napi_env & env,const DmDeviceInfo & nidDevInfo,napi_value & result)3063 void DeviceManagerNapi::DeviceInfotoJsByNetworkId(const napi_env &env, const DmDeviceInfo &nidDevInfo,
3064                                                   napi_value &result)
3065 {
3066     napi_create_object(env, &result);
3067 
3068     SetValueUtf8String(env, "deviceName", nidDevInfo.deviceName, result);
3069     SetValueInt32(env, "deviceType", (int)nidDevInfo.deviceTypeId, result);
3070 }
3071 
JsToStringAndCheck(napi_env env,napi_value value,const std::string & valueName,std::string & strValue)3072 bool DeviceManagerNapi::JsToStringAndCheck(napi_env env, napi_value value, const std::string &valueName,
3073                                            std::string &strValue)
3074 {
3075     napi_valuetype deviceIdType = napi_undefined;
3076     napi_typeof(env, value, &deviceIdType);
3077     if (!CheckArgsType(env, deviceIdType == napi_string, valueName, "string")) {
3078         return false;
3079     }
3080     size_t valueLen = 0;
3081     napi_get_value_string_utf8(env, value, nullptr, 0, &valueLen);
3082     if (!CheckArgsVal(env, valueLen > 0, valueName, "len == 0")) {
3083         return false;
3084     }
3085     if (!CheckArgsVal(env, valueLen < DM_NAPI_BUF_LENGTH, valueName, "len >= MAXLEN")) {
3086         return false;
3087     }
3088     char temp[DM_NAPI_BUF_LENGTH] = {0};
3089     napi_get_value_string_utf8(env, value, temp, valueLen + 1, &valueLen);
3090     strValue = temp;
3091     return true;
3092 }
3093 
GetDeviceInfo(napi_env env,napi_callback_info info)3094 napi_value DeviceManagerNapi::GetDeviceInfo(napi_env env, napi_callback_info info)
3095 {
3096     if (!IsSystemApp()) {
3097         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
3098         return nullptr;
3099     }
3100     napi_value result = nullptr;
3101     size_t argc = 2;
3102     napi_value argv[2] = {nullptr};
3103     napi_value thisVar = nullptr;
3104     DmDeviceInfo deviceInfo;
3105     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
3106     NAPI_ASSERT(env, ((argc >= DM_NAPI_ARGS_ONE) && (argc <= DM_NAPI_ARGS_TWO)), "requires 1 or 2 parameter");
3107 
3108     std::string networkId;
3109     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
3110         return nullptr;
3111     }
3112     DeviceManagerNapi *deviceManagerWrapper = nullptr;
3113     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
3114         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
3115         return result;
3116     }
3117     auto *networkIdAsyncCallbackInfo = new NetworkIdAsyncCallbackInfo();
3118     networkIdAsyncCallbackInfo->env = env;
3119     networkIdAsyncCallbackInfo->deviceInfo = deviceInfo;
3120     networkIdAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
3121     networkIdAsyncCallbackInfo->networkId = networkId;
3122 
3123     if (argc == DM_NAPI_ARGS_ONE) {    // promise
3124         napi_deferred deferred;
3125         napi_value promise = 0;
3126         napi_create_promise(env, &deferred, &promise);
3127         networkIdAsyncCallbackInfo->deferred = deferred;
3128         CallGetDeviceInfo(env, networkIdAsyncCallbackInfo);
3129         return promise;
3130     } else if (argc == DM_NAPI_ARGS_TWO) {    // callback
3131         if (!IsFunctionType(env, argv[1])) {
3132             delete networkIdAsyncCallbackInfo;
3133             networkIdAsyncCallbackInfo = nullptr;
3134             return nullptr;
3135         }
3136         napi_create_reference(env, argv[1], 1, &networkIdAsyncCallbackInfo->callback);
3137         CallGetDeviceInfo(env, networkIdAsyncCallbackInfo);
3138     }
3139     napi_get_undefined(env, &result);
3140     return result;
3141 }
CreateDeviceManager(napi_env env,napi_callback_info info)3142 napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info)
3143 {
3144     LOGI("CreateDeviceManager in");
3145     if (!IsSystemApp()) {
3146         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
3147         return nullptr;
3148     }
3149     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
3150 
3151     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
3152         return nullptr;
3153     }
3154 
3155     napi_valuetype bundleNameValueType = napi_undefined;
3156     napi_typeof(env, argv[0], &bundleNameValueType);
3157     if (!CheckArgsType(env, bundleNameValueType == napi_string, "bundleName", "string")) {
3158         return nullptr;
3159     }
3160 
3161     napi_valuetype funcValueType = napi_undefined;
3162     napi_typeof(env, argv[1], &funcValueType);
3163     if (!CheckArgsType(env, funcValueType == napi_function, "callback", "function")) {
3164         return nullptr;
3165     }
3166 
3167     auto *asCallbackInfo = new AsyncCallbackInfo();
3168     if (asCallbackInfo == nullptr) {
3169         return nullptr;
3170     }
3171     asCallbackInfo->env = env;
3172     napi_get_value_string_utf8(env, argv[0], asCallbackInfo->bundleName, DM_NAPI_BUF_LENGTH - 1,
3173                                &asCallbackInfo->bundleNameLen);
3174 
3175     napi_create_reference(env, argv[1], 1, &asCallbackInfo->callback);
3176 
3177     HandleCreateDmCallBack(env, asCallbackInfo);
3178 
3179     napi_value result = nullptr;
3180     napi_get_undefined(env, &result);
3181     return result;
3182 }
3183 
Constructor(napi_env env,napi_callback_info info)3184 napi_value DeviceManagerNapi::Constructor(napi_env env, napi_callback_info info)
3185 {
3186     LOGI("DeviceManagerNapi Constructor in");
3187     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
3188     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
3189         return nullptr;
3190     }
3191 
3192     napi_valuetype valueType = napi_undefined;
3193     napi_typeof(env, argv[0], &valueType);
3194     if (!CheckArgsType(env, valueType == napi_string, "bundleName", "string")) {
3195         return nullptr;
3196     }
3197 
3198     char bundleName[DM_NAPI_BUF_LENGTH] = {0};
3199     size_t typeLen = 0;
3200     napi_get_value_string_utf8(env, argv[0], bundleName, sizeof(bundleName), &typeLen);
3201 
3202     LOGI("create DeviceManagerNapi for packageName:%{public}s", bundleName);
3203     DeviceManagerNapi *obj = new DeviceManagerNapi(env, thisVar);
3204     if (obj == nullptr) {
3205         return nullptr;
3206     }
3207 
3208     obj->bundleName_ = std::string(bundleName);
3209     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
3210     g_deviceManagerMap[obj->bundleName_] = obj;
3211     napi_wrap(
3212         env, thisVar, reinterpret_cast<void *>(obj),
3213         [](napi_env env, void *data, void *hint) {
3214             (void)env;
3215             (void)hint;
3216             DeviceManagerNapi *deviceManager = reinterpret_cast<DeviceManagerNapi *>(data);
3217             delete deviceManager;
3218             deviceManager = nullptr;
3219             LOGI("delete deviceManager");
3220         },
3221         nullptr, nullptr);
3222     return thisVar;
3223 }
3224 
Init(napi_env env,napi_value exports)3225 napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports)
3226 {
3227     napi_value dmClass = nullptr;
3228     napi_property_descriptor dmProperties[] = {
3229         DECLARE_NAPI_FUNCTION("release", ReleaseDeviceManager),
3230         DECLARE_NAPI_FUNCTION("getTrustedDeviceListSync", GetTrustedDeviceListSync),
3231         DECLARE_NAPI_FUNCTION("getTrustedDeviceList", GetTrustedDeviceList),
3232         DECLARE_NAPI_FUNCTION("startDeviceDiscovery", StartDeviceDiscoverSync),
3233         DECLARE_NAPI_FUNCTION("stopDeviceDiscovery", StopDeviceDiscoverSync),
3234         DECLARE_NAPI_FUNCTION("publishDeviceDiscovery", PublishDeviceDiscoverySync),
3235         DECLARE_NAPI_FUNCTION("unPublishDeviceDiscovery", UnPublishDeviceDiscoverySync),
3236         DECLARE_NAPI_FUNCTION("getLocalDeviceInfoSync", GetLocalDeviceInfoSync),
3237         DECLARE_NAPI_FUNCTION("getLocalDeviceInfo", GetLocalDeviceInfo),
3238         DECLARE_NAPI_FUNCTION("getDeviceInfo", GetDeviceInfo),
3239         DECLARE_NAPI_FUNCTION("unAuthenticateDevice", UnAuthenticateDevice),
3240         DECLARE_NAPI_FUNCTION("authenticateDevice", AuthenticateDevice),
3241         DECLARE_NAPI_FUNCTION("setUserOperation", SetUserOperationSync),
3242         DECLARE_NAPI_FUNCTION("requestCredentialRegisterInfo", RequestCredential),
3243         DECLARE_NAPI_FUNCTION("importCredential", ImportCredential),
3244         DECLARE_NAPI_FUNCTION("deleteCredential", DeleteCredential),
3245         DECLARE_NAPI_FUNCTION("on", JsOn),
3246         DECLARE_NAPI_FUNCTION("off", JsOff)};
3247 
3248     napi_property_descriptor static_prop[] = {
3249         DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager),
3250     };
3251 
3252     LOGI("DeviceManagerNapi::Init() is called!");
3253     NAPI_CALL(env, napi_define_class(env, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor,
3254                                      nullptr, sizeof(dmProperties) / sizeof(dmProperties[0]), dmProperties, &dmClass));
3255     NAPI_CALL(env, napi_create_reference(env, dmClass, 1, &sConstructor_));
3256     NAPI_CALL(env, napi_set_named_property(env, exports, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), dmClass));
3257     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop));
3258     LOGI("All props and functions are configured..");
3259     return exports;
3260 }
3261 
EnumTypeConstructor(napi_env env,napi_callback_info info)3262 napi_value DeviceManagerNapi::EnumTypeConstructor(napi_env env, napi_callback_info info)
3263 {
3264     size_t argc = 0;
3265     napi_value res = nullptr;
3266     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &res, nullptr));
3267     return res;
3268 }
3269 
InitDeviceTypeEnum(napi_env env,napi_value exports)3270 napi_value DeviceManagerNapi::InitDeviceTypeEnum(napi_env env, napi_value exports)
3271 {
3272     napi_value unknown_type;
3273     napi_value speaker;
3274     napi_value phone;
3275     napi_value tablet;
3276     napi_value wearable;
3277     napi_value car;
3278     napi_value tv;
3279     int32_t refCount = 1;
3280 
3281     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_UNKNOWN),
3282         &unknown_type);
3283     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_AUDIO),
3284         &speaker);
3285     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_PHONE),
3286         &phone);
3287     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_PAD),
3288         &tablet);
3289     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_WATCH),
3290         &wearable);
3291     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_CAR),
3292         &car);
3293     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_TV),
3294         &tv);
3295 
3296     napi_property_descriptor desc[] = {
3297         DECLARE_NAPI_STATIC_PROPERTY("UNKNOWN_TYPE", unknown_type),
3298         DECLARE_NAPI_STATIC_PROPERTY("SPEAKER", speaker),
3299         DECLARE_NAPI_STATIC_PROPERTY("PHONE", phone),
3300         DECLARE_NAPI_STATIC_PROPERTY("TABLET", tablet),
3301         DECLARE_NAPI_STATIC_PROPERTY("WEARABLE", wearable),
3302         DECLARE_NAPI_STATIC_PROPERTY("CAR", car),
3303         DECLARE_NAPI_STATIC_PROPERTY("TV", tv),
3304     };
3305 
3306     napi_value result = nullptr;
3307     napi_define_class(env, "DeviceType", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3308         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3309     napi_create_reference(env, result, refCount, &deviceTypeEnumConstructor_);
3310     napi_set_named_property(env, exports, "DeviceType", result);
3311     return exports;
3312 }
3313 
InitDeviceStateChangeActionEnum(napi_env env,napi_value exports)3314 napi_value DeviceManagerNapi::InitDeviceStateChangeActionEnum(napi_env env, napi_value exports)
3315 {
3316     napi_value device_state_online;
3317     napi_value device_state_ready;
3318     napi_value device_state_offline;
3319     napi_value device_state_change;
3320     int32_t refCount = 1;
3321 
3322     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_ONLINE),
3323         &device_state_online);
3324     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_READY),
3325         &device_state_ready);
3326     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_OFFLINE),
3327         &device_state_offline);
3328     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_CHANGED),
3329         &device_state_change);
3330 
3331     napi_property_descriptor desc[] = {
3332         DECLARE_NAPI_STATIC_PROPERTY("ONLINE", device_state_online),
3333         DECLARE_NAPI_STATIC_PROPERTY("READY", device_state_ready),
3334         DECLARE_NAPI_STATIC_PROPERTY("OFFLINE", device_state_offline),
3335         DECLARE_NAPI_STATIC_PROPERTY("CHANGE", device_state_change),
3336     };
3337 
3338     napi_value result = nullptr;
3339     napi_define_class(env, "DeviceStateChangeAction", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3340         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3341     napi_create_reference(env, result, refCount, &deviceStateChangeActionEnumConstructor_);
3342     napi_set_named_property(env, exports, "DeviceStateChangeAction", result);
3343     return exports;
3344 }
3345 
InitDiscoverModeEnum(napi_env env,napi_value exports)3346 napi_value DeviceManagerNapi::InitDiscoverModeEnum(napi_env env, napi_value exports)
3347 {
3348     napi_value discover_mode_passive;
3349     napi_value discover_mode_active;
3350     int32_t refCount = 1;
3351 
3352     napi_create_uint32(env, static_cast<uint32_t>(DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE),
3353         &discover_mode_passive);
3354     napi_create_uint32(env, static_cast<uint32_t>(DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE),
3355         &discover_mode_active);
3356 
3357     napi_property_descriptor desc[] = {
3358         DECLARE_NAPI_STATIC_PROPERTY("DISCOVER_MODE_PASSIVE", discover_mode_passive),
3359         DECLARE_NAPI_STATIC_PROPERTY("DISCOVER_MODE_ACTIVE", discover_mode_active),
3360     };
3361 
3362     napi_value result = nullptr;
3363     napi_define_class(env, "DiscoverMode", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3364         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3365     napi_create_reference(env, result, refCount, &discoverModeEnumConstructor_);
3366     napi_set_named_property(env, exports, "DiscoverMode", result);
3367     return exports;
3368 }
3369 
InitExchangeMediumEnum(napi_env env,napi_value exports)3370 napi_value DeviceManagerNapi::InitExchangeMediumEnum(napi_env env, napi_value exports)
3371 {
3372     napi_value medium_auto;
3373     napi_value medium_ble;
3374     napi_value medium_coap;
3375     napi_value medium_usb;
3376     int32_t refCount = 1;
3377 
3378     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_AUTO),
3379         &medium_auto);
3380     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_BLE),
3381         &medium_ble);
3382     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_COAP),
3383         &medium_coap);
3384     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_USB),
3385         &medium_usb);
3386 
3387     napi_property_descriptor desc[] = {
3388         DECLARE_NAPI_STATIC_PROPERTY("AUTO", medium_auto),
3389         DECLARE_NAPI_STATIC_PROPERTY("BLE", medium_ble),
3390         DECLARE_NAPI_STATIC_PROPERTY("COAP", medium_coap),
3391         DECLARE_NAPI_STATIC_PROPERTY("USB", medium_usb),
3392     };
3393 
3394     napi_value result = nullptr;
3395     napi_define_class(env, "ExchangeMedium", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3396         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3397     napi_create_reference(env, result, refCount, &exchangeMediumEnumConstructor_);
3398     napi_set_named_property(env, exports, "ExchangeMedium", result);
3399     return exports;
3400 }
3401 
InitExchangeFreqEnum(napi_env env,napi_value exports)3402 napi_value DeviceManagerNapi::InitExchangeFreqEnum(napi_env env, napi_value exports)
3403 {
3404     napi_value low;
3405     napi_value mid;
3406     napi_value high;
3407     napi_value super_high;
3408     int32_t refCount = 1;
3409 
3410     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_LOW),
3411         &low);
3412     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_MID),
3413         &mid);
3414     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_HIGH),
3415         &high);
3416     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_SUPER_HIGH),
3417         &super_high);
3418 
3419     napi_property_descriptor desc[] = {
3420         DECLARE_NAPI_STATIC_PROPERTY("LOW", low),
3421         DECLARE_NAPI_STATIC_PROPERTY("MID", mid),
3422         DECLARE_NAPI_STATIC_PROPERTY("HIGH", high),
3423         DECLARE_NAPI_STATIC_PROPERTY("SUPER_HIGH", super_high),
3424     };
3425 
3426     napi_value result = nullptr;
3427     napi_define_class(env, "ExchangeFreq", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3428         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3429     napi_create_reference(env, result, refCount, &exchangeFreqEnumConstructor_);
3430     napi_set_named_property(env, exports, "ExchangeFreq", result);
3431     return exports;
3432 }
3433 
InitSubscribeCapEnum(napi_env env,napi_value exports)3434 napi_value DeviceManagerNapi::InitSubscribeCapEnum(napi_env env, napi_value exports)
3435 {
3436     napi_value subscribe_capability_ddmp;
3437     napi_value subscribe_capability_osd;
3438     int32_t refCount = 1;
3439 
3440     napi_create_uint32(env, static_cast<uint32_t>(DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP),
3441         &subscribe_capability_ddmp);
3442     napi_create_uint32(env, static_cast<uint32_t>(DM_NAPI_SUBSCRIBE_CAPABILITY_OSD),
3443         &subscribe_capability_osd);
3444 
3445     napi_property_descriptor desc[] = {
3446         DECLARE_NAPI_STATIC_PROPERTY("SUBSCRIBE_CAPABILITY_DDMP", subscribe_capability_ddmp),
3447         DECLARE_NAPI_STATIC_PROPERTY("SUBSCRIBE_CAPABILITY_OSD", subscribe_capability_osd),
3448     };
3449 
3450     napi_value result = nullptr;
3451     napi_define_class(env, "SubscribeCap", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3452         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3453     napi_create_reference(env, result, refCount, &subscribeCapEnumConstructor_);
3454     napi_set_named_property(env, exports, "SubscribeCap", result);
3455     return exports;
3456 }
3457 
3458 /*
3459  * Function registering all props and functions of ohos.distributedhardware
3460  */
Export(napi_env env,napi_value exports)3461 static napi_value Export(napi_env env, napi_value exports)
3462 {
3463     LOGI("Export() is called!");
3464     DeviceManagerNapi::Init(env, exports);
3465     DeviceManagerNapi::InitDeviceTypeEnum(env, exports);
3466     DeviceManagerNapi::InitDeviceStateChangeActionEnum(env, exports);
3467     DeviceManagerNapi::InitDiscoverModeEnum(env, exports);
3468     DeviceManagerNapi::InitExchangeMediumEnum(env, exports);
3469     DeviceManagerNapi::InitExchangeFreqEnum(env, exports);
3470     DeviceManagerNapi::InitSubscribeCapEnum(env, exports);
3471     return exports;
3472 }
3473 
3474 /*
3475  * module define
3476  */
3477 static napi_module g_dmModule = {.nm_version = 1,
3478                                  .nm_flags = 0,
3479                                  .nm_filename = nullptr,
3480                                  .nm_register_func = Export,
3481                                  .nm_modname = "distributedHardware.deviceManager",
3482                                  .nm_priv = ((void *)0),
3483                                  .reserved = {0}};
3484 
3485 /*
3486  * module register
3487  */
RegisterModule(void)3488 extern "C" __attribute__((constructor)) void RegisterModule(void)
3489 {
3490     LOGI("RegisterModule() is called!");
3491     napi_module_register(&g_dmModule);
3492 }
3493