1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "native_devicemanager_js.h"
17 
18 #include <securec.h>
19 #include <uv.h>
20 #include <map>
21 #include <mutex>
22 
23 #include "device_manager.h"
24 #include "dm_constants.h"
25 #include "dm_device_info.h"
26 #include "dm_log.h"
27 #include "dm_native_util.h"
28 #include "ipc_skeleton.h"
29 #include "js_native_api.h"
30 #include "tokenid_kit.h"
31 #include "nlohmann/json.hpp"
32 
33 using namespace OHOS::DistributedHardware;
34 
35 namespace {
36 #define GET_PARAMS(env, info, num)    \
37     size_t argc = num;                \
38     napi_value argv[num] = {nullptr}; \
39     napi_value thisVar = nullptr;     \
40     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr))
41 
42 const std::string DM_NAPI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange";
43 const std::string DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS = "discoverSuccess";
44 const std::string DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL = "discoverFail";
45 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS = "publishSuccess";
46 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL = "publishFail";
47 const std::string DM_NAPI_EVENT_DEVICE_SERVICE_DIE = "serviceDie";
48 const std::string DEVICE_MANAGER_NAPI_CLASS_NAME = "DeviceManager";
49 const std::string DM_NAPI_EVENT_REPLY_RESULT = "replyResult";
50 const std::string DM_NAPI_EVENT_DEVICE_NAME_CHANGE = "deviceNameChange";
51 
52 const int32_t DM_NAPI_ARGS_ZERO = 0;
53 const int32_t DM_NAPI_ARGS_ONE = 1;
54 const int32_t DM_NAPI_ARGS_TWO = 2;
55 const int32_t DM_NAPI_ARGS_THREE = 3;
56 const int32_t DM_AUTH_REQUEST_SUCCESS_STATUS = 7;
57 const int32_t DM_MAX_DEVICE_SIZE = 100;
58 
59 napi_ref deviceStateChangeActionEnumConstructor_ = nullptr;
60 
61 std::map<std::string, DeviceManagerNapi *> g_deviceManagerMap;
62 std::map<std::string, std::shared_ptr<DmNapiInitCallback>> g_initCallbackMap;
63 std::map<std::string, std::shared_ptr<DmNapiDeviceStatusCallback>> g_deviceStatusCallbackMap;
64 std::map<std::string, std::shared_ptr<DmNapiDiscoveryCallback>> g_DiscoveryCallbackMap;
65 std::map<std::string, std::shared_ptr<DmNapiPublishCallback>> g_publishCallbackMap;
66 std::map<std::string, std::shared_ptr<DmNapiAuthenticateCallback>> g_authCallbackMap;
67 std::map<std::string, std::shared_ptr<DmNapiBindTargetCallback>> g_bindCallbackMap;
68 std::map<std::string, std::shared_ptr<DmNapiDeviceManagerUiCallback>> g_dmUiCallbackMap;
69 
70 std::mutex g_deviceManagerMapMutex;
71 std::mutex g_initCallbackMapMutex;
72 std::mutex g_deviceStatusCallbackMapMutex;
73 std::mutex g_discoveryCallbackMapMutex;
74 std::mutex g_publishCallbackMapMutex;
75 std::mutex g_authCallbackMapMutex;
76 std::mutex g_bindCallbackMapMutex;
77 std::mutex g_dmUiCallbackMapMutex;
78 
DeleteUvWork(uv_work_t *work)79 void DeleteUvWork(uv_work_t *work)
80 {
81     if (work == nullptr) {
82         return;
83     }
84     delete work;
85     work = nullptr;
86     LOGI("delete work!");
87 }
88 
DeleteDmNapiStatusJsCallbackPtr(DmNapiStatusJsCallback *pJsCallbackPtr)89 void DeleteDmNapiStatusJsCallbackPtr(DmNapiStatusJsCallback *pJsCallbackPtr)
90 {
91     if (pJsCallbackPtr == nullptr) {
92         return;
93     }
94     delete pJsCallbackPtr;
95     pJsCallbackPtr = nullptr;
96     LOGI("delete DmNapiStatusJsCallback callbackPtr!");
97 }
98 
DeleteAsyncCallbackInfo(DeviceBasicInfoListAsyncCallbackInfo *pAsynCallbackInfo)99 void DeleteAsyncCallbackInfo(DeviceBasicInfoListAsyncCallbackInfo *pAsynCallbackInfo)
100 {
101     if (pAsynCallbackInfo == nullptr) {
102         return;
103     }
104     delete pAsynCallbackInfo;
105     pAsynCallbackInfo = nullptr;
106 }
107 
IsDeviceManagerNapiNull(napi_env env, napi_value thisVar, DeviceManagerNapi **pDeviceManagerWrapper)108 bool IsDeviceManagerNapiNull(napi_env env, napi_value thisVar, DeviceManagerNapi **pDeviceManagerWrapper)
109 {
110     napi_unwrap(env, thisVar, reinterpret_cast<void **>(pDeviceManagerWrapper));
111     if (pDeviceManagerWrapper != nullptr && *pDeviceManagerWrapper != nullptr) {
112         return false;
113     }
114     CreateBusinessError(env, ERR_DM_POINT_NULL);
115     LOGE(" DeviceManagerNapi object is nullptr!");
116     return true;
117 }
118 } // namespace
119 
120 thread_local napi_ref DeviceManagerNapi::sConstructor_ = nullptr;
121 AuthAsyncCallbackInfo DeviceManagerNapi::authAsyncCallbackInfo_;
122 
OnRemoteDied()123 void DmNapiInitCallback::OnRemoteDied()
124 {
125     uv_loop_s *loop = nullptr;
126     napi_get_uv_event_loop(env_, &loop);
127     if (loop == nullptr) {
128         return;
129     }
130     uv_work_t *work = new (std::nothrow) uv_work_t;
131     if (work == nullptr) {
132         LOGE("DmNapiInitCallback: OnRemoteDied, No memory");
133         return;
134     }
135 
136     DmDeviceBasicInfo info;
137     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, info);
138     if (jsCallback == nullptr) {
139         DeleteUvWork(work);
140         return;
141     }
142     work->data = reinterpret_cast<void *>(jsCallback);
143 
144     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
145         LOGD("OnRemoteDied uv_queue_work_with_qos");
146     }, [] (uv_work_t *work, int status) {
147         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
148         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
149         if (deviceManagerNapi == nullptr) {
150             LOGE("OnRemoteDied, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
151         } else {
152             deviceManagerNapi->OnEvent("serviceDie", 0, nullptr);
153         }
154         LOGI("OnRemoteDied, deviceManagerNapi bundleName %{public}s", callback->bundleName_.c_str());
155         DeleteDmNapiStatusJsCallbackPtr(callback);
156         DeleteUvWork(work);
157     }, uv_qos_user_initiated);
158     if (ret != 0) {
159         LOGE("Failed to execute OnRemoteDied work queue");
160         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
161         DeleteUvWork(work);
162     }
163 }
164 
OnDeviceOnline(const DmDeviceBasicInfo &deviceBasicInfo)165 void DmNapiDeviceStatusCallback::OnDeviceOnline(const DmDeviceBasicInfo &deviceBasicInfo)
166 {
167     uv_loop_s *loop = nullptr;
168     napi_get_uv_event_loop(env_, &loop);
169     if (loop == nullptr) {
170         return;
171     }
172     uv_work_t *work = new (std::nothrow) uv_work_t;
173     if (work == nullptr) {
174         LOGE("DmNapiDeviceStatusCallback: OnDeviceOnline, No memory");
175         return;
176     }
177 
178     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
179     if (jsCallback == nullptr) {
180         DeleteUvWork(work);
181         return;
182     }
183     work->data = reinterpret_cast<void *>(jsCallback);
184 
185     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
186         LOGD("OnDeviceOnline uv_queue_work_with_qos");
187     }, [] (uv_work_t *work, int status) {
188         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
189         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
190         if (deviceManagerNapi == nullptr) {
191             LOGE("OnDeviceOnline, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
192         } else {
193             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::UNKNOWN, callback->deviceBasicInfo_);
194         }
195         DeleteDmNapiStatusJsCallbackPtr(callback);
196         DeleteUvWork(work);
197     }, uv_qos_user_initiated);
198     if (ret != 0) {
199         LOGE("Failed to execute OnDeviceOnline work queue");
200         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
201         DeleteUvWork(work);
202     }
203 }
204 
OnDeviceReady(const DmDeviceBasicInfo &deviceBasicInfo)205 void DmNapiDeviceStatusCallback::OnDeviceReady(const DmDeviceBasicInfo &deviceBasicInfo)
206 {
207     uv_loop_s *loop = nullptr;
208     napi_get_uv_event_loop(env_, &loop);
209     if (loop == nullptr) {
210         return;
211     }
212     uv_work_t *work = new (std::nothrow) uv_work_t;
213     if (work == nullptr) {
214         LOGE("DmNapiDeviceStateCallback: OnDeviceReady, No memory");
215         return;
216     }
217 
218     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
219     if (jsCallback == nullptr) {
220         DeleteUvWork(work);
221         return;
222     }
223     work->data = reinterpret_cast<void *>(jsCallback);
224 
225     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
226         LOGD("OnDeviceReady uv_queue_work_with_qos");
227     }, [] (uv_work_t *work, int status) {
228         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
229         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
230         if (deviceManagerNapi == nullptr) {
231             LOGE("OnDeviceReady, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
232         } else {
233             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::AVAILABLE, callback->deviceBasicInfo_);
234         }
235         DeleteDmNapiStatusJsCallbackPtr(callback);
236         DeleteUvWork(work);
237     }, uv_qos_user_initiated);
238     if (ret != 0) {
239         LOGE("Failed to execute OnDeviceReady work queue");
240         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
241         DeleteUvWork(work);
242     }
243 }
244 
OnDeviceOffline(const DmDeviceBasicInfo &deviceBasicInfo)245 void DmNapiDeviceStatusCallback::OnDeviceOffline(const DmDeviceBasicInfo &deviceBasicInfo)
246 {
247     uv_loop_s *loop = nullptr;
248     napi_get_uv_event_loop(env_, &loop);
249     if (loop == nullptr) {
250         return;
251     }
252     uv_work_t *work = new (std::nothrow) uv_work_t;
253     if (work == nullptr) {
254         LOGE("DmNapiDeviceStatusCallback: OnDeviceOffline, No memory");
255         return;
256     }
257 
258     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
259     if (jsCallback == nullptr) {
260         DeleteUvWork(work);
261         return;
262     }
263     work->data = reinterpret_cast<void *>(jsCallback);
264 
265     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
266         LOGD("OnDeviceOffline uv_queue_work_with_qos");
267     }, [] (uv_work_t *work, int status) {
268         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
269         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
270         if (deviceManagerNapi == nullptr) {
271             LOGE("OnDeviceOffline, deviceManagerNapi not find for bundleName %{public}s",
272                 callback->bundleName_.c_str());
273         } else {
274             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::UNAVAILABLE, callback->deviceBasicInfo_);
275         }
276         DeleteDmNapiStatusJsCallbackPtr(callback);
277         DeleteUvWork(work);
278     }, uv_qos_user_initiated);
279     if (ret != 0) {
280         LOGE("Failed to execute OnDeviceOffline work queue");
281         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
282         DeleteUvWork(work);
283     }
284 }
285 
OnDeviceChanged(const DmDeviceBasicInfo &deviceBasicInfo)286 void DmNapiDeviceStatusCallback::OnDeviceChanged(const DmDeviceBasicInfo &deviceBasicInfo)
287 {
288     uv_loop_s *loop = nullptr;
289     napi_get_uv_event_loop(env_, &loop);
290     if (loop == nullptr) {
291         return;
292     }
293     uv_work_t *work = new (std::nothrow) uv_work_t;
294     if (work == nullptr) {
295         LOGE("DmNapiDeviceStatusCallback: OnDeviceChanged, No memory");
296         return;
297     }
298 
299     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
300     if (jsCallback == nullptr) {
301         DeleteUvWork(work);
302         return;
303     }
304     work->data = reinterpret_cast<void *>(jsCallback);
305 
306     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
307         LOGD("OnDeviceChanged uv_queue_work_with_qos");
308     }, [] (uv_work_t *work, int status) {
309         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
310         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
311         if (deviceManagerNapi == nullptr) {
312             LOGE("OnDeviceChanged, deviceManagerNapi not find for bundleName %{public}s",
313                 callback->bundleName_.c_str());
314         } else {
315             std::string deviceName = callback->deviceBasicInfo_.deviceName;
316             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::CHANGE, callback->deviceBasicInfo_);
317         }
318         DeleteDmNapiStatusJsCallbackPtr(callback);
319         DeleteUvWork(work);
320     }, uv_qos_user_initiated);
321     if (ret != 0) {
322         LOGE("Failed to execute OnDeviceChanged work queue");
323         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
324         DeleteUvWork(work);
325     }
326 }
327 
OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)328 void DmNapiDiscoveryCallback::OnDeviceFound(uint16_t subscribeId,
329                                             const DmDeviceBasicInfo &deviceBasicInfo)
330 {
331     LOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
332     uv_loop_s *loop = nullptr;
333     napi_get_uv_event_loop(env_, &loop);
334     if (loop == nullptr) {
335         return;
336     }
337     uv_work_t *work = new (std::nothrow) uv_work_t;
338     if (work == nullptr) {
339         LOGE("DmNapiDiscoveryCallback: OnDeviceFound, No memory");
340         return;
341     }
342 
343     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, subscribeId, 0, deviceBasicInfo);
344     if (jsCallback == nullptr) {
345         DeleteUvWork(work);
346         return;
347     }
348     work->data = reinterpret_cast<void *>(jsCallback);
349 
350     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
351         LOGD("OnDeviceFound uv_queue_work_with_qos");
352     }, [] (uv_work_t *work, int status) {
353         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
354         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
355         if (deviceManagerNapi == nullptr) {
356             LOGE("OnDeviceFound, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
357         } else {
358             deviceManagerNapi->OnDeviceFound(callback->subscribeId_, callback->deviceBasicInfo_);
359         }
360         DeleteDmNapiStatusJsCallbackPtr(callback);
361         DeleteUvWork(work);
362     }, uv_qos_user_initiated);
363     if (ret != 0) {
364         LOGE("Failed to execute OnDeviceFound work queue");
365         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
366         DeleteUvWork(work);
367     }
368 }
369 
OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)370 void DmNapiDiscoveryCallback::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
371 {
372     LOGI("OnDiscoveryFailed for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
373 
374     uv_loop_s *loop = nullptr;
375     napi_get_uv_event_loop(env_, &loop);
376     if (loop == nullptr) {
377         return;
378     }
379     uv_work_t *work = new (std::nothrow) uv_work_t;
380     if (work == nullptr) {
381         LOGE("DmNapiDiscoveryCallback: OnDiscoveryFailed, No memory");
382         return;
383     }
384 
385     DmDeviceBasicInfo info;
386     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, subscribeId,
387         failedReason, info);
388     if (jsCallback == nullptr) {
389         DeleteUvWork(work);
390         return;
391     }
392     work->data = reinterpret_cast<void *>(jsCallback);
393 
394     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
395         LOGD("OnDiscoveryFailed uv_queue_work_with_qos");
396     }, [] (uv_work_t *work, int status) {
397         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
398         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
399         if (deviceManagerNapi == nullptr) {
400             LOGE("OnDiscoveryFailed, deviceManagerNapi not find for bundleName %{public}s",
401                 callback->bundleName_.c_str());
402         } else {
403             deviceManagerNapi->OnDiscoveryFailed(callback->subscribeId_, callback->reason_);
404         }
405         DeleteDmNapiStatusJsCallbackPtr(callback);
406         DeleteUvWork(work);
407     }, uv_qos_user_initiated);
408     if (ret != 0) {
409         LOGE("Failed to execute OnDiscoveryFailed work queue");
410         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
411         DeleteUvWork(work);
412     }
413 }
414 
OnDiscoverySuccess(uint16_t subscribeId)415 void DmNapiDiscoveryCallback::OnDiscoverySuccess(uint16_t subscribeId)
416 {
417     DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_);
418     if (deviceManagerNapi == nullptr) {
419         LOGE("OnDiscoverySuccess, deviceManagerNapi not find for bundleName %{public}s", bundleName_.c_str());
420         return;
421     }
422     LOGI("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
423 }
424 
IncreaseRefCount()425 void DmNapiDiscoveryCallback::IncreaseRefCount()
426 {
427     refCount_++;
428 }
429 
DecreaseRefCount()430 void DmNapiDiscoveryCallback::DecreaseRefCount()
431 {
432     refCount_--;
433 }
434 
GetRefCount()435 int32_t DmNapiDiscoveryCallback::GetRefCount()
436 {
437     return refCount_;
438 }
439 
OnPublishResult(int32_t publishId, int32_t publishResult)440 void DmNapiPublishCallback::OnPublishResult(int32_t publishId, int32_t publishResult)
441 {
442     LOGI("OnPublishResult for %{public}s, publishId %{public}d, publishResult %{public}d", bundleName_.c_str(),
443         publishId, publishResult);
444     uv_loop_s *loop = nullptr;
445     napi_get_uv_event_loop(env_, &loop);
446     if (loop == nullptr) {
447         return;
448     }
449     uv_work_t *work = new (std::nothrow) uv_work_t;
450     if (work == nullptr) {
451         LOGE("DmNapiPublishCallback: OnPublishResult, No memory");
452         return;
453     }
454 
455     DmNapiPublishJsCallback *jsCallback = new DmNapiPublishJsCallback(bundleName_, publishId, publishResult);
456     if (jsCallback == nullptr) {
457         DeleteUvWork(work);
458         return;
459     }
460     work->data = reinterpret_cast<void *>(jsCallback);
461 
462     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
463         LOGD("OnPublishResult uv_queue_work_with_qos");
464     }, [] (uv_work_t *work, int status) {
465         DmNapiPublishJsCallback *callback = reinterpret_cast<DmNapiPublishJsCallback *>(work->data);
466         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
467         if (deviceManagerNapi == nullptr) {
468             LOGE("OnPublishResult, deviceManagerNapi failed for bundleName %{public}s", callback->bundleName_.c_str());
469         } else {
470             deviceManagerNapi->OnPublishResult(callback->publishId_, callback->reason_);
471         }
472         delete callback;
473         callback = nullptr;
474         DeleteUvWork(work);
475     }, uv_qos_user_initiated);
476     if (ret != 0) {
477         LOGE("Failed to execute OnPublishResult work queue");
478         delete jsCallback;
479         jsCallback = nullptr;
480         DeleteUvWork(work);
481     }
482 }
483 
IncreaseRefCount()484 void DmNapiPublishCallback::IncreaseRefCount()
485 {
486     refCount_++;
487 }
488 
DecreaseRefCount()489 void DmNapiPublishCallback::DecreaseRefCount()
490 {
491     refCount_--;
492 }
493 
GetRefCount()494 int32_t DmNapiPublishCallback::GetRefCount()
495 {
496     return refCount_;
497 }
498 
OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status, int32_t reason)499 void DmNapiAuthenticateCallback::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
500                                               int32_t reason)
501 {
502     uv_loop_s *loop = nullptr;
503     napi_get_uv_event_loop(env_, &loop);
504     if (loop == nullptr) {
505         return;
506     }
507     uv_work_t *work = new (std::nothrow) uv_work_t;
508     if (work == nullptr) {
509         LOGE("js4.0 DmNapiAuthenticateCallback::OnAuthResult, No memory");
510         return;
511     }
512 
513     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, deviceId, token, status, reason);
514     if (jsCallback == nullptr) {
515         DeleteUvWork(work);
516         return;
517     }
518     work->data = reinterpret_cast<void *>(jsCallback);
519 
520     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
521         LOGD("OnAuthResult uv_queue_work_with_qos");
522     }, [] (uv_work_t *work, int status) {
523         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
524         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
525         if (deviceManagerNapi == nullptr) {
526             LOGE("OnAuthResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
527         } else {
528             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
529                 callback->status_, callback->reason_);
530         }
531         delete callback;
532         callback = nullptr;
533         DeleteUvWork(work);
534     }, uv_qos_user_initiated);
535     if (ret != 0) {
536         LOGE("Failed to execute OnAuthResult work queue");
537         delete jsCallback;
538         jsCallback = nullptr;
539         DeleteUvWork(work);
540     }
541 }
542 
DeviceManagerNapi(napi_env env, napi_value thisVar)543 DeviceManagerNapi::DeviceManagerNapi(napi_env env, napi_value thisVar) : DmNativeEvent(env, thisVar)
544 {
545     env_ = env;
546 }
547 
~DeviceManagerNapi()548 DeviceManagerNapi::~DeviceManagerNapi()
549 {
550 }
551 
GetDeviceManagerNapi(std::string &bundleName)552 DeviceManagerNapi *DeviceManagerNapi::GetDeviceManagerNapi(std::string &bundleName)
553 {
554     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
555     auto iter = g_deviceManagerMap.find(bundleName);
556     if (iter == g_deviceManagerMap.end()) {
557         return nullptr;
558     }
559     return iter->second;
560 }
561 
OnDeviceStatusChange(DmNapiDevStatusChange action, const OHOS::DistributedHardware::DmDeviceBasicInfo &deviceBasicInfo)562 void DeviceManagerNapi::OnDeviceStatusChange(DmNapiDevStatusChange action,
563     const OHOS::DistributedHardware::DmDeviceBasicInfo &deviceBasicInfo)
564 {
565     napi_handle_scope scope;
566     napi_open_handle_scope(env_, &scope);
567     napi_value result = nullptr;
568     napi_create_object(env_, &result);
569     SetValueInt32(env_, "action", (int)action, result);
570 
571     napi_value device = nullptr;
572     napi_create_object(env_, &device);
573     DmDeviceBasicToJsObject(env_, deviceBasicInfo, device);
574 
575     napi_set_named_property(env_, result, "device", device);
576     OnEvent("deviceStateChange", DM_NAPI_ARGS_ONE, &result);
577     napi_close_handle_scope(env_, scope);
578 }
579 
OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)580 void DeviceManagerNapi::OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)
581 {
582     LOGI("OnDeviceFound DmDeviceBasicInfo for subscribeId %{public}d", (int32_t)subscribeId);
583     napi_handle_scope scope;
584     napi_open_handle_scope(env_, &scope);
585     napi_value result = nullptr;
586     napi_create_object(env_, &result);
587 
588     napi_value device = nullptr;
589     napi_create_object(env_, &device);
590     DmDeviceBasicToJsObject(env_, deviceBasicInfo, device);
591 
592     napi_set_named_property(env_, result, "device", device);
593     OnEvent("discoverSuccess", DM_NAPI_ARGS_ONE, &result);
594     napi_close_handle_scope(env_, scope);
595 }
596 
OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)597 void DeviceManagerNapi::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
598 {
599     LOGI("OnDiscoveryFailed for subscribeId %{public}d", (int32_t)subscribeId);
600     napi_handle_scope scope;
601     napi_open_handle_scope(env_, &scope);
602     napi_value result = nullptr;
603     napi_create_object(env_, &result);
604     SetValueInt32(env_, "reason", (int)failedReason, result);
605     std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)failedReason);
606     SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
607     OnEvent("discoverFail", DM_NAPI_ARGS_ONE, &result);
608     napi_close_handle_scope(env_, scope);
609 }
610 
OnPublishResult(int32_t publishId, int32_t publishResult)611 void DeviceManagerNapi::OnPublishResult(int32_t publishId, int32_t publishResult)
612 {
613     LOGI("OnPublishResult for publishId %{public}d, publishResult %{public}d", publishId, publishResult);
614     napi_handle_scope scope;
615     napi_open_handle_scope(env_, &scope);
616     napi_value result = nullptr;
617     napi_create_object(env_, &result);
618     SetValueInt32(env_, "publishId", publishId, result);
619     if (publishResult == 0) {
620         OnEvent("publishSuccess", DM_NAPI_ARGS_ONE, &result);
621     } else {
622         SetValueInt32(env_, "reason", publishResult, result);
623         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString(publishResult);
624         SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
625         OnEvent("publishFail", DM_NAPI_ARGS_ONE, &result);
626     }
627     NAPI_CALL_RETURN_VOID(env_, napi_close_handle_scope(env_, scope));
628 }
629 
OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status, int32_t reason)630 void DeviceManagerNapi::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
631                                      int32_t reason)
632 {
633     LOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason);
634     napi_handle_scope scope;
635     napi_open_handle_scope(env_, &scope);
636     napi_value thisVar = nullptr;
637     napi_get_reference_value(env_, thisVarRef_, &thisVar);
638     napi_value result[DM_NAPI_ARGS_TWO] = {0};
639 
640     if (status == DM_AUTH_REQUEST_SUCCESS_STATUS && reason == 0) {
641         LOGI("OnAuthResult success");
642         napi_get_undefined(env_, &result[0]);
643         napi_create_object(env_, &result[1]);
644         SetValueUtf8String(env_, "deviceId", deviceId, result[1]);
645     } else {
646         LOGI("OnAuthResult failed");
647         napi_create_object(env_, &result[0]);
648         SetValueInt32(env_, "code", status, result[0]);
649         SetValueInt32(env_, "reason", reason, result[0]);
650         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)reason);
651         SetValueUtf8String(env_, "errInfo", errCodeInfo, result[0]);
652         napi_get_undefined(env_, &result[1]);
653     }
654 
655     if (reason == DM_OK && (status <= STATUS_DM_CLOSE_PIN_INPUT_UI && status >= STATUS_DM_SHOW_AUTHORIZE_UI)) {
656         LOGI("update ui change, status: %{public}d, reason: %{public}d", status, reason);
657     } else {
658         napi_value callResult = nullptr;
659         napi_value handler = nullptr;
660         napi_get_reference_value(env_, authAsyncCallbackInfo_.callback, &handler);
661         if (handler != nullptr) {
662             napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_TWO, &result[0], &callResult);
663             napi_delete_reference(env_, authAsyncCallbackInfo_.callback);
664         } else {
665             LOGE("handler is nullptr");
666         }
667         {
668             std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
669             g_authCallbackMap.erase(bundleName_);
670         }
671     }
672     napi_close_handle_scope(env_, scope);
673 }
674 
CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType)675 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType)
676 {
677     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s", bundleName.c_str(), eventType.c_str());
678     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE || eventType == DM_NAPI_EVENT_DEVICE_NAME_CHANGE) {
679         RegisterDevStatusCallback(env, bundleName);
680         return;
681     }
682     if (eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) {
683         auto callback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
684         {
685             std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
686             g_DiscoveryCallbackMap[bundleName] = callback;
687         }
688         std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = callback;
689         discoveryCallback->IncreaseRefCount();
690         return;
691     }
692 
693     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
694         auto callback = std::make_shared<DmNapiPublishCallback>(env, bundleName);
695         {
696             std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
697             g_publishCallbackMap[bundleName] = callback;
698         }
699         std::shared_ptr<DmNapiPublishCallback> publishCallback = callback;
700         publishCallback->IncreaseRefCount();
701         return;
702     }
703 
704     if (eventType == DM_NAPI_EVENT_REPLY_RESULT) {
705         auto callback = std::make_shared<DmNapiDeviceManagerUiCallback>(env, bundleName);
706         int32_t ret = DeviceManager::GetInstance().RegisterDeviceManagerFaCallback(bundleName, callback);
707         if (ret != 0) {
708             LOGE("RegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
709             return;
710         }
711         {
712             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
713             g_dmUiCallbackMap[bundleName] = callback;
714         }
715         return;
716     }
717 }
718 
RegisterDevStatusCallback(napi_env env, std::string &bundleName)719 void DeviceManagerNapi::RegisterDevStatusCallback(napi_env env, std::string &bundleName)
720 {
721     LOGI("RegisterDevStatusCallback start for bundleName %{public}s", bundleName.c_str());
722     {
723         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
724         if (g_deviceStatusCallbackMap.find(bundleName) != g_deviceStatusCallbackMap.end()) {
725             LOGI("bundleName already register.");
726             return;
727         }
728     }
729     auto callback = std::make_shared<DmNapiDeviceStatusCallback>(env, bundleName);
730     std::string extra = "";
731     int32_t ret = DeviceManager::GetInstance().RegisterDevStatusCallback(bundleName, extra, callback);
732     if (ret != 0) {
733         LOGE("RegisterDevStatusCallback failed ret %{public}d", ret);
734         return;
735     }
736     {
737         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
738         g_deviceStatusCallbackMap[bundleName] = callback;
739     }
740     return;
741 }
742 
CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType, std::string &extra)743 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName,
744                                          std::string &eventType, std::string &extra)
745 {
746     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s extra = %{public}s",
747          bundleName.c_str(), eventType.c_str(), extra.c_str());
748     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
749         auto callback = std::make_shared<DmNapiDeviceStatusCallback>(env, bundleName);
750         int32_t ret = DeviceManager::GetInstance().RegisterDevStatusCallback(bundleName, extra, callback);
751         if (ret != 0) {
752             LOGE("RegisterDevStatusCallback failed for bundleName %{public}s", bundleName.c_str());
753             return;
754         }
755         {
756             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
757             g_deviceStatusCallbackMap[bundleName] = callback;
758         }
759     }
760 }
761 
ReleasePublishCallback(std::string &bundleName)762 void DeviceManagerNapi::ReleasePublishCallback(std::string &bundleName)
763 {
764     LOGI("ReleasePublishCallback for bundleName %{public}s", bundleName.c_str());
765     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
766     {
767         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
768         auto iter = g_publishCallbackMap.find(bundleName);
769         if (iter == g_publishCallbackMap.end()) {
770             return;
771         }
772         publishCallback = iter->second;
773     }
774     publishCallback->DecreaseRefCount();
775     if (publishCallback->GetRefCount() == 0) {
776         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
777         g_publishCallbackMap.erase(bundleName);
778     }
779     return;
780 }
781 
ReleaseDiscoveryCallback(std::string &bundleName)782 void DeviceManagerNapi::ReleaseDiscoveryCallback(std::string &bundleName)
783 {
784     LOGI("ReleaseDiscoveryCallback for bundleName %{public}s", bundleName.c_str());
785     std::shared_ptr<DmNapiDiscoveryCallback> DiscoveryCallback = nullptr;
786     {
787         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
788         auto iter = g_DiscoveryCallbackMap.find(bundleName);
789         if (iter == g_DiscoveryCallbackMap.end()) {
790             return;
791         }
792         DiscoveryCallback = iter->second;
793     }
794     DiscoveryCallback->DecreaseRefCount();
795     if (DiscoveryCallback->GetRefCount() == 0) {
796         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
797         g_DiscoveryCallbackMap.erase(bundleName);
798     }
799     return;
800 }
801 
ReleaseDmCallback(std::string &bundleName, std::string &eventType)802 void DeviceManagerNapi::ReleaseDmCallback(std::string &bundleName, std::string &eventType)
803 {
804     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
805         {
806             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
807             auto iter = g_deviceStatusCallbackMap.find(bundleName);
808             if (iter == g_deviceStatusCallbackMap.end()) {
809                 LOGE("ReleaseDmCallback: cannot find statusCallback for bundleName %{public}s", bundleName.c_str());
810                 return;
811             }
812         }
813         int32_t ret = DeviceManager::GetInstance().UnRegisterDevStatusCallback(bundleName);
814         if (ret != 0) {
815             LOGE("UnRegisterDevStatusCallback failed for bundleName %{public}s", bundleName.c_str());
816             return;
817         }
818         {
819             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
820             g_deviceStatusCallbackMap.erase(bundleName);
821         }
822         return;
823     }
824 
825     if (eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) {
826         ReleaseDiscoveryCallback(bundleName);
827         return;
828     }
829 
830     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
831         ReleasePublishCallback(bundleName);
832         return;
833     }
834 
835     if (eventType == DM_NAPI_EVENT_REPLY_RESULT) {
836         {
837             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
838             auto iter = g_dmUiCallbackMap.find(bundleName);
839             if (iter == g_dmUiCallbackMap.end()) {
840                 LOGE("cannot find dmFaCallback for bundleName %{public}s", bundleName.c_str());
841                 return;
842             }
843         }
844         int32_t ret = DeviceManager::GetInstance().UnRegisterDeviceManagerFaCallback(bundleName);
845         if (ret != 0) {
846             LOGE("UnRegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
847             return;
848         }
849         {
850             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
851             g_dmUiCallbackMap.erase(bundleName);
852         }
853         return;
854     }
855 }
856 
SetUserOperationSync(napi_env env, napi_callback_info info)857 napi_value DeviceManagerNapi::SetUserOperationSync(napi_env env, napi_callback_info info)
858 {
859     LOGI("SetUserOperationSync in");
860     if (!IsSystemApp()) {
861         LOGI("SetUserOperationSync not SystemApp");
862         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
863         return nullptr;
864     }
865     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
866     napi_valuetype valueType;
867     napi_typeof(env, argv[0], &valueType);
868     if (!CheckArgsType(env, valueType == napi_number, "action", "number")) {
869         return nullptr;
870     }
871     int32_t action = 0;
872     napi_get_value_int32(env, argv[0], &action);
873 
874     std::string params;
875     if (!JsToStringAndCheck(env, argv[1], "actionResult", params)) {
876         return nullptr;
877     }
878     napi_value result = nullptr;
879     DeviceManagerNapi *deviceManagerWrapper = nullptr;
880     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
881         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
882         return result;
883     }
884     int32_t ret = DeviceManager::GetInstance().SetUserOperation(deviceManagerWrapper->bundleName_, action, params);
885     if (ret != 0) {
886         LOGE("SetUserOperation for bundleName %{public}s failed, ret %{public}d",
887             deviceManagerWrapper->bundleName_.c_str(), ret);
888         CreateBusinessError(env, ret);
889     }
890     napi_get_undefined(env, &result);
891     return result;
892 }
893 
OnCall(const std::string &paramJson)894 void DmNapiDeviceManagerUiCallback::OnCall(const std::string &paramJson)
895 {
896     uv_loop_s *loop = nullptr;
897     napi_get_uv_event_loop(env_, &loop);
898     if (loop == nullptr) {
899         return;
900     }
901     uv_work_t *work = new (std::nothrow) uv_work_t;
902     if (work == nullptr) {
903         LOGE("DmNapiDeviceManagerUiCallback: OnCall, No memory");
904         return;
905     }
906 
907     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, "", paramJson, 0, 0);
908     if (jsCallback == nullptr) {
909         DeleteUvWork(work);
910         return;
911     }
912     work->data = reinterpret_cast<void *>(jsCallback);
913 
914     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
915         LOGD("OnCall uv_queue_work_with_qos");
916     }, [] (uv_work_t *work, int status) {
917         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
918         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
919         if (deviceManagerNapi == nullptr) {
920             LOGE("OnCall, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
921         } else {
922             deviceManagerNapi->OnDmUiCall(callback->token_);
923         }
924         delete callback;
925         callback = nullptr;
926         DeleteUvWork(work);
927     }, uv_qos_user_initiated);
928     if (ret != 0) {
929         LOGE("Failed to execute OnCall work queue");
930         delete jsCallback;
931         jsCallback = nullptr;
932         DeleteUvWork(work);
933     }
934 }
935 
OnDmUiCall(const std::string &paramJson)936 void DeviceManagerNapi::OnDmUiCall(const std::string &paramJson)
937 {
938     LOGI("OnCall for paramJson");
939     napi_handle_scope scope;
940     napi_open_handle_scope(env_, &scope);
941     napi_value result;
942     napi_create_object(env_, &result);
943     SetValueUtf8String(env_, "param", paramJson, result);
944     OnEvent(DM_NAPI_EVENT_REPLY_RESULT, DM_NAPI_ARGS_ONE, &result);
945     napi_close_handle_scope(env_, scope);
946 }
947 
OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status, std::string content)948 void DmNapiBindTargetCallback::OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status,
949     std::string content)
950 {
951     (void)targetId;
952     uv_loop_s *loop = nullptr;
953     napi_get_uv_event_loop(env_, &loop);
954     if (loop == nullptr) {
955         return;
956     }
957     uv_work_t *work = new (std::nothrow) uv_work_t;
958     if (work == nullptr) {
959         LOGE("js4.0 DmNapiBindTargetCallback::OnBindResult, No memory");
960         return;
961     }
962 
963     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, content, "", status, result);
964     if (jsCallback == nullptr) {
965         DeleteUvWork(work);
966         return;
967     }
968     work->data = reinterpret_cast<void *>(jsCallback);
969 
970     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
971         LOGD("OnBindResult uv_queue_work_with_qos");
972     }, [] (uv_work_t *work, int status) {
973         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
974         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
975         if (deviceManagerNapi == nullptr) {
976             LOGE("OnBindResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
977         } else {
978             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
979                 callback->status_, callback->reason_);
980         }
981         delete callback;
982         callback = nullptr;
983         DeleteUvWork(work);
984     }, uv_qos_user_initiated);
985     if (ret != 0) {
986         LOGE("Failed to execute OnBindResult work queue");
987         delete jsCallback;
988         jsCallback = nullptr;
989         DeleteUvWork(work);
990     }
991 }
992 
DumpDeviceInfo( DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)993 int32_t DeviceManagerNapi::DumpDeviceInfo(
994     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
995 {
996     CHECK_NULL_RETURN(deviceBasicInfoListAsyncCallbackInfo, ERR_DM_POINT_NULL);
997     if (deviceBasicInfoListAsyncCallbackInfo->devList.size() > DM_MAX_DEVICE_SIZE) {
998         LOGE("CallGetAvailableDeviceListStatus invalid devList size");
999         return DM_ERR_FAILED;
1000     }
1001     for (unsigned int i = 0; i < deviceBasicInfoListAsyncCallbackInfo->devList.size(); i++) {
1002         LOGI("DeviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1003              GetAnonyString(deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1004              GetAnonyString(deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1005              deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1006     }
1007     return DM_OK;
1008 }
1009 
CallGetAvailableDeviceListStatus(napi_env env, napi_status &status, DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)1010 void DeviceManagerNapi::CallGetAvailableDeviceListStatus(napi_env env, napi_status &status,
1011     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1012 {
1013     if (DumpDeviceInfo(deviceBasicInfoListAsyncCallbackInfo) != DM_OK) {
1014         return;
1015     }
1016     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1017     bool isArray = false;
1018     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &array[1]));
1019     NAPI_CALL_RETURN_VOID(env, napi_is_array(env, array[1], &isArray));
1020     if (!isArray) {
1021         LOGE("napi_create_array fail");
1022     }
1023     if (deviceBasicInfoListAsyncCallbackInfo->status == 0) {
1024         if (deviceBasicInfoListAsyncCallbackInfo->devList.size() > 0) {
1025             for (size_t i = 0; i != deviceBasicInfoListAsyncCallbackInfo->devList.size(); ++i) {
1026                 DeviceBasicInfoToJsArray(env, deviceBasicInfoListAsyncCallbackInfo->devList, i, array[1]);
1027             }
1028             LOGI("devList is OK");
1029         } else {
1030             LOGE("devList is null"); // CB come here
1031         }
1032     } else {
1033         array[0] = CreateBusinessError(env, deviceBasicInfoListAsyncCallbackInfo->ret, false);
1034     }
1035     if (deviceBasicInfoListAsyncCallbackInfo->deferred) {
1036         if (deviceBasicInfoListAsyncCallbackInfo->status == 0) {
1037             napi_resolve_deferred(env, deviceBasicInfoListAsyncCallbackInfo->deferred, array[1]);
1038         } else {
1039             napi_reject_deferred(env, deviceBasicInfoListAsyncCallbackInfo->deferred, array[0]);
1040         }
1041     } else {
1042         napi_value callResult = nullptr;
1043         napi_value handler = nullptr;
1044         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceBasicInfoListAsyncCallbackInfo->callback,
1045             &handler));
1046         if (handler != nullptr) {
1047             NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO, &array[0],
1048                 &callResult));
1049             NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceBasicInfoListAsyncCallbackInfo->callback));
1050         } else {
1051             LOGE("handler is nullptr");
1052         }
1053     }
1054 }
1055 
CallAsyncWork(napi_env env, DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)1056 void DeviceManagerNapi::CallAsyncWork(napi_env env,
1057     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1058 {
1059     napi_value resourceName;
1060     napi_create_string_latin1(env, "GetAvailableListInfo", NAPI_AUTO_LENGTH, &resourceName);
1061     napi_create_async_work(
1062         env, nullptr, resourceName,
1063         [](napi_env env, void *data) {
1064             DeviceBasicInfoListAsyncCallbackInfo *devBasicInfoListAsyncCallbackInfo =
1065                 reinterpret_cast<DeviceBasicInfoListAsyncCallbackInfo *>(data);
1066             int32_t ret = 0;
1067             ret = DeviceManager::GetInstance().GetAvailableDeviceList(devBasicInfoListAsyncCallbackInfo->bundleName,
1068                 devBasicInfoListAsyncCallbackInfo->devList);
1069             if (ret != 0) {
1070                 LOGE("CallAsyncWork for bundleName %{public}s failed, ret %{public}d",
1071                     devBasicInfoListAsyncCallbackInfo->bundleName.c_str(), ret);
1072                 devBasicInfoListAsyncCallbackInfo->status = -1;
1073                 devBasicInfoListAsyncCallbackInfo->ret = ret;
1074             } else {
1075                 devBasicInfoListAsyncCallbackInfo->status = 0;
1076             }
1077             LOGI("CallAsyncWork status %{public}d , ret %{public}d", devBasicInfoListAsyncCallbackInfo->status,
1078                 devBasicInfoListAsyncCallbackInfo->ret);
1079         },
1080         [](napi_env env, napi_status status, void *data) {
1081             (void)status;
1082             DeviceBasicInfoListAsyncCallbackInfo *dBasicInfoListAsyncCallbackInfo =
1083                 reinterpret_cast<DeviceBasicInfoListAsyncCallbackInfo *>(data);
1084             CallGetAvailableDeviceListStatus(env, status, dBasicInfoListAsyncCallbackInfo);
1085             napi_delete_async_work(env, dBasicInfoListAsyncCallbackInfo->asyncWork);
1086             delete dBasicInfoListAsyncCallbackInfo;
1087             dBasicInfoListAsyncCallbackInfo = nullptr;
1088         },
1089         (void *)deviceBasicInfoListAsyncCallbackInfo, &deviceBasicInfoListAsyncCallbackInfo->asyncWork);
1090     napi_queue_async_work_with_qos(env, deviceBasicInfoListAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1091 }
1092 
CallDeviceList(napi_env env, napi_callback_info info, DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)1093 napi_value DeviceManagerNapi::CallDeviceList(napi_env env, napi_callback_info info,
1094     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1095 {
1096     napi_value result = nullptr;
1097     std::string extra = "";
1098     deviceBasicInfoListAsyncCallbackInfo->extra = extra;
1099     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1100     napi_valuetype eventHandleType = napi_undefined;
1101     napi_typeof(env, argv[0], &eventHandleType);
1102     if (eventHandleType == napi_function) {
1103         LOGI("CallDeviceList for argc %{public}zu Type = %{public}d", argc, (int)eventHandleType);
1104         napi_create_reference(env, argv[0], 1, &deviceBasicInfoListAsyncCallbackInfo->callback);
1105         CallAsyncWork(env, deviceBasicInfoListAsyncCallbackInfo);
1106     }
1107     napi_get_undefined(env, &result);
1108     return result;
1109 }
1110 
GetAvailableDeviceListSync(napi_env env, napi_callback_info info)1111 napi_value DeviceManagerNapi::GetAvailableDeviceListSync(napi_env env, napi_callback_info info)
1112 {
1113     LOGI("In");
1114     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1115     if (ret != 0) {
1116         CreateBusinessError(env, ret);
1117         return nullptr;
1118     }
1119     napi_value result = nullptr;
1120     napi_value thisVar = nullptr;
1121     size_t argc = 0;
1122     bool isArray = false;
1123     napi_create_array(env, &result);
1124     napi_is_array(env, result, &isArray);
1125     if (!isArray) {
1126         LOGE("napi_create_array fail");
1127     }
1128     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1129     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1130     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1131         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1132         return result;
1133     }
1134     std::vector<DmDeviceBasicInfo> devList;
1135     ret = DeviceManager::GetInstance().GetAvailableDeviceList(deviceManagerWrapper->bundleName_, devList);
1136     if (ret != 0) {
1137         LOGE("GetTrustedDeviceList for bundleName %{public}s failed, ret %{public}d",
1138             deviceManagerWrapper->bundleName_.c_str(), ret);
1139         CreateBusinessError(env, ret);
1140         return result;
1141     }
1142     LOGD("DeviceManager::GetAvailableDeviceListSync");
1143     if (devList.size() > 0) {
1144         for (size_t i = 0; i != devList.size(); ++i) {
1145             DeviceBasicInfoToJsArray(env, devList, (int32_t)i, result);
1146         }
1147     }
1148     return result;
1149 }
1150 
GetAvailableDeviceListPromise(napi_env env, DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)1151 napi_value DeviceManagerNapi::GetAvailableDeviceListPromise(napi_env env,
1152     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1153 {
1154     std::string extra = "";
1155     deviceBasicInfoListAsyncCallbackInfo->extra = extra;
1156     napi_deferred deferred;
1157     napi_value promise = 0;
1158     napi_create_promise(env, &deferred, &promise);
1159     deviceBasicInfoListAsyncCallbackInfo->deferred = deferred;
1160     CallAsyncWork(env, deviceBasicInfoListAsyncCallbackInfo);
1161     return promise;
1162 }
1163 
GetAvailableDeviceList(napi_env env, napi_callback_info info)1164 napi_value DeviceManagerNapi::GetAvailableDeviceList(napi_env env, napi_callback_info info)
1165 {
1166     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1167     if (ret != 0) {
1168         CreateBusinessError(env, ret);
1169         return nullptr;
1170     }
1171     napi_value result = nullptr;
1172     napi_value thisVar = nullptr;
1173     size_t argc = 0;
1174     std::vector<DmDeviceBasicInfo> devList;
1175     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1176 
1177     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1178     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1179         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1180         return result;
1181     }
1182 
1183     auto *deviceBasicInfoListAsyncCallbackInfo = new DeviceBasicInfoListAsyncCallbackInfo();
1184     if (deviceBasicInfoListAsyncCallbackInfo == nullptr) {
1185         return nullptr;
1186     }
1187     deviceBasicInfoListAsyncCallbackInfo->env = env;
1188     deviceBasicInfoListAsyncCallbackInfo->devList = devList;
1189     deviceBasicInfoListAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
1190     if (argc == DM_NAPI_ARGS_ZERO) {
1191         return GetAvailableDeviceListPromise(env, deviceBasicInfoListAsyncCallbackInfo);
1192     } else if (argc == DM_NAPI_ARGS_ONE) {
1193         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1194         if (!IsFunctionType(env, argv[0])) {
1195             DeleteAsyncCallbackInfo(deviceBasicInfoListAsyncCallbackInfo);
1196             return nullptr;
1197         }
1198         return CallDeviceList(env, info, deviceBasicInfoListAsyncCallbackInfo);
1199     }
1200     napi_get_undefined(env, &result);
1201     return result;
1202 }
1203 
GetLocalDeviceNetworkId(napi_env env, napi_callback_info info)1204 napi_value DeviceManagerNapi::GetLocalDeviceNetworkId(napi_env env, napi_callback_info info)
1205 {
1206     LOGI("GetLocalDeviceNetworkId in");
1207     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1208         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1209         return nullptr;
1210     }
1211     napi_value result = nullptr;
1212     napi_value thisVar = nullptr;
1213     std::string networkId;
1214     size_t argc = 0;
1215 
1216     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1217     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1218     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1219         napi_create_int32(env, ERR_DM_POINT_NULL, &result);
1220         return result;
1221     }
1222 
1223     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceNetWorkId(deviceManagerWrapper->bundleName_, networkId);
1224     if (ret != 0) {
1225         LOGE("GetLocalDeviceNetworkId for failed, ret %{public}d", ret);
1226         CreateBusinessError(env, ret);
1227         return result;
1228     }
1229     LOGI("DeviceManager::GetLocalDeviceNetworkId networkId:%{public}s", GetAnonyString(std::string(networkId)).c_str());
1230     napi_create_string_utf8(env, networkId.c_str(), networkId.size(), &result);
1231     return result;
1232 }
1233 
GetLocalDeviceId(napi_env env, napi_callback_info info)1234 napi_value DeviceManagerNapi::GetLocalDeviceId(napi_env env, napi_callback_info info)
1235 {
1236     LOGI("GetLocalDeviceId in");
1237     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1238         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1239         return nullptr;
1240     }
1241     napi_value result = nullptr;
1242     napi_value thisVar = nullptr;
1243     std::string deviceId;
1244     size_t argc = 0;
1245 
1246     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1247     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1248     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1249         napi_create_int32(env, ERR_DM_POINT_NULL, &result);
1250         return result;
1251     }
1252 
1253     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceId(deviceManagerWrapper->bundleName_, deviceId);
1254     if (ret != 0) {
1255         LOGE("GetLocalDeviceId for failed, ret %{public}d", ret);
1256         CreateBusinessError(env, ret);
1257         return result;
1258     }
1259     LOGI("DeviceManager::GetLocalDeviceId deviceId:%{public}s", GetAnonyString(std::string(deviceId)).c_str());
1260     napi_create_string_utf8(env, deviceId.c_str(), deviceId.size(), &result);
1261     return result;
1262 }
1263 
GetLocalDeviceName(napi_env env, napi_callback_info info)1264 napi_value DeviceManagerNapi::GetLocalDeviceName(napi_env env, napi_callback_info info)
1265 {
1266     LOGI("GetLocalDeviceName in");
1267     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1268         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1269         return nullptr;
1270     }
1271     napi_value result = nullptr;
1272     napi_value thisVar = nullptr;
1273     std::string deviceName;
1274     size_t argc = 0;
1275 
1276     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1277     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1278     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1279         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1280         return result;
1281     }
1282 
1283     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceName(deviceManagerWrapper->bundleName_, deviceName);
1284     if (ret != 0) {
1285         LOGE("GetLocalDeviceName for failed, ret %{public}d", ret);
1286         CreateBusinessError(env, ret);
1287         return result;
1288     }
1289     LOGI("DeviceManager::GetLocalDeviceName deviceName:%{public}s", GetAnonyString(std::string(deviceName)).c_str());
1290     napi_create_string_utf8(env, deviceName.c_str(), deviceName.size(), &result);
1291     return result;
1292 }
1293 
GetLocalDeviceType(napi_env env, napi_callback_info info)1294 napi_value DeviceManagerNapi::GetLocalDeviceType(napi_env env, napi_callback_info info)
1295 {
1296     LOGI("GetLocalDeviceType in");
1297     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1298         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1299         return nullptr;
1300     }
1301     napi_value result = nullptr;
1302     napi_value thisVar = nullptr;
1303     int32_t deviceType = 0;
1304     size_t argc = 0;
1305 
1306     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1307     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1308     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1309         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1310         return result;
1311     }
1312 
1313     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceType(deviceManagerWrapper->bundleName_, deviceType);
1314     if (ret != 0) {
1315         LOGE("GetLocalDeviceType for failed, ret %{public}d", ret);
1316         CreateBusinessError(env, ret);
1317         return result;
1318     }
1319     LOGI("DeviceManager::GetLocalDeviceType deviceType:%{public}d", deviceType);
1320     napi_create_int32(env, deviceType, &result);
1321     return result;
1322 }
1323 
GetDeviceName(napi_env env, napi_callback_info info)1324 napi_value DeviceManagerNapi::GetDeviceName(napi_env env, napi_callback_info info)
1325 {
1326     LOGI("GetDeviceName in");
1327     napi_value result = nullptr;
1328     std::string deviceName;
1329     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1330     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1331         return nullptr;
1332     }
1333     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1334     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1335         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1336         return result;
1337     }
1338     std::string networkId;
1339     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
1340         return nullptr;
1341     }
1342 
1343     int32_t ret = DeviceManager::GetInstance().GetDeviceName(deviceManagerWrapper->bundleName_, networkId, deviceName);
1344     if (ret != 0) {
1345         LOGE("GetDeviceName for failed, ret %{public}d", ret);
1346         CreateBusinessError(env, ret);
1347         return result;
1348     }
1349     LOGI("DeviceManager::GetDeviceName deviceName:%{public}s", GetAnonyString(std::string(deviceName)).c_str());
1350     napi_create_string_utf8(env, deviceName.c_str(), deviceName.size(), &result);
1351     return result;
1352 }
1353 
GetDeviceType(napi_env env, napi_callback_info info)1354 napi_value DeviceManagerNapi::GetDeviceType(napi_env env, napi_callback_info info)
1355 {
1356     LOGI("GetDeviceType in");
1357     napi_value result = nullptr;
1358     int32_t deviceType;
1359     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1360     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1361         return nullptr;
1362     }
1363     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1364     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1365         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1366         return result;
1367     }
1368     std::string networkId;
1369     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
1370         return nullptr;
1371     }
1372 
1373     int32_t ret = DeviceManager::GetInstance().GetDeviceType(deviceManagerWrapper->bundleName_, networkId, deviceType);
1374     if (ret != 0) {
1375         LOGE("GetDeviceType for failed, ret %{public}d", ret);
1376         CreateBusinessError(env, ret);
1377         return result;
1378     }
1379     LOGI("DeviceManager::GetDeviceType deviceType:%{public}d", deviceType);
1380     napi_create_int32(env, deviceType, &result);
1381     return result;
1382 }
1383 
LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName, std::string &extra, uint32_t subscribeId)1384 void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName, std::string &extra,
1385     uint32_t subscribeId)
1386 {
1387     std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = nullptr;
1388     {
1389         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1390         auto iter = g_DiscoveryCallbackMap.find(bundleName);
1391         if (iter == g_DiscoveryCallbackMap.end()) {
1392             discoveryCallback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
1393             g_DiscoveryCallbackMap[bundleName] = discoveryCallback;
1394         } else {
1395             discoveryCallback = iter->second;
1396         }
1397     }
1398     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1399     int32_t ret = DeviceManager::GetInstance().StartDeviceDiscovery(bundleName, tokenId, extra, discoveryCallback);
1400     if (ret != 0) {
1401         LOGE("Discovery failed, bundleName %{public}s, ret %{public}d", bundleName.c_str(), ret);
1402         CreateBusinessError(env, ret);
1403         discoveryCallback->OnDiscoveryFailed(static_cast<uint16_t>(subscribeId), ret);
1404     }
1405     return;
1406 }
1407 
StartDeviceDiscover(napi_env env, napi_callback_info info)1408 napi_value DeviceManagerNapi::StartDeviceDiscover(napi_env env, napi_callback_info info)
1409 {
1410     LOGI("StartDeviceDiscover in");
1411     std::string extra = "";
1412     napi_value result = nullptr;
1413     napi_value thisVar = nullptr;
1414     size_t argcNum = 0;
1415     int32_t discoverTargetType = -1;
1416     uint32_t subscribeId = 0;
1417     NAPI_CALL(env, napi_get_cb_info(env, info, &argcNum, nullptr, &thisVar, nullptr));
1418     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1419     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1420         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1421         return result;
1422     }
1423     if (argcNum == DM_NAPI_ARGS_ONE) {
1424         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1425         if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
1426             return nullptr;
1427         }
1428     } else if (argcNum == DM_NAPI_ARGS_TWO) {
1429         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1430         if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
1431             return nullptr;
1432         }
1433         napi_valuetype objectType = napi_undefined;
1434         napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &objectType);
1435         if (!(CheckArgsType(env, objectType == napi_object, "filterOptions", "object or undefined"))) {
1436             return nullptr;
1437         }
1438         JsToDmDiscoveryExtra(env, argv[DM_NAPI_ARGS_ONE], extra);
1439     }
1440     LockDiscoveryCallbackMutex(env, deviceManagerWrapper->bundleName_, extra, subscribeId);
1441     napi_get_undefined(env, &result);
1442     return result;
1443 }
1444 
StopDeviceDiscover(napi_env env, napi_callback_info info)1445 napi_value DeviceManagerNapi::StopDeviceDiscover(napi_env env, napi_callback_info info)
1446 {
1447     LOGI("StopDeviceDiscover in");
1448     napi_value result = nullptr;
1449     napi_value thisVar = nullptr;
1450     size_t argc = 0;
1451     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1452     if (argc != 0) {
1453         return nullptr;
1454     }
1455     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1456     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1457         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1458         return result;
1459     }
1460     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1461     int32_t ret = DeviceManager::GetInstance().StopDeviceDiscovery(tokenId, deviceManagerWrapper->bundleName_);
1462     if (ret != 0) {
1463         LOGE("StopDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
1464             deviceManagerWrapper->bundleName_.c_str(), ret);
1465         CreateBusinessError(env, ret);
1466         return result;
1467     }
1468     napi_get_undefined(env, &result);
1469     return result;
1470 }
1471 
PublishDeviceDiscoverySync(napi_env env, napi_callback_info info)1472 napi_value DeviceManagerNapi::PublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
1473 {
1474     LOGI("PublishDeviceDiscoverySync in");
1475     if (!IsSystemApp()) {
1476         LOGI("PublishDeviceDiscoverySync not SystemApp");
1477         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1478         return nullptr;
1479     }
1480     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1481     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1482         return nullptr;
1483     }
1484 
1485     napi_value result = nullptr;
1486     napi_valuetype valueType = napi_undefined;
1487     napi_typeof(env, argv[0], &valueType);
1488     if (!CheckArgsType(env, valueType == napi_object, "publishInfo", "object")) {
1489         return nullptr;
1490     }
1491     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1492     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1493         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1494         return result;
1495     }
1496 
1497     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
1498     {
1499         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1500         auto iter = g_publishCallbackMap.find(deviceManagerWrapper->bundleName_);
1501         if (iter == g_publishCallbackMap.end()) {
1502             publishCallback = std::make_shared<DmNapiPublishCallback>(env, deviceManagerWrapper->bundleName_);
1503             g_publishCallbackMap[deviceManagerWrapper->bundleName_] = publishCallback;
1504         } else {
1505             publishCallback = iter->second;
1506         }
1507     }
1508     DmPublishInfo publishInfo;
1509     JsToDmPublishInfo(env, argv[0], publishInfo);
1510     int32_t ret = DeviceManager::GetInstance().PublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishInfo,
1511         publishCallback);
1512     if (ret != 0) {
1513         LOGE("PublishDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
1514             deviceManagerWrapper->bundleName_.c_str(), ret);
1515         CreateBusinessError(env, ret);
1516         publishCallback->OnPublishResult(publishInfo.publishId, ret);
1517         return result;
1518     }
1519 
1520     napi_get_undefined(env, &result);
1521     return result;
1522 }
1523 
UnPublishDeviceDiscoverySync(napi_env env, napi_callback_info info)1524 napi_value DeviceManagerNapi::UnPublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
1525 {
1526     LOGI("UnPublishDeviceDiscoverySync in");
1527     if (!IsSystemApp()) {
1528         LOGI("UnPublishDeviceDiscoverySync not SystemApp");
1529         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1530         return nullptr;
1531     }
1532     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1533     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1534         return nullptr;
1535     }
1536     napi_value result = nullptr;
1537     napi_valuetype valueType = napi_undefined;
1538     napi_typeof(env, argv[0], &valueType);
1539     if (!CheckArgsType(env, valueType == napi_number, "publishId", "number")) {
1540         return nullptr;
1541     }
1542     int32_t publishId = 0;
1543     napi_get_value_int32(env, argv[0], &publishId);
1544 
1545     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1546     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1547         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1548         return result;
1549     }
1550 
1551     int32_t ret = DeviceManager::GetInstance().UnPublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishId);
1552     if (ret != 0) {
1553         LOGE("UnPublishDeviceDiscovery bundleName %{public}s failed, ret %{public}d",
1554             deviceManagerWrapper->bundleName_.c_str(), ret);
1555         CreateBusinessError(env, ret);
1556         return result;
1557     }
1558 
1559     napi_get_undefined(env, &result);
1560     return result;
1561 }
1562 
BindDevOrTarget(DeviceManagerNapi *deviceManagerWrapper, const std::string &deviceId, napi_env env, napi_value &object)1563 void DeviceManagerNapi::BindDevOrTarget(DeviceManagerNapi *deviceManagerWrapper, const std::string &deviceId,
1564     napi_env env, napi_value &object)
1565 {
1566     LOGI("Bind devices or target start");
1567     std::string bindParam;
1568     bool isMetaType = false;
1569     JsToBindParam(env, object, bindParam, authAsyncCallbackInfo_.authType, isMetaType);
1570 
1571     if (isMetaType) {
1572         std::shared_ptr<DmNapiBindTargetCallback> bindTargetCallback = nullptr;
1573         {
1574             std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
1575             auto iter = g_bindCallbackMap.find(deviceManagerWrapper->bundleName_);
1576             if (iter == g_bindCallbackMap.end()) {
1577                 bindTargetCallback = std::make_shared<DmNapiBindTargetCallback>(env, deviceManagerWrapper->bundleName_);
1578                 g_bindCallbackMap[deviceManagerWrapper->bundleName_] = bindTargetCallback;
1579             } else {
1580                 bindTargetCallback = iter->second;
1581             }
1582         }
1583         int32_t ret = BindTargetWarpper(deviceManagerWrapper->bundleName_, deviceId, bindParam, bindTargetCallback);
1584         if (ret != 0) {
1585             LOGE("BindTarget for bundleName %{public}s failed, ret %{public}d",
1586                 deviceManagerWrapper->bundleName_.c_str(), ret);
1587             CreateBusinessError(env, ret);
1588         }
1589         return;
1590     }
1591 
1592     std::shared_ptr<DmNapiAuthenticateCallback> bindDeviceCallback = nullptr;
1593     {
1594         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
1595         auto iter = g_authCallbackMap.find(deviceManagerWrapper->bundleName_);
1596         if (iter == g_authCallbackMap.end()) {
1597             bindDeviceCallback = std::make_shared<DmNapiAuthenticateCallback>(env, deviceManagerWrapper->bundleName_);
1598             g_authCallbackMap[deviceManagerWrapper->bundleName_] = bindDeviceCallback;
1599         } else {
1600             bindDeviceCallback = iter->second;
1601         }
1602     }
1603     int32_t ret = DeviceManager::GetInstance().BindDevice(deviceManagerWrapper->bundleName_,
1604         authAsyncCallbackInfo_.authType, deviceId, bindParam, bindDeviceCallback);
1605     if (ret != 0) {
1606         LOGE("BindDevice for bundleName %{public}s failed, ret %{public}d",
1607             deviceManagerWrapper->bundleName_.c_str(), ret);
1608         CreateBusinessError(env, ret);
1609     }
1610     return;
1611 }
1612 
BindTarget(napi_env env, napi_callback_info info)1613 napi_value DeviceManagerNapi::BindTarget(napi_env env, napi_callback_info info)
1614 {
1615     GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1616     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE,  "Wrong number of arguments, required 3")) {
1617         return nullptr;
1618     }
1619     napi_valuetype bindPramType = napi_undefined;
1620     napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &bindPramType);
1621     if (!CheckArgsType(env, bindPramType == napi_object, "bindParam", "object")) {
1622         return nullptr;
1623     }
1624     if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
1625         return nullptr;
1626     }
1627     napi_value result = nullptr;
1628     authAsyncCallbackInfo_.env = env;
1629     napi_create_reference(env, argv[DM_NAPI_ARGS_TWO], 1, &authAsyncCallbackInfo_.callback);
1630     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1631     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1632         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1633         return result;
1634     }
1635     std::string deviceId;
1636     if (!JsToStringAndCheck(env, argv[DM_NAPI_ARGS_ZERO], "deviceId", deviceId)) {
1637         return nullptr;
1638     }
1639 
1640     napi_value object = argv[DM_NAPI_ARGS_ONE];
1641     BindDevOrTarget(deviceManagerWrapper, deviceId, env, object);
1642     napi_get_undefined(env, &result);
1643     return result;
1644 }
1645 
UnBindTarget(napi_env env, napi_callback_info info)1646 napi_value DeviceManagerNapi::UnBindTarget(napi_env env, napi_callback_info info)
1647 {
1648     LOGI("UnBindDevice");
1649     napi_value result = nullptr;
1650     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1651     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1652         return nullptr;
1653     }
1654     std::string deviceId;
1655     if (!JsToStringAndCheck(env, argv[0], "deviceId", deviceId)) {
1656         return nullptr;
1657     }
1658 
1659     LOGI("UnBindDevice deviceId = %{public}s", GetAnonyString(deviceId).c_str());
1660     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1661     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1662         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1663         return result;
1664     }
1665 
1666     int32_t ret = DeviceManager::GetInstance().UnBindDevice(deviceManagerWrapper->bundleName_, deviceId);
1667     if (ret != 0) {
1668         LOGE("UnBindDevice for bundleName %{public}s failed, ret %{public}d",
1669             deviceManagerWrapper->bundleName_.c_str(), ret);
1670         CreateBusinessError(env, ret);
1671     }
1672 
1673     napi_get_undefined(env, &result);
1674     return result;
1675 }
1676 
JsOnFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])1677 napi_value DeviceManagerNapi::JsOnFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
1678 {
1679     std::string eventType;
1680     if (!JsToStringAndCheck(env, argv[0], "type", eventType)) {
1681         return nullptr;
1682     }
1683 
1684     napi_value result = nullptr;
1685     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1686     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1687         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1688         return result;
1689     }
1690 
1691     LOGI("JsOn for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
1692         eventType.c_str());
1693     deviceManagerWrapper->On(eventType, argv[num + 1]);
1694 
1695     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1696         if (num == 1) {
1697             std::string extraString;
1698             if (!JsToStringAndCheck(env, argv[1], "extra", extraString)) {
1699                 return nullptr;
1700             }
1701             LOGI("extra = %{public}s", extraString.c_str());
1702             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType, extraString);
1703         } else {
1704             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
1705         }
1706     } else {
1707         CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
1708     }
1709 
1710     napi_get_undefined(env, &result);
1711     return result;
1712 }
1713 
JsOn(napi_env env, napi_callback_info info)1714 napi_value DeviceManagerNapi::JsOn(napi_env env, napi_callback_info info)
1715 {
1716     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1717     if (ret != 0) {
1718         CreateBusinessError(env, ret);
1719         return nullptr;
1720     }
1721     size_t argc = 0;
1722     napi_value thisVar = nullptr;
1723     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1724     if (argc == DM_NAPI_ARGS_THREE) {
1725         LOGI("JsOn in argc == 3");
1726         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1727         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE, "Wrong number of arguments, required 3")) {
1728             return nullptr;
1729         }
1730         napi_valuetype eventValueType = napi_undefined;
1731         napi_typeof(env, argv[0], &eventValueType);
1732         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1733             return nullptr;
1734         }
1735         napi_valuetype valueType;
1736         napi_typeof(env, argv[1], &valueType);
1737         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object),
1738             "extra", "string | object")) {
1739             return nullptr;
1740         }
1741         if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
1742             return nullptr;
1743         }
1744         return JsOnFrench(env, 1, thisVar, argv);
1745     } else {
1746         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1747         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
1748             return nullptr;
1749         }
1750         napi_valuetype eventValueType = napi_undefined;
1751         napi_typeof(env, argv[0], &eventValueType);
1752         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1753             return nullptr;
1754         }
1755         if (!IsFunctionType(env, argv[1])) {
1756             return nullptr;
1757         }
1758         return JsOnFrench(env, 0, thisVar, argv);
1759     }
1760 }
1761 
JsOffFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])1762 napi_value DeviceManagerNapi::JsOffFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
1763 {
1764     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1765     if (ret != 0) {
1766         CreateBusinessError(env, ret);
1767         return nullptr;
1768     }
1769     std::string eventType;
1770     if (!JsToStringAndCheck(env, argv[0], "type", eventType)) {
1771         return nullptr;
1772     }
1773     napi_value result = nullptr;
1774     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1775     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1776         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1777         return result;
1778     }
1779 
1780     LOGI("JsOff for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
1781         eventType.c_str());
1782     deviceManagerWrapper->Off(eventType);
1783     ReleaseDmCallback(deviceManagerWrapper->bundleName_, eventType);
1784 
1785     napi_get_undefined(env, &result);
1786     return result;
1787 }
1788 
JsOff(napi_env env, napi_callback_info info)1789 napi_value DeviceManagerNapi::JsOff(napi_env env, napi_callback_info info)
1790 {
1791     size_t argc = 0;
1792     napi_value thisVar = nullptr;
1793     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1794     if (argc == DM_NAPI_ARGS_THREE) {
1795         LOGI("JsOff in argc == 3");
1796         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1797         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1798             return nullptr;
1799         }
1800         napi_valuetype eventValueType = napi_undefined;
1801         napi_typeof(env, argv[0], &eventValueType);
1802         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1803             return nullptr;
1804         }
1805         napi_valuetype valueType;
1806         napi_typeof(env, argv[1], &valueType);
1807         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object), "extra", "string or object")) {
1808             return nullptr;
1809         }
1810         if (argc > DM_NAPI_ARGS_ONE) {
1811             if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
1812                 return nullptr;
1813             }
1814         }
1815         return JsOffFrench(env, 1, thisVar, argv);
1816     } else {
1817         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1818         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1819             return nullptr;
1820         }
1821         napi_valuetype eventValueType = napi_undefined;
1822         napi_typeof(env, argv[0], &eventValueType);
1823         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1824             return nullptr;
1825         }
1826         if (argc > DM_NAPI_ARGS_ONE) {
1827             if (!IsFunctionType(env, argv[1])) {
1828                 return nullptr;
1829             }
1830         }
1831         return JsOffFrench(env, 0, thisVar, argv);
1832     }
1833 }
1834 
ClearBundleCallbacks(std::string &bundleName)1835 void DeviceManagerNapi::ClearBundleCallbacks(std::string &bundleName)
1836 {
1837     LOGI("ClearBundleCallbacks start for bundleName %{public}s", bundleName.c_str());
1838     {
1839         std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
1840         g_deviceManagerMap.erase(bundleName);
1841     }
1842     {
1843         std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
1844         g_initCallbackMap.erase(bundleName);
1845     }
1846     {
1847         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
1848         g_deviceStatusCallbackMap.erase(bundleName);
1849     }
1850     {
1851         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1852         g_DiscoveryCallbackMap.erase(bundleName);
1853     }
1854     {
1855         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1856         g_publishCallbackMap.erase(bundleName);
1857     }
1858     {
1859         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
1860         g_authCallbackMap.erase(bundleName);
1861     }
1862     {
1863         std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
1864         g_bindCallbackMap.erase(bundleName);
1865     }
1866     return;
1867 }
1868 
ReleaseDeviceManager(napi_env env, napi_callback_info info)1869 napi_value DeviceManagerNapi::ReleaseDeviceManager(napi_env env, napi_callback_info info)
1870 {
1871     LOGI("ReleaseDeviceManager in");
1872     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1873     if (!CheckArgsCount(env, argc == DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1874         return nullptr;
1875     }
1876     napi_valuetype argvType = napi_undefined;
1877     napi_typeof(env, argv[0], &argvType);
1878     if (!CheckArgsType(env, argvType == napi_object, "DeviceManager", "object")) {
1879         return nullptr;
1880     }
1881     napi_value result = nullptr;
1882     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1883     if (IsDeviceManagerNapiNull(env, argv[0], &deviceManagerWrapper)) {
1884         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1885         return result;
1886     }
1887     LOGI("ReleaseDeviceManager for bundleName %{public}s", deviceManagerWrapper->bundleName_.c_str());
1888     int32_t ret = DeviceManager::GetInstance().UnInitDeviceManager(deviceManagerWrapper->bundleName_);
1889     if (ret != 0) {
1890         LOGE("ReleaseDeviceManager for bundleName %{public}s failed, ret %{public}d",
1891             deviceManagerWrapper->bundleName_.c_str(), ret);
1892         CreateBusinessError(env, ret);
1893         napi_create_uint32(env, static_cast<uint32_t>(ret), &result);
1894         return result;
1895     }
1896     ClearBundleCallbacks(deviceManagerWrapper->bundleName_);
1897     napi_get_undefined(env, &result);
1898     NAPI_CALL(env, napi_remove_wrap(env, argv[0], (void**)&deviceManagerWrapper));
1899     return result;
1900 }
1901 
CreateDeviceManager(napi_env env, napi_callback_info info)1902 napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info)
1903 {
1904     LOGI("In");
1905     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1906     if (!CheckArgsCount(env, argc == DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1907         return nullptr;
1908     }
1909     std::string bundleName;
1910     if (!JsToStringAndCheck(env, argv[0], "bundleName", bundleName)) {
1911         return nullptr;
1912     }
1913     std::shared_ptr<DmNapiInitCallback> initCallback = std::make_shared<DmNapiInitCallback>(env, bundleName);
1914     int32_t ret = DeviceManager::GetInstance().InitDeviceManager(bundleName, initCallback);
1915     if (ret != 0) {
1916         LOGE("CreateDeviceManager for bundleName %{public}s failed, ret %{public}d.", bundleName.c_str(), ret);
1917         CreateBusinessError(env, ret);
1918         return nullptr;
1919     }
1920     {
1921         std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
1922         g_initCallbackMap[bundleName] = initCallback;
1923     }
1924     napi_value ctor = nullptr;
1925     napi_value napiName = nullptr;
1926     napi_value result = nullptr;
1927     napi_get_reference_value(env, sConstructor_, &ctor);
1928     napi_create_string_utf8(env, bundleName.c_str(), NAPI_AUTO_LENGTH, &napiName);
1929     napi_status status = napi_new_instance(env, ctor, DM_NAPI_ARGS_ONE, &napiName, &result);
1930     if (status != napi_ok) {
1931         LOGE("Create DeviceManagerNapi for bundleName %{public}s failed", bundleName.c_str());
1932     }
1933     return result;
1934 }
1935 
Constructor(napi_env env, napi_callback_info info)1936 napi_value DeviceManagerNapi::Constructor(napi_env env, napi_callback_info info)
1937 {
1938     LOGI("In");
1939     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1940     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1941         return nullptr;
1942     }
1943     std::string bundleName;
1944     if (!JsToStringAndCheck(env, argv[0], "bundleName", bundleName)) {
1945         return nullptr;
1946     }
1947 
1948     LOGI("Create for packageName:%{public}s", bundleName.c_str());
1949     DeviceManagerNapi *obj = new DeviceManagerNapi(env, thisVar);
1950     if (obj == nullptr) {
1951         return nullptr;
1952     }
1953 
1954     obj->bundleName_ = bundleName;
1955     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
1956     g_deviceManagerMap[obj->bundleName_] = obj;
1957     napi_wrap(
1958         env, thisVar, reinterpret_cast<void *>(obj),
1959         [](napi_env env, void *data, void *hint) {
1960             (void)env;
1961             (void)hint;
1962             DeviceManagerNapi *deviceManager = reinterpret_cast<DeviceManagerNapi *>(data);
1963             delete deviceManager;
1964             deviceManager = nullptr;
1965             LOGI("delete deviceManager");
1966         },
1967         nullptr, nullptr);
1968     return thisVar;
1969 }
1970 
Init(napi_env env, napi_value exports)1971 napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports)
1972 {
1973     napi_value dmClass = nullptr;
1974     napi_property_descriptor dmProperties[] = {
1975         DECLARE_NAPI_FUNCTION("getAvailableDeviceListSync", GetAvailableDeviceListSync),
1976         DECLARE_NAPI_FUNCTION("getAvailableDeviceList", GetAvailableDeviceList),
1977         DECLARE_NAPI_FUNCTION("getLocalDeviceNetworkId", GetLocalDeviceNetworkId),
1978         DECLARE_NAPI_FUNCTION("getLocalDeviceId", GetLocalDeviceId),
1979         DECLARE_NAPI_FUNCTION("getLocalDeviceName", GetLocalDeviceName),
1980         DECLARE_NAPI_FUNCTION("getLocalDeviceType", GetLocalDeviceType),
1981         DECLARE_NAPI_FUNCTION("getDeviceName", GetDeviceName),
1982         DECLARE_NAPI_FUNCTION("getDeviceType", GetDeviceType),
1983         DECLARE_NAPI_FUNCTION("startDiscovering", StartDeviceDiscover),
1984         DECLARE_NAPI_FUNCTION("stopDiscovering", StopDeviceDiscover),
1985         DECLARE_NAPI_FUNCTION("unbindTarget", UnBindTarget),
1986         DECLARE_NAPI_FUNCTION("bindTarget", BindTarget),
1987         DECLARE_NAPI_FUNCTION("replyUiAction", SetUserOperationSync),
1988         DECLARE_NAPI_FUNCTION("on", JsOn),
1989         DECLARE_NAPI_FUNCTION("off", JsOff)};
1990 
1991     napi_property_descriptor static_prop[] = {
1992         DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager),
1993         DECLARE_NAPI_STATIC_FUNCTION("releaseDeviceManager", ReleaseDeviceManager),
1994     };
1995 
1996     LOGI("DeviceManagerNapi::Init() is called!");
1997     NAPI_CALL(env, napi_define_class(env, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor,
1998                                      nullptr, sizeof(dmProperties) / sizeof(dmProperties[0]), dmProperties, &dmClass));
1999     NAPI_CALL(env, napi_create_reference(env, dmClass, 1, &sConstructor_));
2000     NAPI_CALL(env, napi_set_named_property(env, exports, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), dmClass));
2001     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop));
2002     LOGI("All props and functions are configured..");
2003     return exports;
2004 }
2005 
EnumTypeConstructor(napi_env env, napi_callback_info info)2006 napi_value DeviceManagerNapi::EnumTypeConstructor(napi_env env, napi_callback_info info)
2007 {
2008     size_t argc = 0;
2009     napi_value res = nullptr;
2010     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &res, nullptr));
2011     return res;
2012 }
2013 
InitDeviceStatusChangeActionEnum(napi_env env, napi_value exports)2014 napi_value DeviceManagerNapi::InitDeviceStatusChangeActionEnum(napi_env env, napi_value exports)
2015 {
2016     napi_value device_state_online;
2017     napi_value device_state_ready;
2018     napi_value device_state_offline;
2019     int32_t refCount = 1;
2020 
2021     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_ONLINE),
2022         &device_state_online);
2023     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_READY),
2024         &device_state_ready);
2025     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_OFFLINE),
2026         &device_state_offline);
2027 
2028     napi_property_descriptor desc[] = {
2029         DECLARE_NAPI_STATIC_PROPERTY("UNKNOWN", device_state_online),
2030         DECLARE_NAPI_STATIC_PROPERTY("AVAILABLE", device_state_ready),
2031         DECLARE_NAPI_STATIC_PROPERTY("UNAVAILABLE", device_state_offline),
2032     };
2033 
2034     napi_value result = nullptr;
2035     napi_define_class(env, "DeviceStateChange", NAPI_AUTO_LENGTH, EnumTypeConstructor,
2036         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
2037     napi_create_reference(env, result, refCount, &deviceStateChangeActionEnumConstructor_);
2038     napi_set_named_property(env, exports, "DeviceStateChange", result);
2039     return exports;
2040 }
2041 
BindTargetWarpper(const std::string &pkgName, const std::string &deviceId, const std::string &bindParam, std::shared_ptr<DmNapiBindTargetCallback> callback)2042 int32_t DeviceManagerNapi::BindTargetWarpper(const std::string &pkgName, const std::string &deviceId,
2043     const std::string &bindParam, std::shared_ptr<DmNapiBindTargetCallback> callback)
2044 {
2045     if (bindParam.empty()) {
2046         return ERR_DM_INPUT_PARA_INVALID;
2047     }
2048     nlohmann::json bindParamObj = nlohmann::json::parse(bindParam, nullptr, false);
2049     if (bindParamObj.is_discarded()) {
2050         return ERR_DM_INPUT_PARA_INVALID;
2051     }
2052     PeerTargetId targetId;
2053     targetId.deviceId = deviceId;
2054     if (IsString(bindParamObj, PARAM_KEY_BR_MAC)) {
2055         targetId.brMac = bindParamObj[PARAM_KEY_BR_MAC].get<std::string>();
2056     }
2057     if (IsString(bindParamObj, PARAM_KEY_BLE_MAC)) {
2058         targetId.bleMac = bindParamObj[PARAM_KEY_BLE_MAC].get<std::string>();
2059     }
2060     if (IsString(bindParamObj, PARAM_KEY_WIFI_IP)) {
2061         targetId.wifiIp = bindParamObj[PARAM_KEY_WIFI_IP].get<std::string>();
2062     }
2063     if (IsInt32(bindParamObj, PARAM_KEY_WIFI_PORT)) {
2064         targetId.wifiPort = (uint16_t)(bindParamObj[PARAM_KEY_WIFI_PORT].get<int32_t>());
2065     }
2066 
2067     std::map<std::string, std::string> bindParamMap;
2068     InsertMapParames(bindParamObj, bindParamMap);
2069     return DeviceManager::GetInstance().BindTarget(pkgName, targetId, bindParamMap, callback);
2070 }
2071 
2072 /*
2073  * Function registering all props and functions of ohos.distributedhardware
2074  */
Export(napi_env env, napi_value exports)2075 static napi_value Export(napi_env env, napi_value exports)
2076 {
2077     LOGI("Export() is called!");
2078     DeviceManagerNapi::Init(env, exports);
2079     DeviceManagerNapi::InitDeviceStatusChangeActionEnum(env, exports);
2080     return exports;
2081 }
2082 
2083 /*
2084  * module define
2085  */
2086 static napi_module g_dmModule = {.nm_version = 1,
2087                                  .nm_flags = 0,
2088                                  .nm_filename = nullptr,
2089                                  .nm_register_func = Export,
2090                                  .nm_modname = "distributedDeviceManager",
2091                                  .nm_priv = ((void *)0),
2092                                  .reserved = {0}};
2093 
2094 /*
2095  * module register
2096  */
RegisterModule(void)2097 extern "C" __attribute__((constructor)) void RegisterModule(void)
2098 {
2099     LOGI("RegisterModule() is called!");
2100     napi_module_register(&g_dmModule);
2101 }
2102