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