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