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