• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "native_devicemanager_js.h"
17 #include <uv.h>
18 #include "device_manager.h"
19 #include "dm_constants.h"
20 #include "dm_device_info.h"
21 #include "dm_log.h"
22 #include "ipc_skeleton.h"
23 #include "js_native_api.h"
24 #include "tokenid_kit.h"
25 #include "json_object.h"
26 
27 using namespace OHOS::DistributedHardware;
28 
29 namespace {
30 #define GET_PARAMS(env, info, num)    \
31     size_t argc = num;                \
32     napi_value argv[num] = {nullptr}; \
33     napi_value thisVar = nullptr;     \
34     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr))
35 
36 const std::string DM_NAPI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange";
37 const std::string DM_NAPI_EVENT_DEVICE_FOUND = "deviceFound";
38 const std::string DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL = "discoveryFail";
39 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS = "publishSuccess";
40 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL = "publishFail";
41 const std::string DM_NAPI_EVENT_DEVICE_SERVICE_DIE = "serviceDie";
42 const std::string DEVICE_MANAGER_NAPI_CLASS_NAME = "DeviceManager";
43 const std::string DM_NAPI_EVENT_UI_STATE_CHANGE = "uiStateChange";
44 
45 const int32_t DM_NAPI_ARGS_ZERO = 0;
46 const int32_t DM_NAPI_ARGS_ONE = 1;
47 const int32_t DM_NAPI_ARGS_TWO = 2;
48 const int32_t DM_NAPI_ARGS_THREE = 3;
49 const int32_t DM_NAPI_SUB_ID_MAX = 65535;
50 const int32_t DM_AUTH_DIRECTION_CLIENT = 1;
51 const int32_t DM_AUTH_REQUEST_SUCCESS_STATUS = 7;
52 
53 const int32_t DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP = 0;
54 const int32_t DM_NAPI_SUBSCRIBE_CAPABILITY_OSD = 1;
55 constexpr int32_t DM_MAX_DEVICE_SIZE = 100;
56 
57 napi_ref deviceTypeEnumConstructor_ = nullptr;
58 napi_ref deviceStateChangeActionEnumConstructor_ = nullptr;
59 napi_ref discoverModeEnumConstructor_ = nullptr;
60 napi_ref exchangeMediumEnumConstructor_ = nullptr;
61 napi_ref exchangeFreqEnumConstructor_ = nullptr;
62 napi_ref subscribeCapEnumConstructor_ = nullptr;
63 
64 std::map<std::string, DeviceManagerNapi *> g_deviceManagerMap;
65 std::map<std::string, std::shared_ptr<DmNapiInitCallback>> g_initCallbackMap;
66 std::map<std::string, std::shared_ptr<DmNapiDeviceStateCallback>> g_deviceStateCallbackMap;
67 std::map<std::string, std::shared_ptr<DmNapiDiscoveryCallback>> g_DiscoveryCallbackMap;
68 std::map<std::string, std::shared_ptr<DmNapiPublishCallback>> g_publishCallbackMap;
69 std::map<std::string, std::shared_ptr<DmNapiAuthenticateCallback>> g_authCallbackMap;
70 std::map<std::string, std::shared_ptr<DmNapiDeviceManagerUiCallback>> g_dmUiCallbackMap;
71 std::map<std::string, std::shared_ptr<DmNapiCredentialCallback>> g_creCallbackMap;
72 
73 std::mutex g_deviceManagerMapMutex;
74 std::mutex g_initCallbackMapMutex;
75 std::mutex g_deviceStateCallbackMapMutex;
76 std::mutex g_discoveryCallbackMapMutex;
77 std::mutex g_publishCallbackMapMutex;
78 std::mutex g_authCallbackMapMutex;
79 std::mutex g_dmUiCallbackMapMutex;
80 
81 enum class DMBussinessErrorCode : int32_t {
82     // Permission verify failed.
83     ERR_NO_PERMISSION = 201,
84     // The caller is not a system application.
85     ERR_NOT_SYSTEM_APP = 202,
86     // Input parameter error.
87     ERR_INVALID_PARAMS = 401,
88     // Failed to execute the function.
89     DM_ERR_FAILED = 11600101,
90     // Failed to obtain the service.
91     DM_ERR_OBTAIN_SERVICE = 11600102,
92     // Authentication invalid.
93     DM_ERR_AUTHENTICALTION_INVALID = 11600103,
94     // Discovery invalid.
95     DM_ERR_DISCOVERY_INVALID = 11600104,
96     // Publish invalid.
97     DM_ERR_PUBLISH_INVALID = 11600105,
98 };
99 
100 const std::string ERR_MESSAGE_NO_PERMISSION = "Permission verify failed.";
101 const std::string ERR_MESSAGE_NOT_SYSTEM_APP = "The caller is not a system application.";
102 const std::string ERR_MESSAGE_INVALID_PARAMS = "Input parameter error.";
103 const std::string ERR_MESSAGE_FAILED = "Failed to execute the function.";
104 const std::string ERR_MESSAGE_OBTAIN_SERVICE = "Failed to obtain the service.";
105 const std::string ERR_MESSAGE_AUTHENTICALTION_INVALID = "Authentication invalid.";
106 const std::string ERR_MESSAGE_DISCOVERY_INVALID = "Discovery invalid.";
107 const std::string ERR_MESSAGE_PUBLISH_INVALID = "Publish invalid.";
108 
GenerateBusinessError(napi_env env,int32_t err,const std::string & msg)109 napi_value GenerateBusinessError(napi_env env, int32_t err, const std::string &msg)
110 {
111     napi_value businessError = nullptr;
112     NAPI_CALL(env, napi_create_object(env, &businessError));
113     napi_value errorCode = nullptr;
114     NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
115     napi_value errorMessage = nullptr;
116     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
117     NAPI_CALL(env, napi_set_named_property(env, businessError, "code", errorCode));
118     NAPI_CALL(env, napi_set_named_property(env, businessError, "message", errorMessage));
119 
120     return businessError;
121 }
122 
CheckArgsVal(napi_env env,bool assertion,const std::string & param,const std::string & msg)123 bool CheckArgsVal(napi_env env, bool assertion, const std::string &param, const std::string &msg)
124 {
125     if (!(assertion)) {
126         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The value of " + param + ": " + msg;
127         napi_throw_error(env, std::to_string(
128             static_cast<int32_t>(DMBussinessErrorCode::ERR_INVALID_PARAMS)).c_str(), errMsg.c_str());
129         return false;
130     }
131     return true;
132 }
133 
CheckArgsCount(napi_env env,bool assertion,const std::string & message)134 bool CheckArgsCount(napi_env env, bool assertion, const std::string &message)
135 {
136     if (!(assertion)) {
137         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + message;
138         napi_throw_error(env, std::to_string(
139             static_cast<int32_t>(DMBussinessErrorCode::ERR_INVALID_PARAMS)).c_str(), errMsg.c_str());
140         return false;
141     }
142     return true;
143 }
144 
CheckArgsType(napi_env env,bool assertion,const std::string & paramName,const std::string & type)145 bool CheckArgsType(napi_env env, bool assertion, const std::string &paramName, const std::string &type)
146 {
147     if (!(assertion)) {
148         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The type of " + paramName +
149                 " must be " + type;
150         napi_throw_error(env, std::to_string(
151             static_cast<int32_t>(DMBussinessErrorCode::ERR_INVALID_PARAMS)).c_str(), errMsg.c_str());
152         return false;
153     }
154     return true;
155 }
156 
CreateErrorForCall(napi_env env,int32_t code,const std::string & errMsg,bool isAsync=true)157 napi_value CreateErrorForCall(napi_env env, int32_t code, const std::string &errMsg, bool isAsync = true)
158 {
159     LOGI("CreateErrorForCall code:%{public}d, message:%{public}s", code, errMsg.c_str());
160     napi_value error = nullptr;
161     if (isAsync) {
162         napi_throw_error(env, std::to_string(code).c_str(), errMsg.c_str());
163     } else {
164         error = GenerateBusinessError(env, code, errMsg);
165     }
166     return error;
167 }
168 
CreateBusinessError(napi_env env,int32_t errCode,bool isAsync=true)169 napi_value CreateBusinessError(napi_env env, int32_t errCode, bool isAsync = true)
170 {
171     napi_value error = nullptr;
172     switch (errCode) {
173         case ERR_DM_NO_PERMISSION:
174             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NO_PERMISSION),
175                 ERR_MESSAGE_NO_PERMISSION, isAsync);
176             break;
177         case ERR_DM_DISCOVERY_REPEATED:
178             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::DM_ERR_DISCOVERY_INVALID),
179                 ERR_MESSAGE_DISCOVERY_INVALID, isAsync);
180             break;
181         case ERR_DM_PUBLISH_REPEATED:
182             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::DM_ERR_PUBLISH_INVALID),
183                 ERR_MESSAGE_PUBLISH_INVALID, isAsync);
184             break;
185         case ERR_DM_AUTH_BUSINESS_BUSY:
186             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::DM_ERR_AUTHENTICALTION_INVALID),
187                 ERR_MESSAGE_AUTHENTICALTION_INVALID, isAsync);
188             break;
189         case ERR_DM_INPUT_PARA_INVALID:
190         case ERR_DM_UNSUPPORTED_AUTH_TYPE:
191             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_INVALID_PARAMS),
192                 ERR_MESSAGE_INVALID_PARAMS, isAsync);
193             break;
194         case ERR_DM_INIT_FAILED:
195             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::DM_ERR_OBTAIN_SERVICE),
196                 ERR_MESSAGE_OBTAIN_SERVICE, isAsync);
197             break;
198         case ERR_DM_NOT_SYSTEM_APP:
199             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP),
200                 ERR_MESSAGE_NOT_SYSTEM_APP, isAsync);
201             break;
202         default:
203             error = CreateErrorForCall(env, static_cast<int32_t>(DMBussinessErrorCode::DM_ERR_FAILED),
204                 ERR_MESSAGE_FAILED, isAsync);
205             break;
206     }
207     return error;
208 }
209 
DeleteUvWork(uv_work_t * work)210 void DeleteUvWork(uv_work_t *work)
211 {
212     if (work == nullptr) {
213         return;
214     }
215     delete work;
216     work = nullptr;
217     LOGI("delete work!");
218 }
219 
DeleteDmNapiStateJsCallbackPtr(DmNapiStateJsCallback * pJsCallbackPtr)220 void DeleteDmNapiStateJsCallbackPtr(DmNapiStateJsCallback *pJsCallbackPtr)
221 {
222     if (pJsCallbackPtr == nullptr) {
223         return;
224     }
225     delete pJsCallbackPtr;
226     pJsCallbackPtr = nullptr;
227     LOGI("delete DmNapiStateJsCallback callbackPtr!");
228 }
229 
DeleteAsyncCallbackInfo(DeviceInfoListAsyncCallbackInfo * pAsynCallbackInfo)230 void DeleteAsyncCallbackInfo(DeviceInfoListAsyncCallbackInfo *pAsynCallbackInfo)
231 {
232     if (pAsynCallbackInfo == nullptr) {
233         return;
234     }
235     delete pAsynCallbackInfo;
236     pAsynCallbackInfo = nullptr;
237 }
238 
IsJSObjectType(napi_env env,napi_value value,const std::string & param)239 bool IsJSObjectType(napi_env env, napi_value value, const std::string &param)
240 {
241     napi_valuetype authparamType = napi_undefined;
242     napi_typeof(env, value, &authparamType);
243     return CheckArgsType(env, authparamType == napi_object, param, "object");
244 }
245 
IsFunctionType(napi_env env,napi_value value)246 bool IsFunctionType(napi_env env, napi_value value)
247 {
248     napi_valuetype eventHandleType = napi_undefined;
249     napi_typeof(env, value, &eventHandleType);
250     return CheckArgsType(env, eventHandleType == napi_function, "callback", "function");
251 }
252 
IsDeviceManagerNapiNull(napi_env env,napi_value thisVar,DeviceManagerNapi ** pDeviceManagerWrapper)253 bool IsDeviceManagerNapiNull(napi_env env, napi_value thisVar, DeviceManagerNapi **pDeviceManagerWrapper)
254 {
255     napi_unwrap(env, thisVar, reinterpret_cast<void **>(pDeviceManagerWrapper));
256     if (pDeviceManagerWrapper != nullptr && *pDeviceManagerWrapper != nullptr) {
257         return false;
258     }
259     CreateBusinessError(env, ERR_DM_POINT_NULL);
260     LOGE(" DeviceManagerNapi object is nullptr!");
261     return true;
262 }
263 } // namespace
264 
265 thread_local napi_ref DeviceManagerNapi::sConstructor_ = nullptr;
266 AuthAsyncCallbackInfo DeviceManagerNapi::authAsyncCallbackInfo_;
267 CredentialAsyncCallbackInfo DeviceManagerNapi::creAsyncCallbackInfo_;
268 std::mutex DeviceManagerNapi::creMapLocks_;
269 
OnRemoteDied()270 void DmNapiInitCallback::OnRemoteDied()
271 {
272     uv_loop_s *loop = nullptr;
273     napi_get_uv_event_loop(env_, &loop);
274     if (loop == nullptr) {
275         return;
276     }
277     uv_work_t *work = new (std::nothrow) uv_work_t;
278     if (work == nullptr) {
279         LOGE("DmNapiInitCallback: OnRemoteDied, No memory");
280         return;
281     }
282 
283     DmDeviceInfo info;
284     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, info);
285     if (jsCallback == nullptr) {
286         DeleteUvWork(work);
287         return;
288     }
289     work->data = reinterpret_cast<void *>(jsCallback);
290 
291     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
292         LOGD("OnRemoteDied uv_queue_work_with_qos");
293     }, [] (uv_work_t *work, int status) {
294         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
295         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
296         if (deviceManagerNapi == nullptr) {
297             LOGE("OnRemoteDied, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
298         } else {
299             deviceManagerNapi->OnEvent("serviceDie", 0, nullptr);
300         }
301         LOGI("OnRemoteDied, deviceManagerNapi bundleName %{public}s", callback->bundleName_.c_str());
302         DeleteDmNapiStateJsCallbackPtr(callback);
303         DeleteUvWork(work);
304     }, uv_qos_user_initiated);
305     if (ret != 0) {
306         LOGE("Failed to execute OnRemoteDied work queue");
307         DeleteDmNapiStateJsCallbackPtr(jsCallback);
308         DeleteUvWork(work);
309     }
310 }
311 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)312 void DmNapiDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
313 {
314     uv_loop_s *loop = nullptr;
315     napi_get_uv_event_loop(env_, &loop);
316     if (loop == nullptr) {
317         return;
318     }
319     uv_work_t *work = new (std::nothrow) uv_work_t;
320     if (work == nullptr) {
321         LOGE("DmNapiDeviceStateCallback: OnDeviceOnline, No memory");
322         return;
323     }
324 
325     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
326     if (jsCallback == nullptr) {
327         DeleteUvWork(work);
328         return;
329     }
330     work->data = reinterpret_cast<void *>(jsCallback);
331 
332     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
333         LOGD("OnDeviceOnline uv_queue_work_with_qos");
334     }, [] (uv_work_t *work, int status) {
335         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
336         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
337         if (deviceManagerNapi == nullptr) {
338             LOGE("OnDeviceOnline, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
339         } else {
340             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::ONLINE, callback->deviceInfo_);
341         }
342         DeleteDmNapiStateJsCallbackPtr(callback);
343         DeleteUvWork(work);
344     }, uv_qos_user_initiated);
345     if (ret != 0) {
346         LOGE("Failed to execute OnDeviceOnline work queue");
347         DeleteDmNapiStateJsCallbackPtr(jsCallback);
348         DeleteUvWork(work);
349     }
350 }
351 
OnDeviceReady(const DmDeviceInfo & deviceInfo)352 void DmNapiDeviceStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
353 {
354     uv_loop_s *loop = nullptr;
355     napi_get_uv_event_loop(env_, &loop);
356     if (loop == nullptr) {
357         return;
358     }
359     uv_work_t *work = new (std::nothrow) uv_work_t;
360     if (work == nullptr) {
361         LOGE("DmNapiDeviceStateCallback: OnDeviceReady, No memory");
362         return;
363     }
364 
365     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
366     if (jsCallback == nullptr) {
367         DeleteUvWork(work);
368         return;
369     }
370     work->data = reinterpret_cast<void *>(jsCallback);
371 
372     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
373         LOGD("OnDeviceReady uv_queue_work_with_qos");
374     }, [] (uv_work_t *work, int status) {
375         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
376         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
377         if (deviceManagerNapi == nullptr) {
378             LOGE("OnDeviceReady, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
379         } else {
380             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::READY, callback->deviceInfo_);
381         }
382         DeleteDmNapiStateJsCallbackPtr(callback);
383         DeleteUvWork(work);
384     }, uv_qos_user_initiated);
385     if (ret != 0) {
386         LOGE("Failed to execute OnDeviceReady work queue");
387         DeleteDmNapiStateJsCallbackPtr(jsCallback);
388         DeleteUvWork(work);
389     }
390 }
391 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)392 void DmNapiDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
393 {
394     uv_loop_s *loop = nullptr;
395     napi_get_uv_event_loop(env_, &loop);
396     if (loop == nullptr) {
397         return;
398     }
399     uv_work_t *work = new (std::nothrow) uv_work_t;
400     if (work == nullptr) {
401         LOGE("DmNapiDeviceStateCallback: OnDeviceOffline, No memory");
402         return;
403     }
404 
405     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
406     if (jsCallback == nullptr) {
407         DeleteUvWork(work);
408         return;
409     }
410     work->data = reinterpret_cast<void *>(jsCallback);
411 
412     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
413         LOGD("OnDeviceOffline uv_queue_work_with_qos");
414     }, [] (uv_work_t *work, int status) {
415         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
416         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
417         if (deviceManagerNapi == nullptr) {
418             LOGE("OnDeviceOffline, deviceManagerNapi not find for bundleName %{public}s",
419                 callback->bundleName_.c_str());
420         } else {
421             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::OFFLINE, callback->deviceInfo_);
422         }
423         DeleteDmNapiStateJsCallbackPtr(callback);
424         DeleteUvWork(work);
425     }, uv_qos_user_initiated);
426     if (ret != 0) {
427         LOGE("Failed to execute OnDeviceOffline work queue");
428         DeleteDmNapiStateJsCallbackPtr(jsCallback);
429         DeleteUvWork(work);
430     }
431 }
432 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)433 void DmNapiDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
434 {
435     uv_loop_s *loop = nullptr;
436     napi_get_uv_event_loop(env_, &loop);
437     if (loop == nullptr) {
438         return;
439     }
440     uv_work_t *work = new (std::nothrow) uv_work_t;
441     if (work == nullptr) {
442         LOGE("DmNapiDeviceStateCallback: OnDeviceChanged, No memory");
443         return;
444     }
445 
446     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, 0, 0, deviceInfo);
447     if (jsCallback == nullptr) {
448         DeleteUvWork(work);
449         return;
450     }
451     work->data = reinterpret_cast<void *>(jsCallback);
452 
453     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
454         LOGD("OnDeviceChanged uv_queue_work_with_qos");
455     }, [] (uv_work_t *work, int status) {
456         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
457         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
458         if (deviceManagerNapi == nullptr) {
459             LOGE("OnDeviceChanged, deviceManagerNapi not find for bundleName %{public}s",
460                 callback->bundleName_.c_str());
461         } else {
462             deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::CHANGE, callback->deviceInfo_);
463         }
464         DeleteDmNapiStateJsCallbackPtr(callback);
465         DeleteUvWork(work);
466     }, uv_qos_user_initiated);
467     if (ret != 0) {
468         LOGE("Failed to execute OnDeviceChanged work queue");
469         DeleteDmNapiStateJsCallbackPtr(jsCallback);
470         DeleteUvWork(work);
471     }
472 }
473 
OnDeviceFound(uint16_t subscribeId,const DmDeviceInfo & deviceInfo)474 void DmNapiDiscoveryCallback::OnDeviceFound(uint16_t subscribeId, const DmDeviceInfo &deviceInfo)
475 {
476     LOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
477 
478     uv_loop_s *loop = nullptr;
479     napi_get_uv_event_loop(env_, &loop);
480     if (loop == nullptr) {
481         return;
482     }
483     uv_work_t *work = new (std::nothrow) uv_work_t;
484     if (work == nullptr) {
485         LOGE("DmNapiDiscoveryCallback: OnDeviceFound, No memory");
486         return;
487     }
488 
489     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, subscribeId, 0, deviceInfo);
490     if (jsCallback == nullptr) {
491         DeleteUvWork(work);
492         return;
493     }
494     work->data = reinterpret_cast<void *>(jsCallback);
495 
496     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
497         LOGD("OnDeviceFound uv_queue_work_with_qos");
498     }, [] (uv_work_t *work, int status) {
499         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
500         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
501         if (deviceManagerNapi == nullptr) {
502             LOGE("OnDeviceFound, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
503         } else {
504             deviceManagerNapi->OnDeviceFound(callback->subscribeId_, callback->deviceInfo_);
505         }
506         DeleteDmNapiStateJsCallbackPtr(callback);
507         DeleteUvWork(work);
508     }, uv_qos_user_initiated);
509     if (ret != 0) {
510         LOGE("Failed to execute OnDeviceFound work queue");
511         DeleteDmNapiStateJsCallbackPtr(jsCallback);
512         DeleteUvWork(work);
513     }
514 }
515 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)516 void DmNapiDiscoveryCallback::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
517 {
518     LOGI("OnDiscoveryFailed for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
519 
520     uv_loop_s *loop = nullptr;
521     napi_get_uv_event_loop(env_, &loop);
522     if (loop == nullptr) {
523         return;
524     }
525     uv_work_t *work = new (std::nothrow) uv_work_t;
526     if (work == nullptr) {
527         LOGE("DmNapiDiscoveryCallback: OnDiscoveryFailed, No memory");
528         return;
529     }
530 
531     DmDeviceInfo info;
532     DmNapiStateJsCallback *jsCallback = new DmNapiStateJsCallback(bundleName_, subscribeId,
533         failedReason, info);
534     if (jsCallback == nullptr) {
535         DeleteUvWork(work);
536         return;
537     }
538     work->data = reinterpret_cast<void *>(jsCallback);
539 
540     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
541         LOGD("OnDiscoveryFailed uv_queue_work_with_qos");
542     }, [] (uv_work_t *work, int status) {
543         DmNapiStateJsCallback *callback = reinterpret_cast<DmNapiStateJsCallback *>(work->data);
544         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
545         if (deviceManagerNapi == nullptr) {
546             LOGE("OnDiscoveryFailed, deviceManagerNapi not find for bundleName %{public}s",
547                 callback->bundleName_.c_str());
548         } else {
549             deviceManagerNapi->OnDiscoveryFailed(callback->subscribeId_, callback->reason_);
550         }
551         DeleteDmNapiStateJsCallbackPtr(callback);
552         DeleteUvWork(work);
553     }, uv_qos_user_initiated);
554     if (ret != 0) {
555         LOGE("Failed to execute OnDiscoveryFailed work queue");
556         DeleteDmNapiStateJsCallbackPtr(jsCallback);
557         DeleteUvWork(work);
558     }
559 }
560 
OnDiscoverySuccess(uint16_t subscribeId)561 void DmNapiDiscoveryCallback::OnDiscoverySuccess(uint16_t subscribeId)
562 {
563     DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_);
564     if (deviceManagerNapi == nullptr) {
565         LOGE("OnDiscoverySuccess, deviceManagerNapi not find for bundleName %{public}s", bundleName_.c_str());
566         return;
567     }
568     LOGI("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
569 }
570 
IncreaseRefCount()571 void DmNapiDiscoveryCallback::IncreaseRefCount()
572 {
573     refCount_++;
574 }
575 
DecreaseRefCount()576 void DmNapiDiscoveryCallback::DecreaseRefCount()
577 {
578     refCount_--;
579 }
580 
GetRefCount()581 int32_t DmNapiDiscoveryCallback::GetRefCount()
582 {
583     return refCount_;
584 }
585 
OnPublishResult(int32_t publishId,int32_t publishResult)586 void DmNapiPublishCallback::OnPublishResult(int32_t publishId, int32_t publishResult)
587 {
588     LOGI("OnPublishResult for %{public}s, publishId %{public}d, publishResult %{public}d", bundleName_.c_str(),
589         publishId, publishResult);
590     uv_loop_s *loop = nullptr;
591     napi_get_uv_event_loop(env_, &loop);
592     if (loop == nullptr) {
593         return;
594     }
595     uv_work_t *work = new (std::nothrow) uv_work_t;
596     if (work == nullptr) {
597         LOGE("DmNapiPublishCallback: OnPublishResult, No memory");
598         return;
599     }
600 
601     DmNapiPublishJsCallback *jsCallback = new DmNapiPublishJsCallback(bundleName_, publishId, publishResult);
602     if (jsCallback == nullptr) {
603         DeleteUvWork(work);
604         return;
605     }
606     work->data = reinterpret_cast<void *>(jsCallback);
607 
608     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
609         LOGD("OnPublishResult uv_queue_work_with_qos");
610     }, [] (uv_work_t *work, int status) {
611         DmNapiPublishJsCallback *callback = reinterpret_cast<DmNapiPublishJsCallback *>(work->data);
612         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
613         if (deviceManagerNapi == nullptr) {
614             LOGE("OnPublishResult, deviceManagerNapi failed for bundleName %{public}s", callback->bundleName_.c_str());
615         } else {
616             deviceManagerNapi->OnPublishResult(callback->publishId_, callback->reason_);
617         }
618         delete callback;
619         callback = nullptr;
620         DeleteUvWork(work);
621     }, uv_qos_user_initiated);
622     if (ret != 0) {
623         LOGE("Failed to execute OnPublishResult work queue");
624         delete jsCallback;
625         jsCallback = nullptr;
626         DeleteUvWork(work);
627     }
628 }
629 
IncreaseRefCount()630 void DmNapiPublishCallback::IncreaseRefCount()
631 {
632     refCount_++;
633 }
634 
DecreaseRefCount()635 void DmNapiPublishCallback::DecreaseRefCount()
636 {
637     refCount_--;
638 }
639 
GetRefCount()640 int32_t DmNapiPublishCallback::GetRefCount()
641 {
642     return refCount_;
643 }
644 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)645 void DmNapiAuthenticateCallback::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
646                                               int32_t reason)
647 {
648     uv_loop_s *loop = nullptr;
649     napi_get_uv_event_loop(env_, &loop);
650     if (loop == nullptr) {
651         return;
652     }
653     uv_work_t *work = new (std::nothrow) uv_work_t;
654     if (work == nullptr) {
655         LOGE("js DmNapiAuthenticateCallback::OnAuthResult, No memory");
656         return;
657     }
658 
659     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, deviceId, token, status, reason);
660     if (jsCallback == nullptr) {
661         DeleteUvWork(work);
662         return;
663     }
664     work->data = reinterpret_cast<void *>(jsCallback);
665 
666     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
667         LOGD("OnAuthResult uv_queue_work_with_qos");
668     }, [] (uv_work_t *work, int status) {
669         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
670         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
671         if (deviceManagerNapi == nullptr) {
672             LOGE("OnAuthResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
673         } else {
674             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
675                 callback->status_, callback->reason_);
676         }
677         delete callback;
678         callback = nullptr;
679         DeleteUvWork(work);
680     }, uv_qos_user_initiated);
681     if (ret != 0) {
682         LOGE("Failed to execute OnAuthResult work queue");
683         delete jsCallback;
684         jsCallback = nullptr;
685         DeleteUvWork(work);
686     }
687 }
688 
OnCredentialResult(int32_t & action,const std::string & credentialResult)689 void DmNapiCredentialCallback::OnCredentialResult(int32_t &action, const std::string &credentialResult)
690 {
691     uv_loop_s *loop = nullptr;
692     napi_get_uv_event_loop(env_, &loop);
693     if (loop == nullptr) {
694         return;
695     }
696     uv_work_t *work = new (std::nothrow) uv_work_t;
697     if (work == nullptr) {
698         LOGE("js DmNapiAuthenticateCallback::OnAuthResult, No memory");
699         return;
700     }
701 
702     DmNapiCredentialJsCallback *jsCallback = new DmNapiCredentialJsCallback(bundleName_, action, credentialResult);
703     if (jsCallback == nullptr) {
704         delete work;
705         work = nullptr;
706         return;
707     }
708     work->data = reinterpret_cast<void *>(jsCallback);
709 
710     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
711         LOGD("OnCredentialResult uv_queue_work_with_qos");
712     }, [] (uv_work_t *work, int status) {
713         DmNapiCredentialJsCallback *callback = reinterpret_cast<DmNapiCredentialJsCallback *>(work->data);
714         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
715         if (deviceManagerNapi == nullptr) {
716             LOGE("OnCredentialResult, deviceManagerNapi not find for bundleName %{public}s",
717                 callback->bundleName_.c_str());
718         } else {
719             deviceManagerNapi->OnCredentialResult(callback->action_, callback->credentialResult_);
720         }
721         delete callback;
722         callback = nullptr;
723         delete work;
724         work = nullptr;
725     }, uv_qos_user_initiated);
726     if (ret != 0) {
727         LOGE("Failed to execute OnCredentialResult work queue");
728         delete jsCallback;
729         jsCallback = nullptr;
730         delete work;
731         work = nullptr;
732     }
733 }
734 
DeviceManagerNapi(napi_env env,napi_value thisVar)735 DeviceManagerNapi::DeviceManagerNapi(napi_env env, napi_value thisVar) : DmNativeEvent(env, thisVar)
736 {
737     env_ = env;
738 }
739 
~DeviceManagerNapi()740 DeviceManagerNapi::~DeviceManagerNapi()
741 {
742 }
743 
GetDeviceManagerNapi(std::string & bundleName)744 DeviceManagerNapi *DeviceManagerNapi::GetDeviceManagerNapi(std::string &bundleName)
745 {
746     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
747     auto iter = g_deviceManagerMap.find(bundleName);
748     if (iter == g_deviceManagerMap.end()) {
749         return nullptr;
750     }
751     return iter->second;
752 }
753 
OnDeviceStateChange(DmNapiDevStateChangeAction action,const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)754 void DeviceManagerNapi::OnDeviceStateChange(DmNapiDevStateChangeAction action,
755                                             const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
756 {
757     napi_handle_scope scope;
758     napi_open_handle_scope(env_, &scope);
759     napi_value result = nullptr;
760     napi_create_object(env_, &result);
761     SetValueInt32(env_, "action", (int)action, result);
762 
763     napi_value device = nullptr;
764     napi_create_object(env_, &device);
765     SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device);
766     SetValueUtf8String(env_, "networkId", deviceInfo.networkId, device);
767     SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device);
768     SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device);
769     SetValueInt32(env_, "authForm", (int)deviceInfo.authForm, device);
770 
771     napi_set_named_property(env_, result, "device", device);
772     OnEvent("deviceStateChange", DM_NAPI_ARGS_ONE, &result);
773     napi_close_handle_scope(env_, scope);
774 }
775 
OnDeviceFound(uint16_t subscribeId,const DmDeviceInfo & deviceInfo)776 void DeviceManagerNapi::OnDeviceFound(uint16_t subscribeId, const DmDeviceInfo &deviceInfo)
777 {
778     LOGI("OnDeviceFound for subscribeId %{public}d, range : %{public}d", (int32_t)subscribeId, deviceInfo.range);
779     napi_handle_scope scope;
780     napi_open_handle_scope(env_, &scope);
781     napi_value result = nullptr;
782     napi_create_object(env_, &result);
783     SetValueInt32(env_, "subscribeId", (int)subscribeId, result);
784 
785     napi_value device = nullptr;
786     napi_create_object(env_, &device);
787     SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device);
788     SetValueUtf8String(env_, "networkId", deviceInfo.networkId, device);
789     SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device);
790     SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device);
791     SetValueInt32(env_, "authForm", (int)deviceInfo.authForm, device);
792     SetValueInt32(env_, "range", deviceInfo.range, device);
793 
794     napi_set_named_property(env_, result, "device", device);
795     OnEvent("deviceFound", DM_NAPI_ARGS_ONE, &result);
796     napi_close_handle_scope(env_, scope);
797 }
798 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)799 void DeviceManagerNapi::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
800 {
801     LOGI("OnDiscoveryFailed for subscribeId %{public}d", (int32_t)subscribeId);
802     napi_handle_scope scope;
803     napi_open_handle_scope(env_, &scope);
804     napi_value result = nullptr;
805     napi_create_object(env_, &result);
806     SetValueInt32(env_, "subscribeId", (int)subscribeId, result);
807     SetValueInt32(env_, "reason", (int)failedReason, result);
808     std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)failedReason);
809     SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
810     OnEvent("discoverFail", DM_NAPI_ARGS_ONE, &result);
811     napi_close_handle_scope(env_, scope);
812 }
813 
OnPublishResult(int32_t publishId,int32_t publishResult)814 void DeviceManagerNapi::OnPublishResult(int32_t publishId, int32_t publishResult)
815 {
816     LOGI("OnPublishResult for publishId %{public}d, publishResult %{public}d", publishId, publishResult);
817     napi_handle_scope scope;
818     napi_open_handle_scope(env_, &scope);
819     napi_value result = nullptr;
820     napi_create_object(env_, &result);
821     SetValueInt32(env_, "publishId", publishId, result);
822     if (publishResult == 0) {
823         OnEvent("publishSuccess", DM_NAPI_ARGS_ONE, &result);
824     } else {
825         SetValueInt32(env_, "reason", publishResult, result);
826         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString(publishResult);
827         SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
828         OnEvent("publishFail", DM_NAPI_ARGS_ONE, &result);
829     }
830     NAPI_CALL_RETURN_VOID(env_, napi_close_handle_scope(env_, scope));
831 }
832 
OnCredentialResult(int32_t & action,const std::string & credentialResult)833 void DeviceManagerNapi::OnCredentialResult(int32_t &action, const std::string &credentialResult)
834 {
835     LOGI("OnCredentialResult for action: %{public}d", action);
836     napi_handle_scope scope = nullptr;
837     napi_open_handle_scope(env_, &scope);
838     if (scope == nullptr) {
839         LOGE("scope is nullptr");
840         return;
841     }
842     napi_value result = nullptr;
843     napi_create_object(env_, &result);
844     SetValueUtf8String(env_, "resultInfo", credentialResult, result);
845 
846     napi_value callResult = nullptr;
847     napi_value handler = nullptr;
848     napi_get_reference_value(env_, creAsyncCallbackInfo_.callback, &handler);
849     if (handler != nullptr) {
850         napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_ONE, &result, &callResult);
851         napi_delete_reference(env_, creAsyncCallbackInfo_.callback);
852         creAsyncCallbackInfo_.callback = nullptr;
853     } else {
854         LOGE("handler is nullptr");
855     }
856     napi_close_handle_scope(env_, scope);
857     DeviceManager::GetInstance().UnRegisterCredentialCallback(bundleName_);
858     {
859         std::lock_guard<std::mutex> autoLock(creMapLocks_);
860         g_creCallbackMap.erase(bundleName_);
861     }
862 }
863 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)864 void DeviceManagerNapi::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
865                                      int32_t reason)
866 {
867     LOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason);
868     napi_handle_scope scope;
869     napi_open_handle_scope(env_, &scope);
870     napi_value thisVar = nullptr;
871     napi_get_reference_value(env_, thisVarRef_, &thisVar);
872     napi_value result[DM_NAPI_ARGS_TWO] = {0};
873 
874     if (status == DM_AUTH_REQUEST_SUCCESS_STATUS && reason == 0) {
875         LOGI("OnAuthResult success");
876         napi_get_undefined(env_, &result[0]);
877         napi_create_object(env_, &result[1]);
878         SetValueUtf8String(env_, "deviceId", deviceId, result[1]);
879     } else {
880         LOGI("OnAuthResult failed");
881         napi_create_object(env_, &result[0]);
882         SetValueInt32(env_, "code", status, result[0]);
883         SetValueInt32(env_, "reason", reason, result[0]);
884         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)reason);
885         SetValueUtf8String(env_, "errInfo", errCodeInfo, result[0]);
886         napi_get_undefined(env_, &result[1]);
887     }
888 
889     napi_value callResult = nullptr;
890     napi_value handler = nullptr;
891     napi_get_reference_value(env_, authAsyncCallbackInfo_.callback, &handler);
892     if (handler != nullptr) {
893         if (reason == DM_OK && (status <= STATUS_DM_CLOSE_PIN_INPUT_UI && status >= STATUS_DM_SHOW_AUTHORIZE_UI)) {
894             LOGI("update ui change, status: %{public}d, reason: %{public}d", status, reason);
895         } else {
896             napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_TWO, &result[0], &callResult);
897             napi_delete_reference(env_, authAsyncCallbackInfo_.callback);
898             authAsyncCallbackInfo_.callback = nullptr;
899         }
900     } else {
901         LOGE("handler is nullptr");
902     }
903     napi_close_handle_scope(env_, scope);
904     std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
905     g_authCallbackMap.erase(bundleName_);
906 }
907 
SetValueUtf8String(const napi_env & env,const std::string & fieldStr,const std::string & str,napi_value & result)908 void DeviceManagerNapi::SetValueUtf8String(const napi_env &env, const std::string &fieldStr, const std::string &str,
909                                            napi_value &result)
910 {
911     napi_value value = nullptr;
912     napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value);
913     napi_set_named_property(env, result, fieldStr.c_str(), value);
914 }
915 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int32_t intValue,napi_value & result)916 void DeviceManagerNapi::SetValueInt32(const napi_env &env, const std::string &fieldStr, const int32_t intValue,
917                                       napi_value &result)
918 {
919     napi_value value = nullptr;
920     napi_create_int32(env, intValue, &value);
921     napi_set_named_property(env, result, fieldStr.c_str(), value);
922 }
923 
DeviceInfoToJsArray(const napi_env & env,const std::vector<DmDeviceInfo> & vecDevInfo,const int32_t idx,napi_value & arrayResult)924 void DeviceManagerNapi::DeviceInfoToJsArray(const napi_env &env, const std::vector<DmDeviceInfo> &vecDevInfo,
925                                             const int32_t idx, napi_value &arrayResult)
926 {
927     napi_value result = nullptr;
928     napi_create_object(env, &result);
929 
930     SetValueUtf8String(env, "deviceId", vecDevInfo[idx].deviceId, result);
931     SetValueUtf8String(env, "networkId", vecDevInfo[idx].networkId, result);
932     SetValueUtf8String(env, "deviceName", vecDevInfo[idx].deviceName, result);
933     SetValueInt32(env, "deviceType", (int)vecDevInfo[idx].deviceTypeId, result);
934     SetValueInt32(env, "authForm", (int)vecDevInfo[idx].authForm, result);
935 
936     napi_status status = napi_set_element(env, arrayResult, idx, result);
937     if (status != napi_ok) {
938         LOGE("DmDeviceInfo To JsArray set element error: %{public}d", status);
939     }
940 }
941 
DmAuthParamDetection(const DmAuthParam & authParam)942 bool DeviceManagerNapi::DmAuthParamDetection(const DmAuthParam &authParam)
943 {
944     LOGI("DeviceManagerNapi::DmAuthParamDetection");
945     const uint32_t maxIntValueLen = 10;
946     const std::string maxAuthToken = "2147483647";
947     if (authParam.authToken.length() > maxIntValueLen) {
948         LOGE("The authToken is illegal");
949         return false;
950     } else {
951         if (!IsNumberString(authParam.authToken)) {
952             LOGE("The authToken is Error");
953             return false;
954         } else {
955             if (authParam.authToken > maxAuthToken) {
956                 LOGE("The authToken is Cross the border");
957                 return false;
958             }
959         }
960     }
961     return true;
962 }
963 
DmAuthParamToJsAuthParam(const napi_env & env,const DmAuthParam & authParam,napi_value & paramResult)964 void DeviceManagerNapi::DmAuthParamToJsAuthParam(const napi_env &env, const DmAuthParam &authParam,
965                                                  napi_value &paramResult)
966 {
967     LOGI("DeviceManagerNapi::DmAuthParamToJsAuthParam");
968     if (!DmAuthParamDetection(authParam)) {
969         LOGE("The authToken is Error");
970         return;
971     }
972     napi_value extraInfo = nullptr;
973     napi_create_object(env, &extraInfo);
974     SetValueInt32(env, "direction", authParam.direction, extraInfo);
975     SetValueInt32(env, "authType", authParam.authType, paramResult);
976     SetValueInt32(env, "pinToken", atoi(authParam.authToken.c_str()), extraInfo);
977 
978     if (authParam.direction == DM_AUTH_DIRECTION_CLIENT) {
979         napi_set_named_property(env, paramResult, "extraInfo", extraInfo);
980         return;
981     }
982 
983     SetValueUtf8String(env, "packageName", authParam.packageName, extraInfo);
984     SetValueUtf8String(env, "appName", authParam.appName, extraInfo);
985     SetValueUtf8String(env, "appDescription", authParam.appDescription, extraInfo);
986     SetValueInt32(env, "business", authParam.business, extraInfo);
987     SetValueInt32(env, "pinCode", authParam.pincode, extraInfo);
988     napi_set_named_property(env, paramResult, "extraInfo", extraInfo);
989 
990     size_t appIconLen = static_cast<size_t>(authParam.imageinfo.GetAppIconLen());
991     if (appIconLen > 0) {
992         void *appIcon = nullptr;
993         napi_value appIconBuffer = nullptr;
994         napi_create_arraybuffer(env, appIconLen, &appIcon, &appIconBuffer);
995         if (appIcon != nullptr &&
996             memcpy_s(appIcon, appIconLen, reinterpret_cast<const void *>(authParam.imageinfo.GetAppIcon()),
997                      appIconLen) == 0) {
998             napi_value appIconArray = nullptr;
999             napi_create_typedarray(env, napi_uint8_array, appIconLen, appIconBuffer, 0, &appIconArray);
1000             napi_set_named_property(env, paramResult, "appIcon", appIconArray);
1001         }
1002     }
1003 
1004     size_t appThumbnailLen = static_cast<size_t>(authParam.imageinfo.GetAppThumbnailLen());
1005     if (appThumbnailLen > 0) {
1006         void *appThumbnail = nullptr;
1007         napi_value appThumbnailBuffer = nullptr;
1008         napi_create_arraybuffer(env, appThumbnailLen, &appThumbnail, &appThumbnailBuffer);
1009         if (appThumbnail != nullptr &&
1010             memcpy_s(appThumbnail, appThumbnailLen,
1011                      reinterpret_cast<const void *>(authParam.imageinfo.GetAppThumbnail()), appThumbnailLen) == 0) {
1012             napi_value appThumbnailArray = nullptr;
1013             napi_create_typedarray(env, napi_uint8_array, appThumbnailLen, appThumbnailBuffer, 0, &appThumbnailArray);
1014             napi_set_named_property(env, paramResult, "appThumbnail", appThumbnailArray);
1015         }
1016     }
1017     return;
1018 }
1019 
JsObjectToString(const napi_env & env,const napi_value & object,const std::string & fieldStr,char * dest,const int32_t destLen)1020 void DeviceManagerNapi::JsObjectToString(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1021                                          char *dest, const int32_t destLen)
1022 {
1023     bool hasProperty = false;
1024     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1025     if (hasProperty) {
1026         napi_value field = nullptr;
1027         napi_valuetype valueType = napi_undefined;
1028 
1029         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1030         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1031         if (!CheckArgsType(env, valueType == napi_string, fieldStr.c_str(), "string")) {
1032             return;
1033         }
1034         size_t result = 0;
1035         NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, field, dest, destLen, &result));
1036     } else {
1037         LOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str());
1038     }
1039 }
1040 
JsObjectToString(const napi_env & env,const napi_value & param)1041 std::string DeviceManagerNapi::JsObjectToString(const napi_env &env, const napi_value &param)
1042 {
1043     LOGI("JsObjectToString in.");
1044     size_t size = 0;
1045     if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
1046         return "";
1047     }
1048     if (size == 0) {
1049         return "";
1050     }
1051     char *buf = new (std::nothrow) char[size + 1];
1052     if (buf == nullptr) {
1053         return "";
1054     }
1055     int32_t ret = memset_s(buf, (size + 1), 0, (size + 1));
1056     if (ret != 0) {
1057         LOGE("devicemanager memset_s error.");
1058         delete[] buf;
1059         buf = nullptr;
1060         return "";
1061     }
1062     bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
1063 
1064     std::string value;
1065     if (rev) {
1066         value = buf;
1067     } else {
1068         value = "";
1069     }
1070     delete[] buf;
1071     buf = nullptr;
1072     return value;
1073 }
1074 
JsObjectToInt(const napi_env & env,const napi_value & object,const std::string & fieldStr,int32_t & fieldRef)1075 void DeviceManagerNapi::JsObjectToInt(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1076                                       int32_t &fieldRef)
1077 {
1078     bool hasProperty = false;
1079     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1080     if (hasProperty) {
1081         napi_value field = nullptr;
1082         napi_valuetype valueType = napi_undefined;
1083 
1084         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1085         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1086         if (!CheckArgsType(env, valueType == napi_number, fieldStr.c_str(), "number")) {
1087             return;
1088         }
1089         napi_get_value_int32(env, field, &fieldRef);
1090     } else {
1091         LOGE("devicemanager napi js to int no property: %{public}s", fieldStr.c_str());
1092     }
1093 }
1094 
JsObjectToBool(const napi_env & env,const napi_value & object,const std::string & fieldStr,bool & fieldRef)1095 void DeviceManagerNapi::JsObjectToBool(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1096                                        bool &fieldRef)
1097 {
1098     bool hasProperty = false;
1099     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1100     if (hasProperty) {
1101         napi_value field = nullptr;
1102         napi_valuetype valueType = napi_undefined;
1103 
1104         napi_get_named_property(env, object, fieldStr.c_str(), &field);
1105         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
1106         if (!CheckArgsType(env, valueType == napi_boolean, fieldStr.c_str(), "bool")) {
1107             return;
1108         }
1109         napi_get_value_bool(env, field, &fieldRef);
1110     } else {
1111         LOGE("devicemanager napi js to bool no property: %{public}s", fieldStr.c_str());
1112     }
1113 }
1114 
JsToDmPublishInfo(const napi_env & env,const napi_value & object,DmPublishInfo & info)1115 void DeviceManagerNapi::JsToDmPublishInfo(const napi_env &env, const napi_value &object, DmPublishInfo &info)
1116 {
1117     int32_t publishId = -1;
1118     JsObjectToInt(env, object, "publishId", publishId);
1119     info.publishId = publishId;
1120 
1121     int32_t mode = -1;
1122     JsObjectToInt(env, object, "mode", mode);
1123     info.mode = static_cast<DmDiscoverMode>(mode);
1124 
1125     int32_t freq = -1;
1126     JsObjectToInt(env, object, "freq", freq);
1127     info.freq = static_cast<DmExchangeFreq>(freq);
1128 
1129     JsObjectToBool(env, object, "ranging", info.ranging);
1130     return;
1131 }
1132 
JsToDmSubscribeInfo(const napi_env & env,const napi_value & object,DmSubscribeInfo & info)1133 int32_t DeviceManagerNapi::JsToDmSubscribeInfo(const napi_env &env, const napi_value &object, DmSubscribeInfo &info)
1134 {
1135     int32_t subscribeId = -1;
1136     JsObjectToInt(env, object, "subscribeId", subscribeId);
1137     if (subscribeId < 0 || subscribeId > DM_NAPI_SUB_ID_MAX) {
1138         LOGE("DeviceManagerNapi::JsToDmSubscribeInfo, subscribeId error, subscribeId: %{public}d ", subscribeId);
1139         return -1;
1140     }
1141 
1142     info.subscribeId = static_cast<uint16_t>(subscribeId);
1143 
1144     int32_t mode = -1;
1145     JsObjectToInt(env, object, "mode", mode);
1146     info.mode = static_cast<DmDiscoverMode>(mode);
1147 
1148     int32_t medium = -1;
1149     JsObjectToInt(env, object, "medium", medium);
1150     info.medium = static_cast<DmExchangeMedium>(medium);
1151 
1152     int32_t freq = -1;
1153     JsObjectToInt(env, object, "freq", freq);
1154     info.freq = static_cast<DmExchangeFreq>(freq);
1155 
1156     JsObjectToBool(env, object, "isSameAccount", info.isSameAccount);
1157     JsObjectToBool(env, object, "isWakeRemote", info.isWakeRemote);
1158 
1159     int32_t capability = -1;
1160     JsObjectToInt(env, object, "capability", capability);
1161     if (capability == DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP || capability == DM_NAPI_SUBSCRIBE_CAPABILITY_OSD) {
1162         (void)strncpy_s(info.capability, sizeof(info.capability), DM_CAPABILITY_OSD, strlen(DM_CAPABILITY_OSD));
1163     }
1164     return 0;
1165 }
1166 
JsToDmDeviceInfo(const napi_env & env,const napi_value & object,DmDeviceInfo & info)1167 void DeviceManagerNapi::JsToDmDeviceInfo(const napi_env &env, const napi_value &object, DmDeviceInfo &info)
1168 {
1169     JsObjectToString(env, object, "deviceId", info.deviceId, sizeof(info.deviceId));
1170     JsObjectToString(env, object, "deviceName", info.deviceName, sizeof(info.deviceName));
1171     JsObjectToString(env, object, "networkId", info.networkId, sizeof(info.networkId));
1172     int32_t deviceType = -1;
1173     JsObjectToInt(env, object, "deviceType", deviceType);
1174     info.deviceTypeId = static_cast<DmDeviceType>(deviceType);
1175     JsObjectToInt(env, object, "range", info.range);
1176 }
1177 
JsToDmExtra(const napi_env & env,const napi_value & object,std::string & extra,int32_t & authType)1178 void DeviceManagerNapi::JsToDmExtra(const napi_env &env, const napi_value &object, std::string &extra,
1179                                     int32_t &authType)
1180 {
1181     LOGI("JsToDmExtra in.");
1182     int32_t authTypeTemp = -1;
1183     JsObjectToInt(env, object, "authType", authTypeTemp);
1184     authType = authTypeTemp;
1185 
1186     char appOperation[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
1187     JsObjectToString(env, object, "appOperation", appOperation, sizeof(appOperation));
1188     std::string appOperationStr = appOperation;
1189 
1190     char customDescription[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
1191     JsObjectToString(env, object, "customDescription", customDescription, sizeof(customDescription));
1192     std::string customDescriptionStr = customDescription;
1193 
1194     int32_t bindLevel = 0;
1195     JsObjectToInt(env, object, "bindLevel", bindLevel);
1196 
1197     JsonObject jsonObj;
1198     jsonObj[AUTH_TYPE] = authType;
1199     jsonObj[APP_OPERATION] = appOperationStr;
1200     jsonObj[CUSTOM_DESCRIPTION] = customDescriptionStr;
1201     jsonObj[BIND_LEVEL] = bindLevel;
1202     JsToJsonObject(env, object, "extraInfo", jsonObj);
1203     extra = SafetyDump(jsonObj);
1204     LOGI("appOperationLen %{public}zu, customDescriptionLen %{public}zu", appOperationStr.size(),
1205         customDescriptionStr.size());
1206 }
1207 
JsToJsonObject(const napi_env & env,const napi_value & object,const std::string & fieldStr,JsonObject & jsonObj)1208 void DeviceManagerNapi::JsToJsonObject(const napi_env &env, const napi_value &object, const std::string &fieldStr,
1209                                        JsonObject &jsonObj)
1210 {
1211     bool hasProperty = false;
1212     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
1213     if (!hasProperty) {
1214         LOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str());
1215         return;
1216     }
1217 
1218     napi_value jsonField = nullptr;
1219     napi_get_named_property(env, object, fieldStr.c_str(), &jsonField);
1220     napi_valuetype jsValueType = napi_undefined;
1221     napi_value jsProNameList = nullptr;
1222     uint32_t jsProCount = 0;
1223     napi_get_property_names(env, jsonField, &jsProNameList);
1224     napi_get_array_length(env, jsProNameList, &jsProCount);
1225 
1226     napi_value jsProName = nullptr;
1227     napi_value jsProValue = nullptr;
1228     for (uint32_t index = 0; index < jsProCount; index++) {
1229         napi_get_element(env, jsProNameList, index, &jsProName);
1230         std::string strProName = JsObjectToString(env, jsProName);
1231         napi_get_named_property(env, jsonField, strProName.c_str(), &jsProValue);
1232         napi_typeof(env, jsProValue, &jsValueType);
1233         int32_t numberValue = 0;
1234         bool boolValue = false;
1235         std::string stringValue = "";
1236         switch (jsValueType) {
1237             case napi_string:
1238                 stringValue = JsObjectToString(env, jsProValue);
1239                 LOGI("Property name = %{public}s, string, value = %{public}s", strProName.c_str(), stringValue.c_str());
1240                 jsonObj[strProName] = stringValue;
1241                 break;
1242             case napi_boolean:
1243                 napi_get_value_bool(env, jsProValue, &boolValue);
1244                 LOGI("Property name = %{public}s, boolean, value = %{public}d.", strProName.c_str(), boolValue);
1245                 jsonObj[strProName] = boolValue;
1246                 break;
1247             case napi_number:
1248                 if (napi_get_value_int32(env, jsProValue, &numberValue) != napi_ok) {
1249                     LOGE("Property name = %{public}s, Property int32_t parse error", strProName.c_str());
1250                 } else {
1251                     jsonObj[strProName] = numberValue;
1252                     LOGI("Property name = %{public}s, number, value = %{public}d.", strProName.c_str(), numberValue);
1253                 }
1254                 break;
1255             default:
1256                 LOGE("Property name = %{public}s, value type not support.", strProName.c_str());
1257                 break;
1258         }
1259     }
1260 }
1261 
JsToDmAuthInfo(const napi_env & env,const napi_value & object,std::string & extra)1262 void DeviceManagerNapi::JsToDmAuthInfo(const napi_env &env, const napi_value &object, std::string &extra)
1263 {
1264     LOGI("%{public}s called.", __func__);
1265     int32_t authType = -1;
1266     int32_t token = -1;
1267 
1268     JsObjectToInt(env, object, "authType", authType);
1269     JsObjectToInt(env, object, "token", token);
1270     JsonObject jsonObj;
1271     jsonObj[AUTH_TYPE] = authType;
1272     jsonObj[PIN_TOKEN] = token;
1273     JsToJsonObject(env, object, "extraInfo", jsonObj);
1274     extra = SafetyDump(jsonObj);
1275 }
1276 
JsToDmDiscoveryExtra(const napi_env & env,const napi_value & object,std::string & extra)1277 void DeviceManagerNapi::JsToDmDiscoveryExtra(const napi_env &env, const napi_value &object, std::string &extra)
1278 {
1279     napi_valuetype valueType1 = napi_undefined;
1280     napi_typeof(env, object, &valueType1);
1281     if (valueType1 == napi_undefined) {
1282         extra = "";
1283         return;
1284     }
1285     char filterOption[DM_NAPI_BUF_LENGTH] = {0};
1286     size_t typeLen = 0;
1287     NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, object, nullptr, 0, &typeLen));
1288     if (!CheckArgsVal(env, typeLen > 0, "extra", "typeLen == 0")) {
1289         return;
1290     }
1291 
1292     if (!CheckArgsVal(env, typeLen < DM_NAPI_BUF_LENGTH, "extra", "typeLen >= BUF_MAX_LENGTH")) {
1293         return;
1294     }
1295     NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, object, filterOption, typeLen + 1, &typeLen));
1296     extra = filterOption;
1297     LOGI("JsToDmDiscoveryExtra, extra :%{public}s, typeLen : %{public}zu", extra.c_str(), typeLen);
1298 }
1299 
IsSystemApp()1300 bool DeviceManagerNapi::IsSystemApp()
1301 {
1302     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1303     return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1304 }
1305 
DmDeviceInfotoJsDeviceInfo(const napi_env & env,const DmDeviceInfo & vecDevInfo,napi_value & result)1306 void DeviceManagerNapi::DmDeviceInfotoJsDeviceInfo(const napi_env &env, const DmDeviceInfo &vecDevInfo,
1307                                                    napi_value &result)
1308 {
1309     napi_create_object(env, &result);
1310 
1311     SetValueUtf8String(env, "deviceId", vecDevInfo.deviceId, result);
1312     SetValueUtf8String(env, "networkId", vecDevInfo.networkId, result);
1313     SetValueUtf8String(env, "deviceName", vecDevInfo.deviceName, result);
1314     SetValueInt32(env, "deviceType", (int)vecDevInfo.deviceTypeId, result);
1315 }
1316 
RegisterDevStateCallback(napi_env env,std::string & bundleName)1317 void DeviceManagerNapi::RegisterDevStateCallback(napi_env env, std::string &bundleName)
1318 {
1319     LOGI("RegisterDevStateCallback start bundleName %{public}s", bundleName.c_str());
1320     auto callback = std::make_shared<DmNapiDeviceStateCallback>(env, bundleName);
1321     std::string extra = "";
1322     int32_t ret = DeviceManager::GetInstance().RegisterDevStateCallback(bundleName, extra, callback);
1323     if (ret != 0) {
1324         LOGE("RegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1325         return;
1326     }
1327     {
1328         std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1329         g_deviceStateCallbackMap[bundleName] = callback;
1330     }
1331     return;
1332 }
1333 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType)1334 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType)
1335 {
1336     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s", bundleName.c_str(), eventType.c_str());
1337     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1338         RegisterDevStateCallback(env, bundleName);
1339         return;
1340     }
1341 
1342     if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL) {
1343         auto callback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
1344         {
1345             std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1346             g_DiscoveryCallbackMap[bundleName] = callback;
1347         }
1348         std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = callback;
1349         discoveryCallback->IncreaseRefCount();
1350         return;
1351     }
1352 
1353     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
1354         auto callback = std::make_shared<DmNapiPublishCallback>(env, bundleName);
1355         {
1356             std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1357             g_publishCallbackMap[bundleName] = callback;
1358         }
1359         std::shared_ptr<DmNapiPublishCallback> publishCallback = callback;
1360         publishCallback->IncreaseRefCount();
1361         return;
1362     }
1363 
1364     if (eventType == DM_NAPI_EVENT_UI_STATE_CHANGE) {
1365         auto callback = std::make_shared<DmNapiDeviceManagerUiCallback>(env, bundleName);
1366         int32_t ret = DeviceManager::GetInstance().RegisterDeviceManagerFaCallback(bundleName, callback);
1367         if (ret != 0) {
1368             LOGE("RegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
1369             return;
1370         }
1371         {
1372             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1373             g_dmUiCallbackMap[bundleName] = callback;
1374         }
1375     }
1376 }
1377 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType,std::string & extra)1378 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName,
1379                                          std::string &eventType, std::string &extra)
1380 {
1381     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s extra = %{public}s",
1382          bundleName.c_str(), eventType.c_str(), extra.c_str());
1383     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1384         auto callback = std::make_shared<DmNapiDeviceStateCallback>(env, bundleName);
1385         int32_t ret = DeviceManager::GetInstance().RegisterDevStateCallback(bundleName, extra, callback);
1386         if (ret != 0) {
1387             LOGE("RegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1388             return;
1389         }
1390         {
1391             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1392             g_deviceStateCallbackMap[bundleName] = callback;
1393         }
1394     }
1395 }
1396 
ReleasePublishCallback(std::string & bundleName)1397 void DeviceManagerNapi::ReleasePublishCallback(std::string &bundleName)
1398 {
1399     LOGI("ReleasePublishCallback for bundleName %{public}s", bundleName.c_str());
1400     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
1401     {
1402         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1403         auto iter = g_publishCallbackMap.find(bundleName);
1404         if (iter == g_publishCallbackMap.end()) {
1405             return;
1406         }
1407         publishCallback = iter->second;
1408     }
1409     publishCallback->DecreaseRefCount();
1410     if (publishCallback->GetRefCount() == 0) {
1411         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1412         g_publishCallbackMap.erase(bundleName);
1413     }
1414     return;
1415 }
1416 
ReleaseDiscoveryCallback(std::string & bundleName)1417 void DeviceManagerNapi::ReleaseDiscoveryCallback(std::string &bundleName)
1418 {
1419     LOGI("ReleaseDiscoveryCallback for bundleName %{public}s", bundleName.c_str());
1420     std::shared_ptr<DmNapiDiscoveryCallback> DiscoveryCallback = nullptr;
1421     {
1422         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1423         auto iter = g_DiscoveryCallbackMap.find(bundleName);
1424         if (iter == g_DiscoveryCallbackMap.end()) {
1425             return;
1426         }
1427         DiscoveryCallback = iter->second;
1428     }
1429     DiscoveryCallback->DecreaseRefCount();
1430     if (DiscoveryCallback->GetRefCount() == 0) {
1431         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1432         g_DiscoveryCallbackMap.erase(bundleName);
1433     }
1434     return;
1435 }
1436 
ReleaseDmCallback(std::string & bundleName,std::string & eventType)1437 void DeviceManagerNapi::ReleaseDmCallback(std::string &bundleName, std::string &eventType)
1438 {
1439     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1440         {
1441             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1442             auto iter = g_deviceStateCallbackMap.find(bundleName);
1443             if (iter == g_deviceStateCallbackMap.end()) {
1444                 LOGE("ReleaseDmCallback: cannot find stateCallback for bundleName %{public}s", bundleName.c_str());
1445                 return;
1446             }
1447         }
1448         int32_t ret = DeviceManager::GetInstance().UnRegisterDevStateCallback(bundleName);
1449         if (ret != 0) {
1450             LOGE("UnRegisterDevStateCallback failed for bundleName %{public}s", bundleName.c_str());
1451             return;
1452         }
1453         {
1454             std::lock_guard<std::mutex> autoLock(g_deviceStateCallbackMapMutex);
1455             g_deviceStateCallbackMap.erase(bundleName);
1456         }
1457         return;
1458     }
1459 
1460     if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVERY_FAIL) {
1461         ReleaseDiscoveryCallback(bundleName);
1462         return;
1463     }
1464 
1465     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
1466         ReleasePublishCallback(bundleName);
1467         return;
1468     }
1469 
1470     if (eventType == DM_NAPI_EVENT_UI_STATE_CHANGE) {
1471         {
1472             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1473             auto iter = g_dmUiCallbackMap.find(bundleName);
1474             if (iter == g_dmUiCallbackMap.end()) {
1475                 LOGE("cannot find dmFaCallback for bundleName %{public}s", bundleName.c_str());
1476                 return;
1477             }
1478         }
1479         int32_t ret = DeviceManager::GetInstance().UnRegisterDeviceManagerFaCallback(bundleName);
1480         if (ret != 0) {
1481             LOGE("UnRegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
1482             return;
1483         }
1484         std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1485         g_dmUiCallbackMap.erase(bundleName);
1486         return;
1487     }
1488 }
1489 
SetUserOperationSync(napi_env env,napi_callback_info info)1490 napi_value DeviceManagerNapi::SetUserOperationSync(napi_env env, napi_callback_info info)
1491 {
1492     LOGI("SetUserOperationSync in");
1493     if (!IsSystemApp()) {
1494         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
1495         return nullptr;
1496     }
1497     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1498     napi_valuetype valueType;
1499     napi_typeof(env, argv[0], &valueType);
1500     if (!CheckArgsType(env, valueType == napi_number, "action", "number")) {
1501         return nullptr;
1502     }
1503 
1504     napi_valuetype strType;
1505     napi_typeof(env, argv[1], &strType);
1506     NAPI_ASSERT(env, strType == napi_string, "Wrong argument type, string expected.");
1507 
1508     int32_t action = 0;
1509     napi_get_value_int32(env, argv[0], &action);
1510 
1511     size_t typeLen = 0;
1512     napi_get_value_string_utf8(env, argv[1], nullptr, 0, &typeLen);
1513     NAPI_ASSERT(env, typeLen > 0, "typeLen == 0");
1514     NAPI_ASSERT(env, typeLen < DM_NAPI_BUF_LENGTH, "typeLen >= MAXLEN");
1515     char type[DM_NAPI_BUF_LENGTH] = {0};
1516     napi_get_value_string_utf8(env, argv[1], type, typeLen + 1, &typeLen);
1517 
1518     std::string params = type;
1519     napi_value result = nullptr;
1520     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1521     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1522         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1523         return result;
1524     }
1525     int32_t ret = DeviceManager::GetInstance().SetUserOperation(deviceManagerWrapper->bundleName_, action, params);
1526     if (ret != 0) {
1527         LOGE("SetUserOperation for bundleName %{public}s failed, ret %{public}d",
1528             deviceManagerWrapper->bundleName_.c_str(), ret);
1529         CreateBusinessError(env, ret);
1530     }
1531     napi_get_undefined(env, &result);
1532     return result;
1533 }
1534 
CallGetTrustedDeviceListStatusSync(napi_env env,napi_status & status,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1535 void DeviceManagerNapi::CallGetTrustedDeviceListStatusSync(napi_env env, napi_status &status,
1536     DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1537 {
1538     CHECK_NULL_VOID(deviceInfoListAsyncCallbackInfo);
1539     if (deviceInfoListAsyncCallbackInfo->devList.size() > DM_MAX_DEVICE_SIZE) {
1540         LOGE("CallGetTrustedDeviceListStatusSync invalid devList size");
1541         return;
1542     }
1543     for (unsigned int i = 0; i < deviceInfoListAsyncCallbackInfo->devList.size(); i++) {
1544         LOGI("DeviceManager::GetTrustedDeviceList deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1545              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1546              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1547              deviceInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1548     }
1549 
1550     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1551     if (deviceInfoListAsyncCallbackInfo->status == 0) {
1552         bool isArray = false;
1553         napi_create_array(env, &array[1]);
1554         napi_is_array(env, array[1], &isArray);
1555         if (!isArray) {
1556             LOGE("napi_create_array fail");
1557         }
1558         if (deviceInfoListAsyncCallbackInfo->devList.size() > 0) {
1559             for (unsigned int i = 0; i != deviceInfoListAsyncCallbackInfo->devList.size(); ++i) {
1560                 DeviceInfoToJsArray(env, deviceInfoListAsyncCallbackInfo->devList, (int32_t)i, array[1]);
1561             }
1562             LOGI("devList is OK");
1563         } else {
1564             LOGE("devList is null");
1565         }
1566         napi_resolve_deferred(env, deviceInfoListAsyncCallbackInfo->deferred, array[1]);
1567     } else {
1568         array[0] = CreateBusinessError(env, deviceInfoListAsyncCallbackInfo->ret, false);
1569         napi_reject_deferred(env, deviceInfoListAsyncCallbackInfo->deferred, array[0]);
1570     }
1571 }
1572 
OnCall(const std::string & paramJson)1573 void DmNapiDeviceManagerUiCallback::OnCall(const std::string &paramJson)
1574 {
1575     uv_loop_s *loop = nullptr;
1576     napi_get_uv_event_loop(env_, &loop);
1577     if (loop == nullptr) {
1578         return;
1579     }
1580     uv_work_t *work = new (std::nothrow) uv_work_t;
1581     if (work == nullptr) {
1582         LOGE("DmNapiDeviceManagerUiCallback: OnCall, No memory");
1583         return;
1584     }
1585 
1586     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, "", paramJson, 0, 0);
1587     if (jsCallback == nullptr) {
1588         DeleteUvWork(work);
1589         return;
1590     }
1591     work->data = reinterpret_cast<void *>(jsCallback);
1592 
1593     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
1594         LOGD("OnCall uv_queue_work_with_qos");
1595     }, [] (uv_work_t *work, int status) {
1596         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
1597         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
1598         if (deviceManagerNapi == nullptr) {
1599             LOGE("OnCall, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
1600         } else {
1601             deviceManagerNapi->OnDmUiCall(callback->token_);
1602         }
1603         delete callback;
1604         callback = nullptr;
1605         DeleteUvWork(work);
1606     }, uv_qos_user_initiated);
1607     if (ret != 0) {
1608         LOGE("Failed to execute OnCall work queue");
1609         delete jsCallback;
1610         jsCallback = nullptr;
1611         DeleteUvWork(work);
1612     }
1613 }
1614 
OnDmUiCall(const std::string & paramJson)1615 void DeviceManagerNapi::OnDmUiCall(const std::string &paramJson)
1616 {
1617     LOGI("OnCall for paramJson");
1618     napi_handle_scope scope;
1619     napi_open_handle_scope(env_, &scope);
1620     napi_value result;
1621     napi_create_object(env_, &result);
1622     SetValueUtf8String(env_, "param", paramJson, result);
1623     OnEvent(DM_NAPI_EVENT_UI_STATE_CHANGE, DM_NAPI_ARGS_ONE, &result);
1624     napi_close_handle_scope(env_, scope);
1625 }
1626 
CallGetTrustedDeviceListStatus(napi_env env,napi_status & status,DeviceInfoListAsyncCallbackInfo * deviceInfoListAsyncCallbackInfo)1627 void DeviceManagerNapi::CallGetTrustedDeviceListStatus(napi_env env, napi_status &status,
1628                                                        DeviceInfoListAsyncCallbackInfo *deviceInfoListAsyncCallbackInfo)
1629 {
1630     CHECK_NULL_VOID(deviceInfoListAsyncCallbackInfo);
1631     if (deviceInfoListAsyncCallbackInfo->devList.size() > DM_MAX_DEVICE_SIZE) {
1632         LOGE("CallGetTrustedDeviceListStatus invalid devList size");
1633         return;
1634     }
1635     for (unsigned int i = 0; i < deviceInfoListAsyncCallbackInfo->devList.size(); i++) {
1636         LOGI("DeviceManager::GetTrustedDeviceList deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1637              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1638              GetAnonyString(deviceInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1639              deviceInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1640     }
1641     napi_value callResult = nullptr;
1642     napi_value handler = nullptr;
1643     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1644 
1645     if (deviceInfoListAsyncCallbackInfo->status == 0) {
1646         if (deviceInfoListAsyncCallbackInfo->devList.size() > 0) {
1647             bool isArray = false;
1648             NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &array[1]));
1649             NAPI_CALL_RETURN_VOID(env, napi_is_array(env, array[1], &isArray));
1650             if (!isArray) {
1651                 LOGE("napi_create_array fail");
1652             }
1653             for (size_t i = 0; i != deviceInfoListAsyncCallbackInfo->devList.size(); ++i) {
1654                 DeviceInfoToJsArray(env, deviceInfoListAsyncCallbackInfo->devList, i, array[1]);
1655             }
1656             LOGI("devList is OK");
1657         } else {
1658             LOGE("devList is null");
1659         }
1660     } else {
1661         array[0] = CreateBusinessError(env, deviceInfoListAsyncCallbackInfo->ret, false);
1662     }
1663 
1664     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceInfoListAsyncCallbackInfo->callback, &handler));
1665     if (handler != nullptr) {
1666         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO, &array[0], &callResult));
1667         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceInfoListAsyncCallbackInfo->callback));
1668         deviceInfoListAsyncCallbackInfo->callback = nullptr;
1669     } else {
1670         LOGE("handler is nullptr");
1671     }
1672 }
1673 
CallRequestCreInfoStatus(napi_env env,napi_status & status,CredentialAsyncCallbackInfo * creAsyncCallbackInfo)1674 void DeviceManagerNapi::CallRequestCreInfoStatus(napi_env env, napi_status &status,
1675                                                  CredentialAsyncCallbackInfo *creAsyncCallbackInfo)
1676 {
1677     LOGI("DeviceManager::RequestCredential");
1678     napi_value callResult = nullptr;
1679     napi_value handler = nullptr;
1680     napi_value result = nullptr;
1681     napi_create_object(env, &result);
1682 
1683     if (creAsyncCallbackInfo->status == 0) {
1684         if (creAsyncCallbackInfo->returnJsonStr == "") {
1685             LOGE("creAsyncCallbackInfo returnJsonStr is null");
1686         }
1687         SetValueUtf8String(env, "registerInfo", creAsyncCallbackInfo->returnJsonStr, result);
1688     } else {
1689         result = CreateBusinessError(env, creAsyncCallbackInfo->ret, false);
1690     }
1691 
1692     napi_get_reference_value(env, creAsyncCallbackInfo->callback, &handler);
1693     if (handler != nullptr) {
1694         napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_ONE, &result, &callResult);
1695         napi_delete_reference(env, creAsyncCallbackInfo->callback);
1696         creAsyncCallbackInfo->callback = nullptr;
1697     } else {
1698         LOGE("handler is nullptr");
1699     }
1700 }
1701 
CallGetLocalDeviceInfoSync(napi_env env,napi_status & status,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1702 void DeviceManagerNapi::CallGetLocalDeviceInfoSync(napi_env env, napi_status &status,
1703                                                    DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1704 {
1705     napi_value result[DM_NAPI_ARGS_TWO] = {0};
1706 
1707     LOGI("DeviceManager::CallGetLocalDeviceInfoSync deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1708          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceId).c_str(),
1709          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
1710          deviceInfoAsyncCallbackInfo->deviceInfo.deviceTypeId);
1711 
1712     if (deviceInfoAsyncCallbackInfo->status == 0) {
1713         DmDeviceInfotoJsDeviceInfo(env, deviceInfoAsyncCallbackInfo->deviceInfo, result[1]);
1714         napi_resolve_deferred(env, deviceInfoAsyncCallbackInfo->deferred, result[1]);
1715     } else {
1716         result[0] = CreateBusinessError(env, deviceInfoAsyncCallbackInfo->ret, false);
1717         napi_reject_deferred(env, deviceInfoAsyncCallbackInfo->deferred, result[0]);
1718     }
1719 }
1720 
CallGetLocalDeviceInfo(napi_env env,napi_status & status,DeviceInfoAsyncCallbackInfo * deviceInfoAsyncCallbackInfo)1721 void DeviceManagerNapi::CallGetLocalDeviceInfo(napi_env env, napi_status &status,
1722                                                DeviceInfoAsyncCallbackInfo *deviceInfoAsyncCallbackInfo)
1723 {
1724     napi_value result[DM_NAPI_ARGS_TWO] = {0};
1725     LOGI("DeviceManager::CallGetLocalDeviceInfo deviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1726          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceId).c_str(),
1727          GetAnonyString(deviceInfoAsyncCallbackInfo->deviceInfo.deviceName).c_str(),
1728          deviceInfoAsyncCallbackInfo->deviceInfo.deviceTypeId);
1729     napi_value callResult = nullptr;
1730     napi_value handler = nullptr;
1731 
1732     if (deviceInfoAsyncCallbackInfo->status == 0) {
1733         DmDeviceInfotoJsDeviceInfo(env, deviceInfoAsyncCallbackInfo->deviceInfo, result[1]);
1734     } else {
1735         result[0] = CreateBusinessError(env, deviceInfoAsyncCallbackInfo->ret, false);
1736     }
1737 
1738     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceInfoAsyncCallbackInfo->callback, &handler));
1739     if (handler != nullptr) {
1740         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO,
1741             &result[0], &callResult));
1742         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceInfoAsyncCallbackInfo->callback));
1743         deviceInfoAsyncCallbackInfo->callback = nullptr;
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         networkIdAsyncCallbackInfo->callback = nullptr;
3078     } else {
3079         LOGE("handler is nullptr");
3080     }
3081 }
3082 
DeviceInfotoJsByNetworkId(const napi_env & env,const DmDeviceInfo & nidDevInfo,napi_value & result)3083 void DeviceManagerNapi::DeviceInfotoJsByNetworkId(const napi_env &env, const DmDeviceInfo &nidDevInfo,
3084                                                   napi_value &result)
3085 {
3086     napi_create_object(env, &result);
3087 
3088     SetValueUtf8String(env, "deviceName", nidDevInfo.deviceName, result);
3089     SetValueInt32(env, "deviceType", (int)nidDevInfo.deviceTypeId, result);
3090 }
3091 
JsToStringAndCheck(napi_env env,napi_value value,const std::string & valueName,std::string & strValue)3092 bool DeviceManagerNapi::JsToStringAndCheck(napi_env env, napi_value value, const std::string &valueName,
3093                                            std::string &strValue)
3094 {
3095     napi_valuetype deviceIdType = napi_undefined;
3096     napi_typeof(env, value, &deviceIdType);
3097     if (!CheckArgsType(env, deviceIdType == napi_string, valueName, "string")) {
3098         return false;
3099     }
3100     size_t valueLen = 0;
3101     napi_get_value_string_utf8(env, value, nullptr, 0, &valueLen);
3102     if (!CheckArgsVal(env, valueLen > 0, valueName, "len == 0")) {
3103         return false;
3104     }
3105     if (!CheckArgsVal(env, valueLen < DM_NAPI_BUF_LENGTH, valueName, "len >= MAXLEN")) {
3106         return false;
3107     }
3108     char temp[DM_NAPI_BUF_LENGTH] = {0};
3109     napi_get_value_string_utf8(env, value, temp, valueLen + 1, &valueLen);
3110     strValue = temp;
3111     return true;
3112 }
3113 
GetDeviceInfo(napi_env env,napi_callback_info info)3114 napi_value DeviceManagerNapi::GetDeviceInfo(napi_env env, napi_callback_info info)
3115 {
3116     if (!IsSystemApp()) {
3117         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
3118         return nullptr;
3119     }
3120     napi_value result = nullptr;
3121     size_t argc = 2;
3122     napi_value argv[2] = {nullptr};
3123     napi_value thisVar = nullptr;
3124     DmDeviceInfo deviceInfo;
3125     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
3126     NAPI_ASSERT(env, ((argc >= DM_NAPI_ARGS_ONE) && (argc <= DM_NAPI_ARGS_TWO)), "requires 1 or 2 parameter");
3127 
3128     std::string networkId;
3129     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
3130         return nullptr;
3131     }
3132     DeviceManagerNapi *deviceManagerWrapper = nullptr;
3133     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
3134         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
3135         return result;
3136     }
3137     auto *networkIdAsyncCallbackInfo = new NetworkIdAsyncCallbackInfo();
3138     networkIdAsyncCallbackInfo->env = env;
3139     networkIdAsyncCallbackInfo->deviceInfo = deviceInfo;
3140     networkIdAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
3141     networkIdAsyncCallbackInfo->networkId = networkId;
3142 
3143     if (argc == DM_NAPI_ARGS_ONE) {    // promise
3144         napi_deferred deferred;
3145         napi_value promise = 0;
3146         napi_create_promise(env, &deferred, &promise);
3147         networkIdAsyncCallbackInfo->deferred = deferred;
3148         CallGetDeviceInfo(env, networkIdAsyncCallbackInfo);
3149         return promise;
3150     } else if (argc == DM_NAPI_ARGS_TWO) {    // callback
3151         if (!IsFunctionType(env, argv[1])) {
3152             delete networkIdAsyncCallbackInfo;
3153             networkIdAsyncCallbackInfo = nullptr;
3154             return nullptr;
3155         }
3156         napi_create_reference(env, argv[1], 1, &networkIdAsyncCallbackInfo->callback);
3157         CallGetDeviceInfo(env, networkIdAsyncCallbackInfo);
3158     }
3159     napi_get_undefined(env, &result);
3160     return result;
3161 }
CreateDeviceManager(napi_env env,napi_callback_info info)3162 napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info)
3163 {
3164     LOGI("CreateDeviceManager in");
3165     if (!IsSystemApp()) {
3166         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
3167         return nullptr;
3168     }
3169     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
3170 
3171     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
3172         return nullptr;
3173     }
3174 
3175     napi_valuetype bundleNameValueType = napi_undefined;
3176     napi_typeof(env, argv[0], &bundleNameValueType);
3177     if (!CheckArgsType(env, bundleNameValueType == napi_string, "bundleName", "string")) {
3178         return nullptr;
3179     }
3180 
3181     napi_valuetype funcValueType = napi_undefined;
3182     napi_typeof(env, argv[1], &funcValueType);
3183     if (!CheckArgsType(env, funcValueType == napi_function, "callback", "function")) {
3184         return nullptr;
3185     }
3186 
3187     auto *asCallbackInfo = new AsyncCallbackInfo();
3188     if (asCallbackInfo == nullptr) {
3189         return nullptr;
3190     }
3191     asCallbackInfo->env = env;
3192     napi_get_value_string_utf8(env, argv[0], asCallbackInfo->bundleName, DM_NAPI_BUF_LENGTH - 1,
3193                                &asCallbackInfo->bundleNameLen);
3194 
3195     napi_create_reference(env, argv[1], 1, &asCallbackInfo->callback);
3196 
3197     HandleCreateDmCallBack(env, asCallbackInfo);
3198 
3199     napi_value result = nullptr;
3200     napi_get_undefined(env, &result);
3201     return result;
3202 }
3203 
Constructor(napi_env env,napi_callback_info info)3204 napi_value DeviceManagerNapi::Constructor(napi_env env, napi_callback_info info)
3205 {
3206     LOGI("DeviceManagerNapi Constructor in");
3207     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
3208     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
3209         return nullptr;
3210     }
3211 
3212     napi_valuetype valueType = napi_undefined;
3213     napi_typeof(env, argv[0], &valueType);
3214     if (!CheckArgsType(env, valueType == napi_string, "bundleName", "string")) {
3215         return nullptr;
3216     }
3217 
3218     char bundleName[DM_NAPI_BUF_LENGTH] = {0};
3219     size_t typeLen = 0;
3220     napi_get_value_string_utf8(env, argv[0], bundleName, sizeof(bundleName), &typeLen);
3221 
3222     LOGI("create DeviceManagerNapi for packageName:%{public}s", GetAnonyString(bundleName).c_str());
3223     DeviceManagerNapi *obj = new DeviceManagerNapi(env, thisVar);
3224     if (obj == nullptr) {
3225         return nullptr;
3226     }
3227 
3228     obj->bundleName_ = std::string(bundleName);
3229     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
3230     g_deviceManagerMap[obj->bundleName_] = obj;
3231     napi_status status = napi_wrap(
3232         env, thisVar, reinterpret_cast<void *>(obj),
3233         [](napi_env env, void *data, void *hint) {
3234             (void)env;
3235             (void)hint;
3236             DeviceManagerNapi *deviceManager = reinterpret_cast<DeviceManagerNapi *>(data);
3237             delete deviceManager;
3238             deviceManager = nullptr;
3239             LOGI("delete deviceManager");
3240         },
3241         nullptr, nullptr);
3242     if (status != napi_ok) {
3243         delete obj;
3244         obj = nullptr;
3245         LOGE("failed to wrap JS object");
3246         return nullptr;
3247     }
3248     return thisVar;
3249 }
3250 
Init(napi_env env,napi_value exports)3251 napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports)
3252 {
3253     napi_value dmClass = nullptr;
3254     napi_property_descriptor dmProperties[] = {
3255         DECLARE_NAPI_FUNCTION("release", ReleaseDeviceManager),
3256         DECLARE_NAPI_FUNCTION("getTrustedDeviceListSync", GetTrustedDeviceListSync),
3257         DECLARE_NAPI_FUNCTION("getTrustedDeviceList", GetTrustedDeviceList),
3258         DECLARE_NAPI_FUNCTION("startDeviceDiscovery", StartDeviceDiscoverSync),
3259         DECLARE_NAPI_FUNCTION("stopDeviceDiscovery", StopDeviceDiscoverSync),
3260         DECLARE_NAPI_FUNCTION("publishDeviceDiscovery", PublishDeviceDiscoverySync),
3261         DECLARE_NAPI_FUNCTION("unPublishDeviceDiscovery", UnPublishDeviceDiscoverySync),
3262         DECLARE_NAPI_FUNCTION("getLocalDeviceInfoSync", GetLocalDeviceInfoSync),
3263         DECLARE_NAPI_FUNCTION("getLocalDeviceInfo", GetLocalDeviceInfo),
3264         DECLARE_NAPI_FUNCTION("getDeviceInfo", GetDeviceInfo),
3265         DECLARE_NAPI_FUNCTION("unAuthenticateDevice", UnAuthenticateDevice),
3266         DECLARE_NAPI_FUNCTION("authenticateDevice", AuthenticateDevice),
3267         DECLARE_NAPI_FUNCTION("setUserOperation", SetUserOperationSync),
3268         DECLARE_NAPI_FUNCTION("requestCredentialRegisterInfo", RequestCredential),
3269         DECLARE_NAPI_FUNCTION("importCredential", ImportCredential),
3270         DECLARE_NAPI_FUNCTION("deleteCredential", DeleteCredential),
3271         DECLARE_NAPI_FUNCTION("on", JsOn),
3272         DECLARE_NAPI_FUNCTION("off", JsOff)};
3273 
3274     napi_property_descriptor static_prop[] = {
3275         DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager),
3276     };
3277 
3278     LOGI("DeviceManagerNapi::Init() is called!");
3279     NAPI_CALL(env, napi_define_class(env, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor,
3280                                      nullptr, sizeof(dmProperties) / sizeof(dmProperties[0]), dmProperties, &dmClass));
3281     NAPI_CALL(env, napi_create_reference(env, dmClass, 1, &sConstructor_));
3282     NAPI_CALL(env, napi_set_named_property(env, exports, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), dmClass));
3283     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop));
3284     LOGI("All props and functions are configured..");
3285     return exports;
3286 }
3287 
EnumTypeConstructor(napi_env env,napi_callback_info info)3288 napi_value DeviceManagerNapi::EnumTypeConstructor(napi_env env, napi_callback_info info)
3289 {
3290     size_t argc = 0;
3291     napi_value res = nullptr;
3292     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &res, nullptr));
3293     return res;
3294 }
3295 
InitDeviceTypeEnum(napi_env env,napi_value exports)3296 napi_value DeviceManagerNapi::InitDeviceTypeEnum(napi_env env, napi_value exports)
3297 {
3298     napi_value unknown_type;
3299     napi_value speaker;
3300     napi_value phone;
3301     napi_value tablet;
3302     napi_value wearable;
3303     napi_value car;
3304     napi_value tv;
3305     int32_t refCount = 1;
3306 
3307     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_UNKNOWN),
3308         &unknown_type);
3309     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_AUDIO),
3310         &speaker);
3311     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_PHONE),
3312         &phone);
3313     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_PAD),
3314         &tablet);
3315     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_WATCH),
3316         &wearable);
3317     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_CAR),
3318         &car);
3319     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceType::DEVICE_TYPE_TV),
3320         &tv);
3321 
3322     napi_property_descriptor desc[] = {
3323         DECLARE_NAPI_STATIC_PROPERTY("UNKNOWN_TYPE", unknown_type),
3324         DECLARE_NAPI_STATIC_PROPERTY("SPEAKER", speaker),
3325         DECLARE_NAPI_STATIC_PROPERTY("PHONE", phone),
3326         DECLARE_NAPI_STATIC_PROPERTY("TABLET", tablet),
3327         DECLARE_NAPI_STATIC_PROPERTY("WEARABLE", wearable),
3328         DECLARE_NAPI_STATIC_PROPERTY("CAR", car),
3329         DECLARE_NAPI_STATIC_PROPERTY("TV", tv),
3330     };
3331 
3332     napi_value result = nullptr;
3333     napi_define_class(env, "DeviceType", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3334         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3335     napi_create_reference(env, result, refCount, &deviceTypeEnumConstructor_);
3336     napi_set_named_property(env, exports, "DeviceType", result);
3337     return exports;
3338 }
3339 
InitDeviceStateChangeActionEnum(napi_env env,napi_value exports)3340 napi_value DeviceManagerNapi::InitDeviceStateChangeActionEnum(napi_env env, napi_value exports)
3341 {
3342     napi_value device_state_online;
3343     napi_value device_state_ready;
3344     napi_value device_state_offline;
3345     napi_value device_state_change;
3346     int32_t refCount = 1;
3347 
3348     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_ONLINE),
3349         &device_state_online);
3350     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_READY),
3351         &device_state_ready);
3352     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_OFFLINE),
3353         &device_state_offline);
3354     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_CHANGED),
3355         &device_state_change);
3356 
3357     napi_property_descriptor desc[] = {
3358         DECLARE_NAPI_STATIC_PROPERTY("ONLINE", device_state_online),
3359         DECLARE_NAPI_STATIC_PROPERTY("READY", device_state_ready),
3360         DECLARE_NAPI_STATIC_PROPERTY("OFFLINE", device_state_offline),
3361         DECLARE_NAPI_STATIC_PROPERTY("CHANGE", device_state_change),
3362     };
3363 
3364     napi_value result = nullptr;
3365     napi_define_class(env, "DeviceStateChangeAction", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3366         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3367     napi_create_reference(env, result, refCount, &deviceStateChangeActionEnumConstructor_);
3368     napi_set_named_property(env, exports, "DeviceStateChangeAction", result);
3369     return exports;
3370 }
3371 
InitDiscoverModeEnum(napi_env env,napi_value exports)3372 napi_value DeviceManagerNapi::InitDiscoverModeEnum(napi_env env, napi_value exports)
3373 {
3374     napi_value discover_mode_passive;
3375     napi_value discover_mode_active;
3376     int32_t refCount = 1;
3377 
3378     napi_create_uint32(env, static_cast<uint32_t>(DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE),
3379         &discover_mode_passive);
3380     napi_create_uint32(env, static_cast<uint32_t>(DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE),
3381         &discover_mode_active);
3382 
3383     napi_property_descriptor desc[] = {
3384         DECLARE_NAPI_STATIC_PROPERTY("DISCOVER_MODE_PASSIVE", discover_mode_passive),
3385         DECLARE_NAPI_STATIC_PROPERTY("DISCOVER_MODE_ACTIVE", discover_mode_active),
3386     };
3387 
3388     napi_value result = nullptr;
3389     napi_define_class(env, "DiscoverMode", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3390         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3391     napi_create_reference(env, result, refCount, &discoverModeEnumConstructor_);
3392     napi_set_named_property(env, exports, "DiscoverMode", result);
3393     return exports;
3394 }
3395 
InitExchangeMediumEnum(napi_env env,napi_value exports)3396 napi_value DeviceManagerNapi::InitExchangeMediumEnum(napi_env env, napi_value exports)
3397 {
3398     napi_value medium_auto;
3399     napi_value medium_ble;
3400     napi_value medium_coap;
3401     napi_value medium_usb;
3402     int32_t refCount = 1;
3403 
3404     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_AUTO),
3405         &medium_auto);
3406     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_BLE),
3407         &medium_ble);
3408     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_COAP),
3409         &medium_coap);
3410     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeMedium::DM_USB),
3411         &medium_usb);
3412 
3413     napi_property_descriptor desc[] = {
3414         DECLARE_NAPI_STATIC_PROPERTY("AUTO", medium_auto),
3415         DECLARE_NAPI_STATIC_PROPERTY("BLE", medium_ble),
3416         DECLARE_NAPI_STATIC_PROPERTY("COAP", medium_coap),
3417         DECLARE_NAPI_STATIC_PROPERTY("USB", medium_usb),
3418     };
3419 
3420     napi_value result = nullptr;
3421     napi_define_class(env, "ExchangeMedium", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3422         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3423     napi_create_reference(env, result, refCount, &exchangeMediumEnumConstructor_);
3424     napi_set_named_property(env, exports, "ExchangeMedium", result);
3425     return exports;
3426 }
3427 
InitExchangeFreqEnum(napi_env env,napi_value exports)3428 napi_value DeviceManagerNapi::InitExchangeFreqEnum(napi_env env, napi_value exports)
3429 {
3430     napi_value low;
3431     napi_value mid;
3432     napi_value high;
3433     napi_value super_high;
3434     int32_t refCount = 1;
3435 
3436     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_LOW),
3437         &low);
3438     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_MID),
3439         &mid);
3440     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_HIGH),
3441         &high);
3442     napi_create_uint32(env, static_cast<uint32_t>(DmExchangeFreq::DM_SUPER_HIGH),
3443         &super_high);
3444 
3445     napi_property_descriptor desc[] = {
3446         DECLARE_NAPI_STATIC_PROPERTY("LOW", low),
3447         DECLARE_NAPI_STATIC_PROPERTY("MID", mid),
3448         DECLARE_NAPI_STATIC_PROPERTY("HIGH", high),
3449         DECLARE_NAPI_STATIC_PROPERTY("SUPER_HIGH", super_high),
3450     };
3451 
3452     napi_value result = nullptr;
3453     napi_define_class(env, "ExchangeFreq", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3454         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3455     napi_create_reference(env, result, refCount, &exchangeFreqEnumConstructor_);
3456     napi_set_named_property(env, exports, "ExchangeFreq", result);
3457     return exports;
3458 }
3459 
InitSubscribeCapEnum(napi_env env,napi_value exports)3460 napi_value DeviceManagerNapi::InitSubscribeCapEnum(napi_env env, napi_value exports)
3461 {
3462     napi_value subscribe_capability_ddmp;
3463     napi_value subscribe_capability_osd;
3464     int32_t refCount = 1;
3465 
3466     napi_create_uint32(env, static_cast<uint32_t>(DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP),
3467         &subscribe_capability_ddmp);
3468     napi_create_uint32(env, static_cast<uint32_t>(DM_NAPI_SUBSCRIBE_CAPABILITY_OSD),
3469         &subscribe_capability_osd);
3470 
3471     napi_property_descriptor desc[] = {
3472         DECLARE_NAPI_STATIC_PROPERTY("SUBSCRIBE_CAPABILITY_DDMP", subscribe_capability_ddmp),
3473         DECLARE_NAPI_STATIC_PROPERTY("SUBSCRIBE_CAPABILITY_OSD", subscribe_capability_osd),
3474     };
3475 
3476     napi_value result = nullptr;
3477     napi_define_class(env, "SubscribeCap", NAPI_AUTO_LENGTH, EnumTypeConstructor,
3478         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
3479     napi_create_reference(env, result, refCount, &subscribeCapEnumConstructor_);
3480     napi_set_named_property(env, exports, "SubscribeCap", result);
3481     return exports;
3482 }
3483 
3484 /*
3485  * Function registering all props and functions of ohos.distributedhardware
3486  */
Export(napi_env env,napi_value exports)3487 static napi_value Export(napi_env env, napi_value exports)
3488 {
3489     LOGI("Export() is called!");
3490     DeviceManagerNapi::Init(env, exports);
3491     DeviceManagerNapi::InitDeviceTypeEnum(env, exports);
3492     DeviceManagerNapi::InitDeviceStateChangeActionEnum(env, exports);
3493     DeviceManagerNapi::InitDiscoverModeEnum(env, exports);
3494     DeviceManagerNapi::InitExchangeMediumEnum(env, exports);
3495     DeviceManagerNapi::InitExchangeFreqEnum(env, exports);
3496     DeviceManagerNapi::InitSubscribeCapEnum(env, exports);
3497     return exports;
3498 }
3499 
3500 /*
3501  * module define
3502  */
3503 static napi_module g_dmModule = {.nm_version = 1,
3504                                  .nm_flags = 0,
3505                                  .nm_filename = nullptr,
3506                                  .nm_register_func = Export,
3507                                  .nm_modname = "distributedHardware.deviceManager",
3508                                  .nm_priv = ((void *)0),
3509                                  .reserved = {0}};
3510 
3511 /*
3512  * module register
3513  */
RegisterModule(void)3514 extern "C" __attribute__((constructor)) void RegisterModule(void)
3515 {
3516     LOGI("RegisterModule() is called!");
3517     napi_module_register(&g_dmModule);
3518 }
3519