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