• 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 "json_object.h"
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 #define CHECK_NULL_VOID_RET_LOG(ptr, fmt, ...)      \
44     do {                                            \
45         if ((ptr) == NULL) {                        \
46             LOGE(fmt, ##__VA_ARGS__);               \
47             return;                                 \
48         }                                           \
49     } while (0)
50 
51 const std::string DM_NAPI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange";
52 const std::string DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS = "discoverSuccess";
53 const std::string DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL = "discoverFail";
54 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS = "publishSuccess";
55 const std::string DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL = "publishFail";
56 const std::string DM_NAPI_EVENT_DEVICE_SERVICE_DIE = "serviceDie";
57 const std::string DEVICE_MANAGER_NAPI_CLASS_NAME = "DeviceManager";
58 const std::string DM_NAPI_EVENT_REPLY_RESULT = "replyResult";
59 const std::string DM_NAPI_EVENT_DEVICE_NAME_CHANGE = "deviceNameChange";
60 
61 const int32_t DM_NAPI_ARGS_ZERO = 0;
62 const int32_t DM_NAPI_ARGS_ONE = 1;
63 const int32_t DM_NAPI_ARGS_TWO = 2;
64 const int32_t DM_NAPI_ARGS_THREE = 3;
65 const int32_t DM_AUTH_REQUEST_SUCCESS_STATUS = 7;
66 const int32_t DM_MAX_DEVICE_SIZE = 100;
67 
68 napi_ref deviceStateChangeActionEnumConstructor_ = nullptr;
69 napi_ref g_strategyForHeartbeatEnumConstructor = nullptr;
70 
71 std::map<std::string, DeviceManagerNapi *> g_deviceManagerMap;
72 std::map<std::string, std::shared_ptr<DmNapiInitCallback>> g_initCallbackMap;
73 std::map<std::string, std::shared_ptr<DmNapiDeviceStatusCallback>> g_deviceStatusCallbackMap;
74 std::map<std::string, std::shared_ptr<DmNapiDiscoveryCallback>> g_DiscoveryCallbackMap;
75 std::map<std::string, std::shared_ptr<DmNapiPublishCallback>> g_publishCallbackMap;
76 std::map<std::string, std::shared_ptr<DmNapiAuthenticateCallback>> g_authCallbackMap;
77 std::map<std::string, std::shared_ptr<DmNapiBindTargetCallback>> g_bindCallbackMap;
78 std::map<std::string, std::shared_ptr<DmNapiDeviceManagerUiCallback>> g_dmUiCallbackMap;
79 
80 std::mutex g_deviceManagerMapMutex;
81 std::mutex g_initCallbackMapMutex;
82 std::mutex g_deviceStatusCallbackMapMutex;
83 std::mutex g_discoveryCallbackMapMutex;
84 std::mutex g_publishCallbackMapMutex;
85 std::mutex g_authCallbackMapMutex;
86 std::mutex g_bindCallbackMapMutex;
87 std::mutex g_dmUiCallbackMapMutex;
88 
DeleteUvWork(uv_work_t * & work)89 void DeleteUvWork(uv_work_t *&work)
90 {
91     if (work == nullptr) {
92         return;
93     }
94     delete work;
95     work = nullptr;
96     LOGI("delete work!");
97 }
98 
DeleteDmNapiStatusJsCallbackPtr(DmNapiStatusJsCallback * & pJsCallbackPtr)99 void DeleteDmNapiStatusJsCallbackPtr(DmNapiStatusJsCallback *&pJsCallbackPtr)
100 {
101     if (pJsCallbackPtr == nullptr) {
102         return;
103     }
104     delete pJsCallbackPtr;
105     pJsCallbackPtr = nullptr;
106     LOGI("delete DmNapiStatusJsCallback callbackPtr!");
107 }
108 
DeleteAsyncCallbackInfo(DeviceBasicInfoListAsyncCallbackInfo * & pAsynCallbackInfo)109 void DeleteAsyncCallbackInfo(DeviceBasicInfoListAsyncCallbackInfo *&pAsynCallbackInfo)
110 {
111     if (pAsynCallbackInfo == nullptr) {
112         return;
113     }
114     delete pAsynCallbackInfo;
115     pAsynCallbackInfo = nullptr;
116 }
117 
IsDeviceManagerNapiNull(napi_env env,napi_value thisVar,DeviceManagerNapi ** pDeviceManagerWrapper)118 bool IsDeviceManagerNapiNull(napi_env env, napi_value thisVar, DeviceManagerNapi **pDeviceManagerWrapper)
119 {
120     napi_unwrap(env, thisVar, reinterpret_cast<void **>(pDeviceManagerWrapper));
121     if (pDeviceManagerWrapper != nullptr && *pDeviceManagerWrapper != nullptr) {
122         return false;
123     }
124     CreateBusinessError(env, ERR_DM_POINT_NULL);
125     LOGE("DeviceManagerNapi object is nullptr!");
126     return true;
127 }
128 } // namespace
129 
130 thread_local napi_ref DeviceManagerNapi::sConstructor_ = nullptr;
131 AuthAsyncCallbackInfo DeviceManagerNapi::authAsyncCallbackInfo_;
132 
OnRemoteDied()133 void DmNapiInitCallback::OnRemoteDied()
134 {
135     uv_loop_s *loop = nullptr;
136     napi_get_uv_event_loop(env_, &loop);
137     if (loop == nullptr) {
138         return;
139     }
140     uv_work_t *work = new (std::nothrow) uv_work_t;
141     if (work == nullptr) {
142         LOGE("DmNapiInitCallback: OnRemoteDied, No memory");
143         return;
144     }
145 
146     DmDeviceBasicInfo info;
147     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, info);
148     if (jsCallback == nullptr) {
149         DeleteUvWork(work);
150         return;
151     }
152     work->data = reinterpret_cast<void *>(jsCallback);
153 
154     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
155         LOGD("OnRemoteDied uv_queue_work_with_qos");
156     }, [] (uv_work_t *work, int status) {
157         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
158         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
159         if (deviceManagerNapi == nullptr) {
160             LOGE("OnRemoteDied, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
161         } else {
162             deviceManagerNapi->OnEvent("serviceDie", 0, nullptr);
163         }
164         LOGI("OnRemoteDied, deviceManagerNapi bundleName %{public}s", callback->bundleName_.c_str());
165         DeleteDmNapiStatusJsCallbackPtr(callback);
166         DeleteUvWork(work);
167     }, uv_qos_user_initiated);
168     if (ret != 0) {
169         LOGE("Failed to execute OnRemoteDied work queue");
170         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
171         DeleteUvWork(work);
172     }
173 }
174 
OnDeviceOnline(const DmDeviceBasicInfo & deviceBasicInfo)175 void DmNapiDeviceStatusCallback::OnDeviceOnline(const DmDeviceBasicInfo &deviceBasicInfo)
176 {
177     uv_loop_s *loop = nullptr;
178     napi_get_uv_event_loop(env_, &loop);
179     if (loop == nullptr) {
180         return;
181     }
182     uv_work_t *work = new (std::nothrow) uv_work_t;
183     if (work == nullptr) {
184         LOGE("DmNapiDeviceStatusCallback: OnDeviceOnline, No memory");
185         return;
186     }
187 
188     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
189     if (jsCallback == nullptr) {
190         DeleteUvWork(work);
191         return;
192     }
193     work->data = reinterpret_cast<void *>(jsCallback);
194 
195     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
196         LOGD("OnDeviceOnline uv_queue_work_with_qos");
197     }, [] (uv_work_t *work, int status) {
198         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
199         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
200         if (deviceManagerNapi == nullptr) {
201             LOGE("OnDeviceOnline, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
202         } else {
203             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::UNKNOWN, callback->deviceBasicInfo_);
204         }
205         DeleteDmNapiStatusJsCallbackPtr(callback);
206         DeleteUvWork(work);
207     }, uv_qos_user_initiated);
208     if (ret != 0) {
209         LOGE("Failed to execute OnDeviceOnline work queue");
210         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
211         DeleteUvWork(work);
212     }
213 }
214 
OnDeviceReady(const DmDeviceBasicInfo & deviceBasicInfo)215 void DmNapiDeviceStatusCallback::OnDeviceReady(const DmDeviceBasicInfo &deviceBasicInfo)
216 {
217     uv_loop_s *loop = nullptr;
218     napi_get_uv_event_loop(env_, &loop);
219     if (loop == nullptr) {
220         return;
221     }
222     uv_work_t *work = new (std::nothrow) uv_work_t;
223     if (work == nullptr) {
224         LOGE("DmNapiDeviceStateCallback: OnDeviceReady, No memory");
225         return;
226     }
227 
228     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
229     if (jsCallback == nullptr) {
230         DeleteUvWork(work);
231         return;
232     }
233     work->data = reinterpret_cast<void *>(jsCallback);
234 
235     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
236         LOGD("OnDeviceReady uv_queue_work_with_qos");
237     }, [] (uv_work_t *work, int status) {
238         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
239         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
240         if (deviceManagerNapi == nullptr) {
241             LOGE("OnDeviceReady, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
242         } else {
243             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::AVAILABLE, callback->deviceBasicInfo_);
244         }
245         DeleteDmNapiStatusJsCallbackPtr(callback);
246         DeleteUvWork(work);
247     }, uv_qos_user_initiated);
248     if (ret != 0) {
249         LOGE("Failed to execute OnDeviceReady work queue");
250         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
251         DeleteUvWork(work);
252     }
253 }
254 
OnDeviceOffline(const DmDeviceBasicInfo & deviceBasicInfo)255 void DmNapiDeviceStatusCallback::OnDeviceOffline(const DmDeviceBasicInfo &deviceBasicInfo)
256 {
257     uv_loop_s *loop = nullptr;
258     napi_get_uv_event_loop(env_, &loop);
259     if (loop == nullptr) {
260         return;
261     }
262     uv_work_t *work = new (std::nothrow) uv_work_t;
263     if (work == nullptr) {
264         LOGE("DmNapiDeviceStatusCallback: OnDeviceOffline, No memory");
265         return;
266     }
267 
268     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
269     if (jsCallback == nullptr) {
270         DeleteUvWork(work);
271         return;
272     }
273     work->data = reinterpret_cast<void *>(jsCallback);
274 
275     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
276         LOGD("OnDeviceOffline uv_queue_work_with_qos");
277     }, [] (uv_work_t *work, int status) {
278         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
279         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
280         if (deviceManagerNapi == nullptr) {
281             LOGE("OnDeviceOffline, deviceManagerNapi not find for bundleName %{public}s",
282                 callback->bundleName_.c_str());
283         } else {
284             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::UNAVAILABLE, callback->deviceBasicInfo_);
285         }
286         DeleteDmNapiStatusJsCallbackPtr(callback);
287         DeleteUvWork(work);
288     }, uv_qos_user_initiated);
289     if (ret != 0) {
290         LOGE("Failed to execute OnDeviceOffline work queue");
291         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
292         DeleteUvWork(work);
293     }
294 }
295 
OnDeviceChanged(const DmDeviceBasicInfo & deviceBasicInfo)296 void DmNapiDeviceStatusCallback::OnDeviceChanged(const DmDeviceBasicInfo &deviceBasicInfo)
297 {
298     uv_loop_s *loop = nullptr;
299     napi_get_uv_event_loop(env_, &loop);
300     if (loop == nullptr) {
301         return;
302     }
303     uv_work_t *work = new (std::nothrow) uv_work_t;
304     if (work == nullptr) {
305         LOGE("DmNapiDeviceStatusCallback: OnDeviceChanged, No memory");
306         return;
307     }
308 
309     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, 0, 0, deviceBasicInfo);
310     if (jsCallback == nullptr) {
311         DeleteUvWork(work);
312         return;
313     }
314     work->data = reinterpret_cast<void *>(jsCallback);
315 
316     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
317         LOGD("OnDeviceChanged uv_queue_work_with_qos");
318     }, [] (uv_work_t *work, int status) {
319         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
320         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
321         if (deviceManagerNapi == nullptr) {
322             LOGE("OnDeviceChanged, deviceManagerNapi not find for bundleName %{public}s",
323                 callback->bundleName_.c_str());
324         } else {
325             std::string deviceName = callback->deviceBasicInfo_.deviceName;
326             deviceManagerNapi->OnDeviceStatusChange(DmNapiDevStatusChange::CHANGE, callback->deviceBasicInfo_);
327         }
328         DeleteDmNapiStatusJsCallbackPtr(callback);
329         DeleteUvWork(work);
330     }, uv_qos_user_initiated);
331     if (ret != 0) {
332         LOGE("Failed to execute OnDeviceChanged work queue");
333         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
334         DeleteUvWork(work);
335     }
336 }
337 
OnDeviceFound(uint16_t subscribeId,const DmDeviceBasicInfo & deviceBasicInfo)338 void DmNapiDiscoveryCallback::OnDeviceFound(uint16_t subscribeId,
339                                             const DmDeviceBasicInfo &deviceBasicInfo)
340 {
341     LOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
342     uv_loop_s *loop = nullptr;
343     napi_get_uv_event_loop(env_, &loop);
344     if (loop == nullptr) {
345         return;
346     }
347     uv_work_t *work = new (std::nothrow) uv_work_t;
348     if (work == nullptr) {
349         LOGE("DmNapiDiscoveryCallback: OnDeviceFound, No memory");
350         return;
351     }
352 
353     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, subscribeId, 0, deviceBasicInfo);
354     if (jsCallback == nullptr) {
355         DeleteUvWork(work);
356         return;
357     }
358     work->data = reinterpret_cast<void *>(jsCallback);
359 
360     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
361         LOGD("OnDeviceFound uv_queue_work_with_qos");
362     }, [] (uv_work_t *work, int status) {
363         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
364         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
365         if (deviceManagerNapi == nullptr) {
366             LOGE("OnDeviceFound, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
367         } else {
368             deviceManagerNapi->OnDeviceFound(callback->subscribeId_, callback->deviceBasicInfo_);
369         }
370         DeleteDmNapiStatusJsCallbackPtr(callback);
371         DeleteUvWork(work);
372     }, uv_qos_user_initiated);
373     if (ret != 0) {
374         LOGE("Failed to execute OnDeviceFound work queue");
375         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
376         DeleteUvWork(work);
377     }
378 }
379 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)380 void DmNapiDiscoveryCallback::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
381 {
382     LOGI("OnDiscoveryFailed for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
383 
384     uv_loop_s *loop = nullptr;
385     napi_get_uv_event_loop(env_, &loop);
386     if (loop == nullptr) {
387         return;
388     }
389     uv_work_t *work = new (std::nothrow) uv_work_t;
390     if (work == nullptr) {
391         LOGE("DmNapiDiscoveryCallback: OnDiscoveryFailed, No memory");
392         return;
393     }
394 
395     DmDeviceBasicInfo info;
396     DmNapiStatusJsCallback *jsCallback = new DmNapiStatusJsCallback(bundleName_, subscribeId,
397         failedReason, info);
398     if (jsCallback == nullptr) {
399         DeleteUvWork(work);
400         return;
401     }
402     work->data = reinterpret_cast<void *>(jsCallback);
403 
404     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
405         LOGD("OnDiscoveryFailed uv_queue_work_with_qos");
406     }, [] (uv_work_t *work, int status) {
407         DmNapiStatusJsCallback *callback = reinterpret_cast<DmNapiStatusJsCallback *>(work->data);
408         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
409         if (deviceManagerNapi == nullptr) {
410             LOGE("OnDiscoveryFailed, deviceManagerNapi not find for bundleName %{public}s",
411                 callback->bundleName_.c_str());
412         } else {
413             deviceManagerNapi->OnDiscoveryFailed(callback->subscribeId_, callback->reason_);
414         }
415         DeleteDmNapiStatusJsCallbackPtr(callback);
416         DeleteUvWork(work);
417     }, uv_qos_user_initiated);
418     if (ret != 0) {
419         LOGE("Failed to execute OnDiscoveryFailed work queue");
420         DeleteDmNapiStatusJsCallbackPtr(jsCallback);
421         DeleteUvWork(work);
422     }
423 }
424 
OnDiscoverySuccess(uint16_t subscribeId)425 void DmNapiDiscoveryCallback::OnDiscoverySuccess(uint16_t subscribeId)
426 {
427     DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_);
428     if (deviceManagerNapi == nullptr) {
429         LOGE("OnDiscoverySuccess, deviceManagerNapi not find for bundleName %{public}s", bundleName_.c_str());
430         return;
431     }
432     LOGI("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
433 }
434 
IncreaseRefCount()435 void DmNapiDiscoveryCallback::IncreaseRefCount()
436 {
437     refCount_++;
438 }
439 
DecreaseRefCount()440 void DmNapiDiscoveryCallback::DecreaseRefCount()
441 {
442     refCount_--;
443 }
444 
GetRefCount()445 int32_t DmNapiDiscoveryCallback::GetRefCount()
446 {
447     return refCount_;
448 }
449 
OnPublishResult(int32_t publishId,int32_t publishResult)450 void DmNapiPublishCallback::OnPublishResult(int32_t publishId, int32_t publishResult)
451 {
452     LOGI("OnPublishResult for %{public}s, publishId %{public}d, publishResult %{public}d", bundleName_.c_str(),
453         publishId, publishResult);
454     uv_loop_s *loop = nullptr;
455     napi_get_uv_event_loop(env_, &loop);
456     if (loop == nullptr) {
457         return;
458     }
459     uv_work_t *work = new (std::nothrow) uv_work_t;
460     if (work == nullptr) {
461         LOGE("DmNapiPublishCallback: OnPublishResult, No memory");
462         return;
463     }
464 
465     DmNapiPublishJsCallback *jsCallback = new DmNapiPublishJsCallback(bundleName_, publishId, publishResult);
466     if (jsCallback == nullptr) {
467         DeleteUvWork(work);
468         return;
469     }
470     work->data = reinterpret_cast<void *>(jsCallback);
471 
472     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
473         LOGD("OnPublishResult uv_queue_work_with_qos");
474     }, [] (uv_work_t *work, int status) {
475         DmNapiPublishJsCallback *callback = reinterpret_cast<DmNapiPublishJsCallback *>(work->data);
476         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
477         if (deviceManagerNapi == nullptr) {
478             LOGE("OnPublishResult, deviceManagerNapi failed for bundleName %{public}s", callback->bundleName_.c_str());
479         } else {
480             deviceManagerNapi->OnPublishResult(callback->publishId_, callback->reason_);
481         }
482         delete callback;
483         callback = nullptr;
484         DeleteUvWork(work);
485     }, uv_qos_user_initiated);
486     if (ret != 0) {
487         LOGE("Failed to execute OnPublishResult work queue");
488         delete jsCallback;
489         jsCallback = nullptr;
490         DeleteUvWork(work);
491     }
492 }
493 
IncreaseRefCount()494 void DmNapiPublishCallback::IncreaseRefCount()
495 {
496     refCount_++;
497 }
498 
DecreaseRefCount()499 void DmNapiPublishCallback::DecreaseRefCount()
500 {
501     refCount_--;
502 }
503 
GetRefCount()504 int32_t DmNapiPublishCallback::GetRefCount()
505 {
506     return refCount_;
507 }
508 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)509 void DmNapiAuthenticateCallback::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
510                                               int32_t reason)
511 {
512     uv_loop_s *loop = nullptr;
513     napi_get_uv_event_loop(env_, &loop);
514     if (loop == nullptr) {
515         return;
516     }
517     uv_work_t *work = new (std::nothrow) uv_work_t;
518     if (work == nullptr) {
519         LOGE("js4.0 DmNapiAuthenticateCallback::OnAuthResult, No memory");
520         return;
521     }
522 
523     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, deviceId, token, status, reason);
524     if (jsCallback == nullptr) {
525         DeleteUvWork(work);
526         return;
527     }
528     work->data = reinterpret_cast<void *>(jsCallback);
529 
530     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
531         LOGD("OnAuthResult uv_queue_work_with_qos");
532     }, [] (uv_work_t *work, int status) {
533         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
534         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
535         if (deviceManagerNapi == nullptr) {
536             LOGE("OnAuthResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
537         } else {
538             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
539                 callback->status_, callback->reason_);
540         }
541         delete callback;
542         callback = nullptr;
543         DeleteUvWork(work);
544     }, uv_qos_user_initiated);
545     if (ret != 0) {
546         LOGE("Failed to execute OnAuthResult work queue");
547         delete jsCallback;
548         jsCallback = nullptr;
549         DeleteUvWork(work);
550     }
551 }
552 
OnResult(const std::vector<DmDeviceProfileInfo> & deviceProfileInfos,int32_t code)553 void DmNapiGetDeviceProfileInfoListCallback::OnResult(const std::vector<DmDeviceProfileInfo> &deviceProfileInfos,
554     int32_t code)
555 {
556     LOGI("In code:%{public}d, size:%{public}zu", code, deviceProfileInfos.size());
557     CHECK_NULL_VOID_RET_LOG(deferred_, "deferred_ is nullptr");
558     uv_loop_s *loop = nullptr;
559     napi_get_uv_event_loop(env_, &loop);
560     if (loop == nullptr) {
561         LOGE("get loop fail");
562         return;
563     }
564     uv_work_t *work = new (std::nothrow) uv_work_t;
565     if (work == nullptr) {
566         LOGE("OnResult, No memory");
567         return;
568     }
569     auto *jsCallback = new DeviceProfileInfosAsyncCallbackInfo();
570     if (jsCallback == nullptr) {
571         LOGE("create jsCallback fail");
572         DeleteUvWork(work);
573         return;
574     }
575     jsCallback->env = env_;
576     jsCallback->bundleName = bundleName_;
577     jsCallback->deferred = deferred_;
578     jsCallback->deviceProfileInfos = deviceProfileInfos;
579     jsCallback->code = code;
580     work->data = reinterpret_cast<void *>(jsCallback);
581     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
582             LOGD("OnResult uv_queue_work_with_qos");
583     },  [] (uv_work_t *work, int status) {
584         DeviceProfileInfosAsyncCallbackInfo *callback =
585             reinterpret_cast<DeviceProfileInfosAsyncCallbackInfo *>(work->data);
586         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName);
587         if (deviceManagerNapi == nullptr) {
588             LOGE("deviceManagerNapi not find for bundleName %{public}s", callback->bundleName.c_str());
589         } else {
590             deviceManagerNapi->OnGetDeviceProfileInfoListCallbackResult(callback);
591         }
592         delete callback;
593         callback = nullptr;
594         DeleteUvWork(work);
595     }, uv_qos_user_initiated);
596     if (ret != 0) {
597         LOGE("Failed to execute OnBindResult work queue");
598         delete jsCallback;
599         jsCallback = nullptr;
600         DeleteUvWork(work);
601     }
602 }
603 
DeviceManagerNapi(napi_env env,napi_value thisVar)604 DeviceManagerNapi::DeviceManagerNapi(napi_env env, napi_value thisVar) : DmNativeEvent(env, thisVar)
605 {
606     env_ = env;
607 }
608 
~DeviceManagerNapi()609 DeviceManagerNapi::~DeviceManagerNapi()
610 {
611 }
612 
GetDeviceManagerNapi(std::string & bundleName)613 DeviceManagerNapi *DeviceManagerNapi::GetDeviceManagerNapi(std::string &bundleName)
614 {
615     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
616     auto iter = g_deviceManagerMap.find(bundleName);
617     if (iter == g_deviceManagerMap.end()) {
618         return nullptr;
619     }
620     return iter->second;
621 }
622 
OnDeviceStatusChange(DmNapiDevStatusChange action,const OHOS::DistributedHardware::DmDeviceBasicInfo & deviceBasicInfo)623 void DeviceManagerNapi::OnDeviceStatusChange(DmNapiDevStatusChange action,
624     const OHOS::DistributedHardware::DmDeviceBasicInfo &deviceBasicInfo)
625 {
626     napi_handle_scope scope;
627     napi_status status = napi_open_handle_scope(env_, &scope);
628     if (status != napi_ok || scope == nullptr) {
629         LOGE("open handle scope failed");
630         return;
631     }
632     napi_value result = nullptr;
633     napi_create_object(env_, &result);
634     SetValueInt32(env_, "action", (int)action, result);
635 
636     napi_value device = nullptr;
637     napi_create_object(env_, &device);
638     DmDeviceBasicToJsObject(env_, deviceBasicInfo, device);
639 
640     napi_set_named_property(env_, result, "device", device);
641     OnEvent("deviceStateChange", DM_NAPI_ARGS_ONE, &result);
642     napi_close_handle_scope(env_, scope);
643 }
644 
OnDeviceFound(uint16_t subscribeId,const DmDeviceBasicInfo & deviceBasicInfo)645 void DeviceManagerNapi::OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)
646 {
647     LOGI("OnDeviceFound DmDeviceBasicInfo for subscribeId %{public}d", (int32_t)subscribeId);
648     napi_handle_scope scope;
649     napi_status status = napi_open_handle_scope(env_, &scope);
650     if (status != napi_ok || scope == nullptr) {
651         LOGE("open handle scope failed");
652         return;
653     }
654     napi_value result = nullptr;
655     napi_create_object(env_, &result);
656 
657     napi_value device = nullptr;
658     napi_create_object(env_, &device);
659     DmDeviceBasicToJsObject(env_, deviceBasicInfo, device);
660 
661     napi_set_named_property(env_, result, "device", device);
662     OnEvent("discoverSuccess", DM_NAPI_ARGS_ONE, &result);
663     napi_close_handle_scope(env_, scope);
664 }
665 
OnDiscoveryFailed(uint16_t subscribeId,int32_t failedReason)666 void DeviceManagerNapi::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
667 {
668     LOGI("OnDiscoveryFailed for subscribeId %{public}d", (int32_t)subscribeId);
669     napi_handle_scope scope;
670     napi_status status = napi_open_handle_scope(env_, &scope);
671     if (status != napi_ok || scope == nullptr) {
672         LOGE("open handle scope failed");
673         return;
674     }
675     napi_value result = nullptr;
676     napi_create_object(env_, &result);
677     SetValueInt32(env_, "reason", (int)failedReason, result);
678     std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)failedReason);
679     SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
680     OnEvent("discoverFail", DM_NAPI_ARGS_ONE, &result);
681     napi_close_handle_scope(env_, scope);
682 }
683 
OnPublishResult(int32_t publishId,int32_t publishResult)684 void DeviceManagerNapi::OnPublishResult(int32_t publishId, int32_t publishResult)
685 {
686     LOGI("OnPublishResult for publishId %{public}d, publishResult %{public}d", publishId, publishResult);
687     napi_handle_scope scope;
688     napi_status status = napi_open_handle_scope(env_, &scope);
689     if (status != napi_ok || scope == nullptr) {
690         LOGE("open handle scope failed");
691         return;
692     }
693     napi_value result = nullptr;
694     napi_create_object(env_, &result);
695     SetValueInt32(env_, "publishId", publishId, result);
696     if (publishResult == 0) {
697         OnEvent("publishSuccess", DM_NAPI_ARGS_ONE, &result);
698     } else {
699         SetValueInt32(env_, "reason", publishResult, result);
700         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString(publishResult);
701         SetValueUtf8String(env_, "errInfo", errCodeInfo, result);
702         OnEvent("publishFail", DM_NAPI_ARGS_ONE, &result);
703     }
704     NAPI_CALL_RETURN_VOID(env_, napi_close_handle_scope(env_, scope));
705 }
706 
OnAuthResult(const std::string & deviceId,const std::string & token,int32_t status,int32_t reason)707 void DeviceManagerNapi::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
708                                      int32_t reason)
709 {
710     LOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason);
711     napi_handle_scope scope;
712     napi_status openHandleStatus = napi_open_handle_scope(env_, &scope);
713     if (openHandleStatus != napi_ok || scope == nullptr) {
714         LOGE("open handle scope failed");
715         return;
716     }
717     napi_value thisVar = nullptr;
718     napi_get_reference_value(env_, thisVarRef_, &thisVar);
719     napi_value result[DM_NAPI_ARGS_TWO] = {0};
720 
721     if (status == DM_AUTH_REQUEST_SUCCESS_STATUS && reason == 0) {
722         LOGI("OnAuthResult success");
723         napi_get_undefined(env_, &result[0]);
724         napi_create_object(env_, &result[1]);
725         SetValueUtf8String(env_, "deviceId", deviceId, result[1]);
726     } else {
727         LOGI("OnAuthResult failed");
728         napi_create_object(env_, &result[0]);
729         SetValueInt32(env_, "code", status, result[0]);
730         SetValueInt32(env_, "reason", reason, result[0]);
731         std::string errCodeInfo = OHOS::DistributedHardware::GetErrorString((int)reason);
732         SetValueUtf8String(env_, "errInfo", errCodeInfo, result[0]);
733         napi_get_undefined(env_, &result[1]);
734     }
735 
736     if (reason == DM_OK && (status <= STATUS_DM_CLOSE_PIN_INPUT_UI && status >= STATUS_DM_SHOW_AUTHORIZE_UI)) {
737         LOGI("update ui change, status: %{public}d, reason: %{public}d", status, reason);
738     } else {
739         napi_value callResult = nullptr;
740         napi_value handler = nullptr;
741         napi_get_reference_value(env_, authAsyncCallbackInfo_.callback, &handler);
742         if (handler != nullptr) {
743             napi_call_function(env_, nullptr, handler, DM_NAPI_ARGS_TWO, &result[0], &callResult);
744             napi_delete_reference(env_, authAsyncCallbackInfo_.callback);
745             authAsyncCallbackInfo_.callback = nullptr;
746         } else {
747             LOGE("handler is nullptr");
748         }
749         {
750             std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
751             g_authCallbackMap.erase(bundleName_);
752         }
753     }
754     napi_close_handle_scope(env_, scope);
755 }
756 
OnGetDeviceProfileInfoListCallbackResult(DeviceProfileInfosAsyncCallbackInfo * jsCallback)757 void DeviceManagerNapi::OnGetDeviceProfileInfoListCallbackResult(DeviceProfileInfosAsyncCallbackInfo *jsCallback)
758 {
759     LOGI("In");
760     CHECK_NULL_VOID_RET_LOG(jsCallback, "jsCallback is nullptr");
761     napi_handle_scope scope;
762     napi_status status = napi_open_handle_scope(env_, &scope);
763     if (status != napi_ok || scope == nullptr) {
764         LOGE("open handle scope failed");
765         return;
766     }
767     if (jsCallback->code != DM_OK) {
768         napi_value error = CreateBusinessError(env_, jsCallback->code, false);
769         napi_reject_deferred(env_, jsCallback->deferred, error);
770         LOGE("jsCallback->code(%{public}d) != DM_OK", jsCallback->code);
771         napi_close_handle_scope(env_, scope);
772         return;
773     }
774     napi_value devInfosJsObj;
775     napi_create_array(env_, &devInfosJsObj);
776     bool isArray = false;
777     napi_is_array(env_, devInfosJsObj, &isArray);
778     if (!isArray) {
779         LOGE("napi_create_array failed");
780         napi_value error = CreateBusinessError(env_, ERR_DM_POINT_NULL, false);
781         napi_reject_deferred(env_, jsCallback->deferred, error);
782         napi_close_handle_scope(env_, scope);
783         return;
784     }
785     DmDeviceProfileInfoToJsArray(env_, jsCallback->deviceProfileInfos, devInfosJsObj);
786     napi_resolve_deferred(env_, jsCallback->deferred, devInfosJsObj);
787     napi_close_handle_scope(env_, scope);
788 }
789 
OnGetDeviceIconInfoCallbackResult(DeviceIconInfoAsyncCallbackInfo * jsCallback)790 void DeviceManagerNapi::OnGetDeviceIconInfoCallbackResult(DeviceIconInfoAsyncCallbackInfo *jsCallback)
791 {
792     LOGI("In");
793     CHECK_NULL_VOID_RET_LOG(jsCallback, "jsCallback is nullptr");
794     napi_handle_scope scope;
795     napi_status status = napi_open_handle_scope(env_, &scope);
796     if (status != napi_ok || scope == nullptr) {
797         LOGE("open handle scope failed");
798         return;
799     }
800     if (jsCallback->code != DM_OK) {
801         napi_value error = CreateBusinessError(env_, jsCallback->code, false);
802         napi_reject_deferred(env_, jsCallback->deferred, error);
803         LOGE("jsCallback->code(%{public}d) != DM_OK", jsCallback->code);
804         napi_close_handle_scope(env_, scope);
805         return;
806     }
807     napi_value deviceIconInfoJsObj;
808     napi_create_object(env_, &deviceIconInfoJsObj);
809     DmDeviceIconInfoToJs(env_, jsCallback->deviceIconInfo, deviceIconInfoJsObj);
810     napi_resolve_deferred(env_, jsCallback->deferred, deviceIconInfoJsObj);
811     napi_close_handle_scope(env_, scope);
812 }
813 
OnSetLocalDeviceNameCallbackResult(SetLocalDeviceNameAsyncCallbackInfo * jsCallback)814 void DeviceManagerNapi::OnSetLocalDeviceNameCallbackResult(SetLocalDeviceNameAsyncCallbackInfo *jsCallback)
815 {
816     LOGI("In");
817     CHECK_NULL_VOID_RET_LOG(jsCallback, "jsCallback is nullptr");
818     napi_handle_scope scope;
819     napi_status status = napi_open_handle_scope(env_, &scope);
820     if (status != napi_ok || scope == nullptr) {
821         LOGE("open handle scope failed");
822         return;
823     }
824     if (jsCallback->code != DM_OK) {
825         napi_value error = CreateBusinessError(env_, jsCallback->code, false);
826         napi_reject_deferred(env_, jsCallback->deferred, error);
827         LOGE("jsCallback->code(%{public}d) != DM_OK", jsCallback->code);
828         napi_close_handle_scope(env_, scope);
829         return;
830     }
831     napi_value value = nullptr;
832     napi_create_int32(env_, jsCallback->code, &value);
833     napi_resolve_deferred(env_, jsCallback->deferred, value);
834     napi_close_handle_scope(env_, scope);
835 }
836 
OnSetRemoteDeviceNameCallbackResult(SetRemoteDeviceNameAsyncCallbackInfo * jsCallback)837 void DeviceManagerNapi::OnSetRemoteDeviceNameCallbackResult(SetRemoteDeviceNameAsyncCallbackInfo *jsCallback)
838 {
839     LOGI("In");
840     CHECK_NULL_VOID_RET_LOG(jsCallback, "jsCallback is nullptr");
841     napi_handle_scope scope;
842     napi_status status = napi_open_handle_scope(env_, &scope);
843     if (status != napi_ok || scope == nullptr) {
844         LOGE("open handle scope failed");
845         return;
846     }
847     if (jsCallback->code != DM_OK) {
848         napi_value error = CreateBusinessError(env_, jsCallback->code, false);
849         napi_reject_deferred(env_, jsCallback->deferred, error);
850         LOGE("jsCallback->code(%{public}d) != DM_OK", jsCallback->code);
851         napi_close_handle_scope(env_, scope);
852         return;
853     }
854     napi_value value = nullptr;
855     napi_create_int32(env_, jsCallback->code, &value);
856     napi_resolve_deferred(env_, jsCallback->deferred, value);
857     napi_close_handle_scope(env_, scope);
858 }
859 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType)860 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName, std::string &eventType)
861 {
862     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s", bundleName.c_str(), eventType.c_str());
863     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE || eventType == DM_NAPI_EVENT_DEVICE_NAME_CHANGE) {
864         RegisterDevStatusCallback(env, bundleName);
865         return;
866     }
867     if (eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) {
868         auto callback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
869         {
870             std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
871             CHECK_SIZE_VOID(g_DiscoveryCallbackMap);
872             g_DiscoveryCallbackMap[bundleName] = callback;
873         }
874         std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = callback;
875         discoveryCallback->IncreaseRefCount();
876         return;
877     }
878 
879     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
880         auto callback = std::make_shared<DmNapiPublishCallback>(env, bundleName);
881         {
882             std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
883             CHECK_SIZE_VOID(g_publishCallbackMap);
884             g_publishCallbackMap[bundleName] = callback;
885         }
886         std::shared_ptr<DmNapiPublishCallback> publishCallback = callback;
887         publishCallback->IncreaseRefCount();
888         return;
889     }
890 
891     if (eventType == DM_NAPI_EVENT_REPLY_RESULT) {
892         auto callback = std::make_shared<DmNapiDeviceManagerUiCallback>(env, bundleName);
893         if (DeviceManager::GetInstance().RegisterDeviceManagerFaCallback(bundleName, callback) != 0) {
894             LOGE("RegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
895             return;
896         }
897         {
898             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
899             CHECK_SIZE_VOID(g_dmUiCallbackMap);
900             g_dmUiCallbackMap[bundleName] = callback;
901         }
902     }
903 }
904 
RegisterDevStatusCallback(napi_env env,std::string & bundleName)905 void DeviceManagerNapi::RegisterDevStatusCallback(napi_env env, std::string &bundleName)
906 {
907     LOGI("RegisterDevStatusCallback start for bundleName %{public}s", bundleName.c_str());
908     {
909         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
910         if (g_deviceStatusCallbackMap.find(bundleName) != g_deviceStatusCallbackMap.end()) {
911             LOGI("bundleName already register.");
912             return;
913         }
914     }
915     auto callback = std::make_shared<DmNapiDeviceStatusCallback>(env, bundleName);
916     std::string extra = "";
917     int32_t ret = DeviceManager::GetInstance().RegisterDevStatusCallback(bundleName, extra, callback);
918     if (ret != 0) {
919         LOGE("RegisterDevStatusCallback failed ret %{public}d", ret);
920         return;
921     }
922     {
923         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
924         CHECK_SIZE_VOID(g_deviceStatusCallbackMap);
925         g_deviceStatusCallbackMap[bundleName] = callback;
926     }
927     return;
928 }
929 
CreateDmCallback(napi_env env,std::string & bundleName,std::string & eventType,std::string & extra)930 void DeviceManagerNapi::CreateDmCallback(napi_env env, std::string &bundleName,
931                                          std::string &eventType, std::string &extra)
932 {
933     LOGI("CreateDmCallback for bundleName %{public}s eventType %{public}s extra = %{public}s",
934          bundleName.c_str(), eventType.c_str(), extra.c_str());
935     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
936         auto callback = std::make_shared<DmNapiDeviceStatusCallback>(env, bundleName);
937         int32_t ret = DeviceManager::GetInstance().RegisterDevStatusCallback(bundleName, extra, callback);
938         if (ret != 0) {
939             LOGE("RegisterDevStatusCallback failed for bundleName %{public}s", bundleName.c_str());
940             return;
941         }
942         {
943             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
944             CHECK_SIZE_VOID(g_deviceStatusCallbackMap);
945             g_deviceStatusCallbackMap[bundleName] = callback;
946         }
947     }
948 }
949 
ReleasePublishCallback(std::string & bundleName)950 void DeviceManagerNapi::ReleasePublishCallback(std::string &bundleName)
951 {
952     LOGI("ReleasePublishCallback for bundleName %{public}s", bundleName.c_str());
953     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
954     {
955         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
956         auto iter = g_publishCallbackMap.find(bundleName);
957         if (iter == g_publishCallbackMap.end()) {
958             return;
959         }
960         publishCallback = iter->second;
961     }
962     publishCallback->DecreaseRefCount();
963     if (publishCallback->GetRefCount() == 0) {
964         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
965         g_publishCallbackMap.erase(bundleName);
966     }
967     return;
968 }
969 
ReleaseDiscoveryCallback(std::string & bundleName)970 void DeviceManagerNapi::ReleaseDiscoveryCallback(std::string &bundleName)
971 {
972     LOGI("ReleaseDiscoveryCallback for bundleName %{public}s", bundleName.c_str());
973     std::shared_ptr<DmNapiDiscoveryCallback> DiscoveryCallback = nullptr;
974     {
975         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
976         auto iter = g_DiscoveryCallbackMap.find(bundleName);
977         if (iter == g_DiscoveryCallbackMap.end()) {
978             return;
979         }
980         DiscoveryCallback = iter->second;
981     }
982     DiscoveryCallback->DecreaseRefCount();
983     if (DiscoveryCallback->GetRefCount() == 0) {
984         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
985         g_DiscoveryCallbackMap.erase(bundleName);
986     }
987     return;
988 }
989 
ReleaseDmCallback(std::string & bundleName,std::string & eventType)990 void DeviceManagerNapi::ReleaseDmCallback(std::string &bundleName, std::string &eventType)
991 {
992     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
993         {
994             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
995             auto iter = g_deviceStatusCallbackMap.find(bundleName);
996             if (iter == g_deviceStatusCallbackMap.end()) {
997                 LOGE("ReleaseDmCallback: cannot find statusCallback for bundleName %{public}s", bundleName.c_str());
998                 return;
999             }
1000         }
1001         int32_t ret = DeviceManager::GetInstance().UnRegisterDevStatusCallback(bundleName);
1002         if (ret != 0) {
1003             LOGE("UnRegisterDevStatusCallback failed for bundleName %{public}s", bundleName.c_str());
1004             return;
1005         }
1006         {
1007             std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
1008             g_deviceStatusCallbackMap.erase(bundleName);
1009         }
1010         return;
1011     }
1012 
1013     if (eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) {
1014         ReleaseDiscoveryCallback(bundleName);
1015         return;
1016     }
1017 
1018     if (eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_SUCCESS || eventType == DM_NAPI_EVENT_DEVICE_PUBLISH_FAIL) {
1019         ReleasePublishCallback(bundleName);
1020         return;
1021     }
1022 
1023     if (eventType == DM_NAPI_EVENT_REPLY_RESULT) {
1024         {
1025             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1026             auto iter = g_dmUiCallbackMap.find(bundleName);
1027             if (iter == g_dmUiCallbackMap.end()) {
1028                 LOGE("cannot find dmFaCallback for bundleName %{public}s", bundleName.c_str());
1029                 return;
1030             }
1031         }
1032         int32_t ret = DeviceManager::GetInstance().UnRegisterDeviceManagerFaCallback(bundleName);
1033         if (ret != 0) {
1034             LOGE("UnRegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName.c_str());
1035             return;
1036         }
1037         {
1038             std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
1039             g_dmUiCallbackMap.erase(bundleName);
1040         }
1041         return;
1042     }
1043 }
1044 
SetUserOperationSync(napi_env env,napi_callback_info info)1045 napi_value DeviceManagerNapi::SetUserOperationSync(napi_env env, napi_callback_info info)
1046 {
1047     LOGI("SetUserOperationSync in");
1048     if (!IsSystemApp()) {
1049         LOGI("SetUserOperationSync not SystemApp");
1050         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1051         return nullptr;
1052     }
1053     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1054     napi_valuetype valueType;
1055     napi_typeof(env, argv[0], &valueType);
1056     if (!CheckArgsType(env, valueType == napi_number, "action", "number")) {
1057         return nullptr;
1058     }
1059     int32_t action = 0;
1060     napi_get_value_int32(env, argv[0], &action);
1061 
1062     std::string params;
1063     if (!JsToStringAndCheck(env, argv[1], "actionResult", params)) {
1064         return nullptr;
1065     }
1066     napi_value result = nullptr;
1067     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1068     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1069         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1070         return result;
1071     }
1072     int32_t ret = DeviceManager::GetInstance().SetUserOperation(deviceManagerWrapper->bundleName_, action, params);
1073     if (ret != 0) {
1074         LOGE("SetUserOperation for bundleName %{public}s failed, ret %{public}d",
1075             deviceManagerWrapper->bundleName_.c_str(), ret);
1076         CreateBusinessError(env, ret);
1077     }
1078     napi_get_undefined(env, &result);
1079     return result;
1080 }
1081 
OnCall(const std::string & paramJson)1082 void DmNapiDeviceManagerUiCallback::OnCall(const std::string &paramJson)
1083 {
1084     uv_loop_s *loop = nullptr;
1085     napi_get_uv_event_loop(env_, &loop);
1086     if (loop == nullptr) {
1087         return;
1088     }
1089     uv_work_t *work = new (std::nothrow) uv_work_t;
1090     if (work == nullptr) {
1091         LOGE("DmNapiDeviceManagerUiCallback: OnCall, No memory");
1092         return;
1093     }
1094 
1095     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, "", paramJson, 0, 0);
1096     if (jsCallback == nullptr) {
1097         DeleteUvWork(work);
1098         return;
1099     }
1100     work->data = reinterpret_cast<void *>(jsCallback);
1101 
1102     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
1103         LOGD("OnCall uv_queue_work_with_qos");
1104     }, [] (uv_work_t *work, int status) {
1105         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
1106         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
1107         if (deviceManagerNapi == nullptr) {
1108             LOGE("OnCall, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
1109         } else {
1110             deviceManagerNapi->OnDmUiCall(callback->token_);
1111         }
1112         delete callback;
1113         callback = nullptr;
1114         DeleteUvWork(work);
1115     }, uv_qos_user_initiated);
1116     if (ret != 0) {
1117         LOGE("Failed to execute OnCall work queue");
1118         delete jsCallback;
1119         jsCallback = nullptr;
1120         DeleteUvWork(work);
1121     }
1122 }
1123 
OnDmUiCall(const std::string & paramJson)1124 void DeviceManagerNapi::OnDmUiCall(const std::string &paramJson)
1125 {
1126     LOGI("OnCall for paramJson");
1127     napi_handle_scope scope;
1128     napi_status status = napi_open_handle_scope(env_, &scope);
1129     if (status != napi_ok || scope == nullptr) {
1130         LOGE("open handle scope failed");
1131         return;
1132     }
1133     napi_value result;
1134     napi_create_object(env_, &result);
1135     SetValueUtf8String(env_, "param", paramJson, result);
1136     OnEvent(DM_NAPI_EVENT_REPLY_RESULT, DM_NAPI_ARGS_ONE, &result);
1137     napi_close_handle_scope(env_, scope);
1138 }
1139 
OnBindResult(const PeerTargetId & targetId,int32_t result,int32_t status,std::string content)1140 void DmNapiBindTargetCallback::OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status,
1141     std::string content)
1142 {
1143     (void)targetId;
1144     uv_loop_s *loop = nullptr;
1145     napi_get_uv_event_loop(env_, &loop);
1146     if (loop == nullptr) {
1147         return;
1148     }
1149     uv_work_t *work = new (std::nothrow) uv_work_t;
1150     if (work == nullptr) {
1151         LOGE("js4.0 DmNapiBindTargetCallback::OnBindResult, No memory");
1152         return;
1153     }
1154 
1155     DmNapiAuthJsCallback *jsCallback = new DmNapiAuthJsCallback(bundleName_, content, "", status, result);
1156     if (jsCallback == nullptr) {
1157         DeleteUvWork(work);
1158         return;
1159     }
1160     work->data = reinterpret_cast<void *>(jsCallback);
1161 
1162     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
1163         LOGD("OnBindResult uv_queue_work_with_qos");
1164     }, [] (uv_work_t *work, int status) {
1165         DmNapiAuthJsCallback *callback = reinterpret_cast<DmNapiAuthJsCallback *>(work->data);
1166         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName_);
1167         if (deviceManagerNapi == nullptr) {
1168             LOGE("OnBindResult, deviceManagerNapi not find for bundleName %{public}s", callback->bundleName_.c_str());
1169         } else {
1170             deviceManagerNapi->OnAuthResult(callback->deviceId_, callback->token_,
1171                 callback->status_, callback->reason_);
1172         }
1173         delete callback;
1174         callback = nullptr;
1175         DeleteUvWork(work);
1176     }, uv_qos_user_initiated);
1177     if (ret != 0) {
1178         LOGE("Failed to execute OnBindResult work queue");
1179         delete jsCallback;
1180         jsCallback = nullptr;
1181         DeleteUvWork(work);
1182     }
1183 }
1184 
DumpDeviceInfo(DeviceBasicInfoListAsyncCallbackInfo * deviceBasicInfoListAsyncCallbackInfo)1185 int32_t DeviceManagerNapi::DumpDeviceInfo(
1186     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1187 {
1188     CHECK_NULL_RETURN(deviceBasicInfoListAsyncCallbackInfo, ERR_DM_POINT_NULL);
1189     if (deviceBasicInfoListAsyncCallbackInfo->devList.size() > DM_MAX_DEVICE_SIZE) {
1190         LOGE("CallGetAvailableDeviceListStatus invalid devList size");
1191         return DM_ERR_FAILED;
1192     }
1193     for (unsigned int i = 0; i < deviceBasicInfoListAsyncCallbackInfo->devList.size(); i++) {
1194         LOGI("DeviceId:%{public}s deviceName:%{public}s deviceTypeId:%{public}d ",
1195              GetAnonyString(deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceId).c_str(),
1196              GetAnonyString(deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceName).c_str(),
1197              deviceBasicInfoListAsyncCallbackInfo->devList[i].deviceTypeId);
1198     }
1199     return DM_OK;
1200 }
1201 
CallGetAvailableDeviceListStatus(napi_env env,napi_status & status,DeviceBasicInfoListAsyncCallbackInfo * deviceBasicInfoListAsyncCallbackInfo)1202 void DeviceManagerNapi::CallGetAvailableDeviceListStatus(napi_env env, napi_status &status,
1203     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1204 {
1205     if (DumpDeviceInfo(deviceBasicInfoListAsyncCallbackInfo) != DM_OK) {
1206         return;
1207     }
1208     napi_value array[DM_NAPI_ARGS_TWO] = {0};
1209     bool isArray = false;
1210     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &array[1]));
1211     NAPI_CALL_RETURN_VOID(env, napi_is_array(env, array[1], &isArray));
1212     if (!isArray) {
1213         LOGE("napi_create_array fail");
1214     }
1215     if (deviceBasicInfoListAsyncCallbackInfo->status == 0) {
1216         if (deviceBasicInfoListAsyncCallbackInfo->devList.size() > 0) {
1217             for (size_t i = 0; i != deviceBasicInfoListAsyncCallbackInfo->devList.size(); ++i) {
1218                 DeviceBasicInfoToJsArray(env, deviceBasicInfoListAsyncCallbackInfo->devList, i, array[1]);
1219             }
1220             LOGI("devList is OK");
1221         } else {
1222             LOGE("devList is null"); // CB come here
1223         }
1224     } else {
1225         array[0] = CreateBusinessError(env, deviceBasicInfoListAsyncCallbackInfo->ret, false);
1226     }
1227     if (deviceBasicInfoListAsyncCallbackInfo->deferred) {
1228         if (deviceBasicInfoListAsyncCallbackInfo->status == 0) {
1229             napi_resolve_deferred(env, deviceBasicInfoListAsyncCallbackInfo->deferred, array[1]);
1230         } else {
1231             napi_reject_deferred(env, deviceBasicInfoListAsyncCallbackInfo->deferred, array[0]);
1232         }
1233     } else {
1234         napi_value callResult = nullptr;
1235         napi_value handler = nullptr;
1236         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, deviceBasicInfoListAsyncCallbackInfo->callback,
1237             &handler));
1238         if (handler != nullptr) {
1239             NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, handler, DM_NAPI_ARGS_TWO, &array[0],
1240                 &callResult));
1241             NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, deviceBasicInfoListAsyncCallbackInfo->callback));
1242             deviceBasicInfoListAsyncCallbackInfo->callback = nullptr;
1243         } else {
1244             LOGE("handler is nullptr");
1245         }
1246     }
1247 }
1248 
CallAsyncWork(napi_env env,DeviceBasicInfoListAsyncCallbackInfo * deviceBasicInfoListAsyncCallbackInfo)1249 void DeviceManagerNapi::CallAsyncWork(napi_env env,
1250     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1251 {
1252     napi_value resourceName;
1253     napi_create_string_latin1(env, "GetAvailableListInfo", NAPI_AUTO_LENGTH, &resourceName);
1254     napi_create_async_work(
1255         env, nullptr, resourceName,
1256         [](napi_env env, void *data) {
1257             DeviceBasicInfoListAsyncCallbackInfo *devBasicInfoListAsyncCallbackInfo =
1258                 reinterpret_cast<DeviceBasicInfoListAsyncCallbackInfo *>(data);
1259             int32_t ret = 0;
1260             ret = DeviceManager::GetInstance().GetAvailableDeviceList(devBasicInfoListAsyncCallbackInfo->bundleName,
1261                 devBasicInfoListAsyncCallbackInfo->devList);
1262             if (ret != 0) {
1263                 LOGE("CallAsyncWork for bundleName %{public}s failed, ret %{public}d",
1264                     devBasicInfoListAsyncCallbackInfo->bundleName.c_str(), ret);
1265                 devBasicInfoListAsyncCallbackInfo->status = -1;
1266                 devBasicInfoListAsyncCallbackInfo->ret = ret;
1267             } else {
1268                 devBasicInfoListAsyncCallbackInfo->status = 0;
1269             }
1270             LOGI("CallAsyncWork status %{public}d , ret %{public}d", devBasicInfoListAsyncCallbackInfo->status,
1271                 devBasicInfoListAsyncCallbackInfo->ret);
1272         },
1273         [](napi_env env, napi_status status, void *data) {
1274             (void)status;
1275             DeviceBasicInfoListAsyncCallbackInfo *dBasicInfoListAsyncCallbackInfo =
1276                 reinterpret_cast<DeviceBasicInfoListAsyncCallbackInfo *>(data);
1277             CallGetAvailableDeviceListStatus(env, status, dBasicInfoListAsyncCallbackInfo);
1278             napi_delete_async_work(env, dBasicInfoListAsyncCallbackInfo->asyncWork);
1279             delete dBasicInfoListAsyncCallbackInfo;
1280             dBasicInfoListAsyncCallbackInfo = nullptr;
1281         },
1282         (void *)deviceBasicInfoListAsyncCallbackInfo, &deviceBasicInfoListAsyncCallbackInfo->asyncWork);
1283     napi_queue_async_work_with_qos(env, deviceBasicInfoListAsyncCallbackInfo->asyncWork, napi_qos_user_initiated);
1284 }
1285 
CallDeviceList(napi_env env,napi_callback_info info,DeviceBasicInfoListAsyncCallbackInfo * deviceBasicInfoListAsyncCallbackInfo)1286 napi_value DeviceManagerNapi::CallDeviceList(napi_env env, napi_callback_info info,
1287     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1288 {
1289     napi_value result = nullptr;
1290     std::string extra = "";
1291     deviceBasicInfoListAsyncCallbackInfo->extra = extra;
1292     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1293     napi_valuetype eventHandleType = napi_undefined;
1294     napi_typeof(env, argv[0], &eventHandleType);
1295     if (eventHandleType == napi_function) {
1296         LOGI("CallDeviceList for argc %{public}zu Type = %{public}d", argc, (int)eventHandleType);
1297         napi_create_reference(env, argv[0], 1, &deviceBasicInfoListAsyncCallbackInfo->callback);
1298         CallAsyncWork(env, deviceBasicInfoListAsyncCallbackInfo);
1299     }
1300     napi_get_undefined(env, &result);
1301     return result;
1302 }
1303 
GetAvailableDeviceListSync(napi_env env,napi_callback_info info)1304 napi_value DeviceManagerNapi::GetAvailableDeviceListSync(napi_env env, napi_callback_info info)
1305 {
1306     LOGI("In");
1307     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1308     if (ret != 0) {
1309         CreateBusinessError(env, ret);
1310         return nullptr;
1311     }
1312     napi_value result = nullptr;
1313     napi_value thisVar = nullptr;
1314     size_t argc = 0;
1315     bool isArray = false;
1316     napi_create_array(env, &result);
1317     napi_is_array(env, result, &isArray);
1318     if (!isArray) {
1319         LOGE("napi_create_array fail");
1320     }
1321     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1322     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1323     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1324         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1325         return result;
1326     }
1327     std::vector<DmDeviceBasicInfo> devList;
1328     ret = DeviceManager::GetInstance().GetAvailableDeviceList(deviceManagerWrapper->bundleName_, devList);
1329     if (ret != 0) {
1330         LOGE("GetTrustedDeviceList for bundleName %{public}s failed, ret %{public}d",
1331             deviceManagerWrapper->bundleName_.c_str(), ret);
1332         CreateBusinessError(env, ret);
1333         return result;
1334     }
1335     LOGD("DeviceManager::GetAvailableDeviceListSync");
1336     if (devList.size() > 0) {
1337         for (size_t i = 0; i != devList.size(); ++i) {
1338             DeviceBasicInfoToJsArray(env, devList, (int32_t)i, result);
1339         }
1340     }
1341     return result;
1342 }
1343 
GetAvailableDeviceListPromise(napi_env env,DeviceBasicInfoListAsyncCallbackInfo * deviceBasicInfoListAsyncCallbackInfo)1344 napi_value DeviceManagerNapi::GetAvailableDeviceListPromise(napi_env env,
1345     DeviceBasicInfoListAsyncCallbackInfo *deviceBasicInfoListAsyncCallbackInfo)
1346 {
1347     std::string extra = "";
1348     deviceBasicInfoListAsyncCallbackInfo->extra = extra;
1349     napi_deferred deferred;
1350     napi_value promise = 0;
1351     napi_create_promise(env, &deferred, &promise);
1352     deviceBasicInfoListAsyncCallbackInfo->deferred = deferred;
1353     CallAsyncWork(env, deviceBasicInfoListAsyncCallbackInfo);
1354     return promise;
1355 }
1356 
GetAvailableDeviceList(napi_env env,napi_callback_info info)1357 napi_value DeviceManagerNapi::GetAvailableDeviceList(napi_env env, napi_callback_info info)
1358 {
1359     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1360     if (ret != 0) {
1361         CreateBusinessError(env, ret);
1362         return nullptr;
1363     }
1364     napi_value result = nullptr;
1365     napi_value thisVar = nullptr;
1366     size_t argc = 0;
1367     std::vector<DmDeviceBasicInfo> devList;
1368     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1369 
1370     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1371     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1372         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1373         return result;
1374     }
1375 
1376     auto *deviceBasicInfoListAsyncCallbackInfo = new DeviceBasicInfoListAsyncCallbackInfo();
1377     if (deviceBasicInfoListAsyncCallbackInfo == nullptr) {
1378         return nullptr;
1379     }
1380     deviceBasicInfoListAsyncCallbackInfo->env = env;
1381     deviceBasicInfoListAsyncCallbackInfo->devList = devList;
1382     deviceBasicInfoListAsyncCallbackInfo->bundleName = deviceManagerWrapper->bundleName_;
1383     if (argc == DM_NAPI_ARGS_ZERO) {
1384         return GetAvailableDeviceListPromise(env, deviceBasicInfoListAsyncCallbackInfo);
1385     } else if (argc == DM_NAPI_ARGS_ONE) {
1386         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1387         if (!IsFunctionType(env, argv[0])) {
1388             DeleteAsyncCallbackInfo(deviceBasicInfoListAsyncCallbackInfo);
1389             return nullptr;
1390         }
1391         return CallDeviceList(env, info, deviceBasicInfoListAsyncCallbackInfo);
1392     } else {
1393         DeleteAsyncCallbackInfo(deviceBasicInfoListAsyncCallbackInfo);
1394     }
1395     napi_get_undefined(env, &result);
1396     return result;
1397 }
1398 
GetLocalDeviceNetworkId(napi_env env,napi_callback_info info)1399 napi_value DeviceManagerNapi::GetLocalDeviceNetworkId(napi_env env, napi_callback_info info)
1400 {
1401     LOGI("GetLocalDeviceNetworkId in");
1402     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1403         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1404         return nullptr;
1405     }
1406     napi_value result = nullptr;
1407     napi_value thisVar = nullptr;
1408     std::string networkId;
1409     size_t argc = 0;
1410 
1411     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1412     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1413     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1414         napi_create_int32(env, ERR_DM_POINT_NULL, &result);
1415         return result;
1416     }
1417 
1418     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceNetWorkId(deviceManagerWrapper->bundleName_, networkId);
1419     if (ret != 0) {
1420         LOGE("GetLocalDeviceNetworkId for failed, ret %{public}d", ret);
1421         CreateBusinessError(env, ret);
1422         return result;
1423     }
1424     LOGI("DeviceManager::GetLocalDeviceNetworkId networkId:%{public}s", GetAnonyString(std::string(networkId)).c_str());
1425     napi_create_string_utf8(env, networkId.c_str(), networkId.size(), &result);
1426     return result;
1427 }
1428 
GetLocalDeviceId(napi_env env,napi_callback_info info)1429 napi_value DeviceManagerNapi::GetLocalDeviceId(napi_env env, napi_callback_info info)
1430 {
1431     LOGI("GetLocalDeviceId in");
1432     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1433         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1434         return nullptr;
1435     }
1436     napi_value result = nullptr;
1437     napi_value thisVar = nullptr;
1438     std::string deviceId;
1439     size_t argc = 0;
1440 
1441     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1442     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1443     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1444         napi_create_int32(env, ERR_DM_POINT_NULL, &result);
1445         return result;
1446     }
1447 
1448     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceId(deviceManagerWrapper->bundleName_, deviceId);
1449     if (ret != 0) {
1450         LOGE("GetLocalDeviceId for failed, ret %{public}d", ret);
1451         CreateBusinessError(env, ret);
1452         return result;
1453     }
1454     LOGI("DeviceManager::GetLocalDeviceId deviceId:%{public}s", GetAnonyString(std::string(deviceId)).c_str());
1455     napi_create_string_utf8(env, deviceId.c_str(), deviceId.size(), &result);
1456     return result;
1457 }
1458 
GetLocalDeviceName(napi_env env,napi_callback_info info)1459 napi_value DeviceManagerNapi::GetLocalDeviceName(napi_env env, napi_callback_info info)
1460 {
1461     LOGI("GetLocalDeviceName in");
1462     napi_value result = nullptr;
1463     napi_value thisVar = nullptr;
1464     std::string deviceName;
1465     size_t argc = 0;
1466 
1467     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1468     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1469     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1470         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1471         return result;
1472     }
1473 
1474     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceName(deviceManagerWrapper->bundleName_, deviceName);
1475     if (ret != 0) {
1476         LOGE("GetLocalDeviceName for failed, ret %{public}d", ret);
1477         CreateBusinessError(env, ret);
1478         return result;
1479     }
1480     LOGI("DeviceManager::GetLocalDeviceName deviceName:%{public}s", GetAnonyString(std::string(deviceName)).c_str());
1481     napi_create_string_utf8(env, deviceName.c_str(), deviceName.size(), &result);
1482     return result;
1483 }
1484 
GetLocalDeviceType(napi_env env,napi_callback_info info)1485 napi_value DeviceManagerNapi::GetLocalDeviceType(napi_env env, napi_callback_info info)
1486 {
1487     LOGI("GetLocalDeviceType in");
1488     if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
1489         CreateBusinessError(env, ERR_DM_NO_PERMISSION);
1490         return nullptr;
1491     }
1492     napi_value result = nullptr;
1493     napi_value thisVar = nullptr;
1494     int32_t deviceType = 0;
1495     size_t argc = 0;
1496 
1497     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1498     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1499     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1500         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1501         return result;
1502     }
1503 
1504     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceType(deviceManagerWrapper->bundleName_, deviceType);
1505     if (ret != 0) {
1506         LOGE("GetLocalDeviceType for failed, ret %{public}d", ret);
1507         CreateBusinessError(env, ret);
1508         return result;
1509     }
1510     LOGI("DeviceManager::GetLocalDeviceType deviceType:%{public}d", deviceType);
1511     napi_create_int32(env, deviceType, &result);
1512     return result;
1513 }
1514 
GetDeviceName(napi_env env,napi_callback_info info)1515 napi_value DeviceManagerNapi::GetDeviceName(napi_env env, napi_callback_info info)
1516 {
1517     LOGI("GetDeviceName in");
1518     napi_value result = nullptr;
1519     std::string deviceName;
1520     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1521     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1522         return nullptr;
1523     }
1524     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1525     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1526         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1527         return result;
1528     }
1529     std::string networkId;
1530     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
1531         return nullptr;
1532     }
1533 
1534     int32_t ret = DeviceManager::GetInstance().GetDeviceName(deviceManagerWrapper->bundleName_, networkId, deviceName);
1535     if (ret != 0) {
1536         LOGE("GetDeviceName for failed, ret %{public}d", ret);
1537         CreateBusinessError(env, ret);
1538         return result;
1539     }
1540     LOGI("DeviceManager::GetDeviceName deviceName:%{public}s", GetAnonyString(std::string(deviceName)).c_str());
1541     napi_create_string_utf8(env, deviceName.c_str(), deviceName.size(), &result);
1542     return result;
1543 }
1544 
GetDeviceType(napi_env env,napi_callback_info info)1545 napi_value DeviceManagerNapi::GetDeviceType(napi_env env, napi_callback_info info)
1546 {
1547     LOGI("GetDeviceType in");
1548     napi_value result = nullptr;
1549     int32_t deviceType;
1550     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1551     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1552         return nullptr;
1553     }
1554     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1555     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1556         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1557         return result;
1558     }
1559     std::string networkId;
1560     if (!JsToStringAndCheck(env, argv[0], "networkId", networkId)) {
1561         return nullptr;
1562     }
1563 
1564     int32_t ret = DeviceManager::GetInstance().GetDeviceType(deviceManagerWrapper->bundleName_, networkId, deviceType);
1565     if (ret != 0) {
1566         LOGE("GetDeviceType for failed, ret %{public}d", ret);
1567         CreateBusinessError(env, ret);
1568         return result;
1569     }
1570     LOGI("DeviceManager::GetDeviceType deviceType:%{public}d", deviceType);
1571     napi_create_int32(env, deviceType, &result);
1572     return result;
1573 }
1574 
LockDiscoveryCallbackMutex(napi_env env,std::string & bundleName,std::map<std::string,std::string> discParam,std::string & extra,uint32_t subscribeId)1575 void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName,
1576     std::map<std::string, std::string> discParam, std::string &extra, uint32_t subscribeId)
1577 {
1578     std::shared_ptr<DmNapiDiscoveryCallback> discoveryCallback = nullptr;
1579     {
1580         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
1581         auto iter = g_DiscoveryCallbackMap.find(bundleName);
1582         if (iter == g_DiscoveryCallbackMap.end()) {
1583             CHECK_SIZE_VOID(g_DiscoveryCallbackMap);
1584             discoveryCallback = std::make_shared<DmNapiDiscoveryCallback>(env, bundleName);
1585             g_DiscoveryCallbackMap[bundleName] = discoveryCallback;
1586         } else {
1587             discoveryCallback = iter->second;
1588         }
1589     }
1590     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1591     discParam.insert(std::pair<std::string, std::string>(PARAM_KEY_SUBSCRIBE_ID, std::to_string(tokenId)));
1592     std::map<std::string, std::string> filterOps;
1593     filterOps.insert(std::pair<std::string, std::string>(PARAM_KEY_FILTER_OPTIONS, extra));
1594     int32_t ret = DeviceManager::GetInstance().StartDiscovering(bundleName, discParam, filterOps, discoveryCallback);
1595     if (ret != 0) {
1596         LOGE("Discovery failed, bundleName %{public}s, ret %{public}d", bundleName.c_str(), ret);
1597         CreateBusinessError(env, ret);
1598         discoveryCallback->OnDiscoveryFailed(static_cast<uint16_t>(subscribeId), ret);
1599     }
1600     return;
1601 }
1602 
StartDeviceDiscover(napi_env env,napi_callback_info info)1603 napi_value DeviceManagerNapi::StartDeviceDiscover(napi_env env, napi_callback_info info)
1604 {
1605     LOGI("StartDeviceDiscover in");
1606     std::string extra = "";
1607     std::map<std::string, std::string> discParam;
1608     napi_value result = nullptr;
1609     napi_value thisVar = nullptr;
1610     size_t argcNum = 0;
1611     int32_t discoverTargetType = -1;
1612     uint32_t subscribeId = 0;
1613     NAPI_CALL(env, napi_get_cb_info(env, info, &argcNum, nullptr, &thisVar, nullptr));
1614     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1615     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1616         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1617         return result;
1618     }
1619     if (argcNum == DM_NAPI_ARGS_ONE) {
1620         GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1621         if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
1622             return nullptr;
1623         }
1624         JsToDiscoveryParam(env, argv[DM_NAPI_ARGS_ZERO], discParam);
1625     } else if (argcNum == DM_NAPI_ARGS_TWO) {
1626         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1627         if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
1628             return nullptr;
1629         }
1630         JsToDiscoveryParam(env, argv[DM_NAPI_ARGS_ZERO], discParam);
1631         napi_valuetype objectType = napi_undefined;
1632         napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &objectType);
1633         if (!(CheckArgsType(env, objectType == napi_object, "filterOptions", "object or undefined"))) {
1634             return nullptr;
1635         }
1636         JsToDmDiscoveryExtra(env, argv[DM_NAPI_ARGS_ONE], extra);
1637     }
1638     LockDiscoveryCallbackMutex(env, deviceManagerWrapper->bundleName_, discParam, extra, subscribeId);
1639     napi_get_undefined(env, &result);
1640     return result;
1641 }
1642 
StopDeviceDiscover(napi_env env,napi_callback_info info)1643 napi_value DeviceManagerNapi::StopDeviceDiscover(napi_env env, napi_callback_info info)
1644 {
1645     LOGI("StopDeviceDiscover in");
1646     napi_value result = nullptr;
1647     napi_value thisVar = nullptr;
1648     size_t argc = 0;
1649     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1650     if (argc != 0) {
1651         return nullptr;
1652     }
1653     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1654     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1655         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1656         return result;
1657     }
1658     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1659     int32_t ret = DeviceManager::GetInstance().StopDeviceDiscovery(tokenId, deviceManagerWrapper->bundleName_);
1660     if (ret != 0) {
1661         LOGE("StopDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
1662             deviceManagerWrapper->bundleName_.c_str(), ret);
1663         CreateBusinessError(env, ret);
1664         return result;
1665     }
1666     napi_get_undefined(env, &result);
1667     return result;
1668 }
1669 
PublishDeviceDiscoverySync(napi_env env,napi_callback_info info)1670 napi_value DeviceManagerNapi::PublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
1671 {
1672     LOGI("PublishDeviceDiscoverySync in");
1673     if (!IsSystemApp()) {
1674         LOGI("PublishDeviceDiscoverySync not SystemApp");
1675         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1676         return nullptr;
1677     }
1678     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1679     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1680         return nullptr;
1681     }
1682 
1683     napi_value result = nullptr;
1684     napi_valuetype valueType = napi_undefined;
1685     napi_typeof(env, argv[0], &valueType);
1686     if (!CheckArgsType(env, valueType == napi_object, "publishInfo", "object")) {
1687         return nullptr;
1688     }
1689     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1690     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1691         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1692         return result;
1693     }
1694 
1695     std::shared_ptr<DmNapiPublishCallback> publishCallback = nullptr;
1696     {
1697         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
1698         auto iter = g_publishCallbackMap.find(deviceManagerWrapper->bundleName_);
1699         if (iter == g_publishCallbackMap.end()) {
1700             CHECK_SIZE_RETURN(g_publishCallbackMap, nullptr);
1701             publishCallback = std::make_shared<DmNapiPublishCallback>(env, deviceManagerWrapper->bundleName_);
1702             g_publishCallbackMap[deviceManagerWrapper->bundleName_] = publishCallback;
1703         } else {
1704             publishCallback = iter->second;
1705         }
1706     }
1707     DmPublishInfo publishInfo;
1708     JsToDmPublishInfo(env, argv[0], publishInfo);
1709     int32_t ret = DeviceManager::GetInstance().PublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishInfo,
1710         publishCallback);
1711     if (ret != 0) {
1712         LOGE("PublishDeviceDiscovery for bundleName %{public}s failed, ret %{public}d",
1713             deviceManagerWrapper->bundleName_.c_str(), ret);
1714         CreateBusinessError(env, ret);
1715         publishCallback->OnPublishResult(publishInfo.publishId, ret);
1716         return result;
1717     }
1718 
1719     napi_get_undefined(env, &result);
1720     return result;
1721 }
1722 
UnPublishDeviceDiscoverySync(napi_env env,napi_callback_info info)1723 napi_value DeviceManagerNapi::UnPublishDeviceDiscoverySync(napi_env env, napi_callback_info info)
1724 {
1725     LOGI("UnPublishDeviceDiscoverySync in");
1726     if (!IsSystemApp()) {
1727         LOGI("UnPublishDeviceDiscoverySync not SystemApp");
1728         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
1729         return nullptr;
1730     }
1731     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1732     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1733         return nullptr;
1734     }
1735     napi_value result = nullptr;
1736     napi_valuetype valueType = napi_undefined;
1737     napi_typeof(env, argv[0], &valueType);
1738     if (!CheckArgsType(env, valueType == napi_number, "publishId", "number")) {
1739         return nullptr;
1740     }
1741     int32_t publishId = 0;
1742     napi_get_value_int32(env, argv[0], &publishId);
1743 
1744     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1745     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1746         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1747         return result;
1748     }
1749 
1750     int32_t ret = DeviceManager::GetInstance().UnPublishDeviceDiscovery(deviceManagerWrapper->bundleName_, publishId);
1751     if (ret != 0) {
1752         LOGE("UnPublishDeviceDiscovery bundleName %{public}s failed, ret %{public}d",
1753             deviceManagerWrapper->bundleName_.c_str(), ret);
1754         CreateBusinessError(env, ret);
1755         return result;
1756     }
1757 
1758     napi_get_undefined(env, &result);
1759     return result;
1760 }
1761 
BindDevOrTarget(DeviceManagerNapi * deviceManagerWrapper,const std::string & deviceId,napi_env env,napi_value & object)1762 void DeviceManagerNapi::BindDevOrTarget(DeviceManagerNapi *deviceManagerWrapper, const std::string &deviceId,
1763     napi_env env, napi_value &object)
1764 {
1765     LOGI("Bind devices or target start bundleName %{public}s", deviceManagerWrapper->bundleName_.c_str());
1766     std::string bindParam;
1767     bool isMetaType = false;
1768     JsToBindParam(env, object, bindParam, authAsyncCallbackInfo_.authType, isMetaType);
1769 
1770     if (isMetaType) {
1771         std::shared_ptr<DmNapiBindTargetCallback> bindTargetCallback = nullptr;
1772         {
1773             std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
1774             auto iter = g_bindCallbackMap.find(deviceManagerWrapper->bundleName_);
1775             if (iter == g_bindCallbackMap.end()) {
1776                 CHECK_SIZE_VOID(g_bindCallbackMap);
1777                 bindTargetCallback = std::make_shared<DmNapiBindTargetCallback>(env, deviceManagerWrapper->bundleName_);
1778                 g_bindCallbackMap[deviceManagerWrapper->bundleName_] = bindTargetCallback;
1779             } else {
1780                 bindTargetCallback = iter->second;
1781             }
1782         }
1783         int32_t ret = BindTargetWarpper(deviceManagerWrapper->bundleName_, deviceId, bindParam, bindTargetCallback);
1784         if (ret != 0) {
1785             LOGE("BindTarget failed, ret %{public}d", ret);
1786             CreateBusinessError(env, ret);
1787         }
1788         return;
1789     }
1790 
1791     std::shared_ptr<DmNapiAuthenticateCallback> bindDeviceCallback = nullptr;
1792     {
1793         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
1794         auto iter = g_authCallbackMap.find(deviceManagerWrapper->bundleName_);
1795         if (iter == g_authCallbackMap.end()) {
1796             CHECK_SIZE_VOID(g_authCallbackMap);
1797             bindDeviceCallback = std::make_shared<DmNapiAuthenticateCallback>(env, deviceManagerWrapper->bundleName_);
1798             g_authCallbackMap[deviceManagerWrapper->bundleName_] = bindDeviceCallback;
1799         } else {
1800             bindDeviceCallback = iter->second;
1801         }
1802     }
1803     int32_t ret = DeviceManager::GetInstance().BindDevice(deviceManagerWrapper->bundleName_,
1804         authAsyncCallbackInfo_.authType, deviceId, bindParam, bindDeviceCallback);
1805     if (ret != 0) {
1806         LOGE("BindDevice failed, ret %{public}d", ret);
1807         CreateBusinessError(env, ret);
1808     }
1809     return;
1810 }
1811 
BindTarget(napi_env env,napi_callback_info info)1812 napi_value DeviceManagerNapi::BindTarget(napi_env env, napi_callback_info info)
1813 {
1814     GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1815     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE,  "Wrong number of arguments, required 3")) {
1816         return nullptr;
1817     }
1818     napi_valuetype bindPramType = napi_undefined;
1819     napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &bindPramType);
1820     if (!CheckArgsType(env, bindPramType == napi_object, "bindParam", "object")) {
1821         return nullptr;
1822     }
1823     if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
1824         return nullptr;
1825     }
1826     napi_value result = nullptr;
1827     authAsyncCallbackInfo_.env = env;
1828     napi_create_reference(env, argv[DM_NAPI_ARGS_TWO], 1, &authAsyncCallbackInfo_.callback);
1829     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1830     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1831         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1832         return result;
1833     }
1834     std::string deviceId;
1835     if (!JsToStringAndCheck(env, argv[DM_NAPI_ARGS_ZERO], "deviceId", deviceId)) {
1836         return nullptr;
1837     }
1838 
1839     napi_value object = argv[DM_NAPI_ARGS_ONE];
1840     BindDevOrTarget(deviceManagerWrapper, deviceId, env, object);
1841     napi_get_undefined(env, &result);
1842     return result;
1843 }
1844 
UnBindTarget(napi_env env,napi_callback_info info)1845 napi_value DeviceManagerNapi::UnBindTarget(napi_env env, napi_callback_info info)
1846 {
1847     LOGI("UnBindDevice");
1848     napi_value result = nullptr;
1849     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
1850     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE,  "Wrong number of arguments, required 1")) {
1851         return nullptr;
1852     }
1853     std::string deviceId;
1854     if (!JsToStringAndCheck(env, argv[0], "deviceId", deviceId)) {
1855         return nullptr;
1856     }
1857 
1858     LOGI("UnBindDevice deviceId = %{public}s", GetAnonyString(deviceId).c_str());
1859     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1860     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1861         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1862         return result;
1863     }
1864 
1865     int32_t ret = DeviceManager::GetInstance().UnBindDevice(deviceManagerWrapper->bundleName_, deviceId);
1866     if (ret != 0) {
1867         LOGE("UnBindDevice for bundleName %{public}s failed, ret %{public}d",
1868             deviceManagerWrapper->bundleName_.c_str(), ret);
1869         CreateBusinessError(env, ret);
1870     }
1871 
1872     napi_get_undefined(env, &result);
1873     return result;
1874 }
1875 
JsOnFrench(napi_env env,int32_t num,napi_value thisVar,napi_value argv[])1876 napi_value DeviceManagerNapi::JsOnFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
1877 {
1878     std::string eventType;
1879     if (!JsToStringAndCheck(env, argv[0], "type", eventType)) {
1880         return nullptr;
1881     }
1882 
1883     napi_value result = nullptr;
1884     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1885     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1886         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1887         return result;
1888     }
1889 
1890     LOGI("JsOn for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
1891         eventType.c_str());
1892     deviceManagerWrapper->On(eventType, argv[num + 1]);
1893 
1894     if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) {
1895         if (num == 1) {
1896             std::string extraString;
1897             if (!JsToStringAndCheck(env, argv[1], "extra", extraString)) {
1898                 return nullptr;
1899             }
1900             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType, extraString);
1901         } else {
1902             CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
1903         }
1904     } else {
1905         CreateDmCallback(env, deviceManagerWrapper->bundleName_, eventType);
1906     }
1907 
1908     napi_get_undefined(env, &result);
1909     return result;
1910 }
1911 
JsOn(napi_env env,napi_callback_info info)1912 napi_value DeviceManagerNapi::JsOn(napi_env env, napi_callback_info info)
1913 {
1914     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1915     if (ret != 0) {
1916         CreateBusinessError(env, ret);
1917         return nullptr;
1918     }
1919     size_t argc = 0;
1920     napi_value thisVar = nullptr;
1921     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1922     if (argc == DM_NAPI_ARGS_THREE) {
1923         LOGI("JsOn in argc == 3");
1924         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1925         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_THREE, "Wrong number of arguments, required 3")) {
1926             return nullptr;
1927         }
1928         napi_valuetype eventValueType = napi_undefined;
1929         napi_typeof(env, argv[0], &eventValueType);
1930         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1931             return nullptr;
1932         }
1933         napi_valuetype valueType;
1934         napi_typeof(env, argv[1], &valueType);
1935         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object),
1936             "extra", "string | object")) {
1937             return nullptr;
1938         }
1939         if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
1940             return nullptr;
1941         }
1942         return JsOnFrench(env, 1, thisVar, argv);
1943     } else {
1944         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
1945         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
1946             return nullptr;
1947         }
1948         napi_valuetype eventValueType = napi_undefined;
1949         napi_typeof(env, argv[0], &eventValueType);
1950         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
1951             return nullptr;
1952         }
1953         if (!IsFunctionType(env, argv[1])) {
1954             return nullptr;
1955         }
1956         return JsOnFrench(env, 0, thisVar, argv);
1957     }
1958 }
1959 
JsOffFrench(napi_env env,int32_t num,napi_value thisVar,napi_value argv[])1960 napi_value DeviceManagerNapi::JsOffFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[])
1961 {
1962     int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
1963     if (ret != 0) {
1964         CreateBusinessError(env, ret);
1965         return nullptr;
1966     }
1967     std::string eventType;
1968     if (!JsToStringAndCheck(env, argv[0], "type", eventType)) {
1969         return nullptr;
1970     }
1971     napi_value result = nullptr;
1972     DeviceManagerNapi *deviceManagerWrapper = nullptr;
1973     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
1974         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
1975         return result;
1976     }
1977 
1978     LOGI("JsOff for bundleName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(),
1979         eventType.c_str());
1980     deviceManagerWrapper->Off(eventType);
1981     ReleaseDmCallback(deviceManagerWrapper->bundleName_, eventType);
1982 
1983     napi_get_undefined(env, &result);
1984     return result;
1985 }
1986 
JsOff(napi_env env,napi_callback_info info)1987 napi_value DeviceManagerNapi::JsOff(napi_env env, napi_callback_info info)
1988 {
1989     size_t argc = 0;
1990     napi_value thisVar = nullptr;
1991     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
1992     if (argc == DM_NAPI_ARGS_THREE) {
1993         LOGI("JsOff in argc == 3");
1994         GET_PARAMS(env, info, DM_NAPI_ARGS_THREE);
1995         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
1996             return nullptr;
1997         }
1998         napi_valuetype eventValueType = napi_undefined;
1999         napi_typeof(env, argv[0], &eventValueType);
2000         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2001             return nullptr;
2002         }
2003         napi_valuetype valueType;
2004         napi_typeof(env, argv[1], &valueType);
2005         if (!CheckArgsType(env, (valueType == napi_string || valueType == napi_object), "extra", "string or object")) {
2006             return nullptr;
2007         }
2008         if (argc > DM_NAPI_ARGS_ONE) {
2009             if (!IsFunctionType(env, argv[DM_NAPI_ARGS_TWO])) {
2010                 return nullptr;
2011             }
2012         }
2013         return JsOffFrench(env, 1, thisVar, argv);
2014     } else {
2015         GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2016         if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2017             return nullptr;
2018         }
2019         napi_valuetype eventValueType = napi_undefined;
2020         napi_typeof(env, argv[0], &eventValueType);
2021         if (!CheckArgsType(env, eventValueType == napi_string, "type", "string")) {
2022             return nullptr;
2023         }
2024         if (argc > DM_NAPI_ARGS_ONE) {
2025             if (!IsFunctionType(env, argv[1])) {
2026                 return nullptr;
2027             }
2028         }
2029         return JsOffFrench(env, 0, thisVar, argv);
2030     }
2031 }
2032 
GetDeviceProfileInfoListPromise(napi_env env,DeviceProfileInfosAsyncCallbackInfo * asyncCallback)2033 napi_value DeviceManagerNapi::GetDeviceProfileInfoListPromise(napi_env env,
2034     DeviceProfileInfosAsyncCallbackInfo *asyncCallback)
2035 {
2036     LOGI("In");
2037     napi_value promise = 0;
2038     napi_deferred deferred;
2039     napi_create_promise(env, &deferred, &promise);
2040     asyncCallback->deferred = deferred;
2041     napi_value workName;
2042     napi_create_string_latin1(env, "GetDeviceProfileInfoListPromise", NAPI_AUTO_LENGTH, &workName);
2043     napi_create_async_work(env, nullptr, workName,
2044         [](napi_env env, void *data) {
2045             DeviceProfileInfosAsyncCallbackInfo *jsCallback =
2046                 reinterpret_cast<DeviceProfileInfosAsyncCallbackInfo *>(data);
2047             std::shared_ptr<DmNapiGetDeviceProfileInfoListCallback> callback =
2048                 std::make_shared<DmNapiGetDeviceProfileInfoListCallback>(jsCallback->env, jsCallback->bundleName,
2049                 jsCallback->deferred);
2050             int32_t ret = DeviceManager::GetInstance().GetDeviceProfileInfoList(jsCallback->bundleName,
2051                 jsCallback->filterOptions, callback);
2052             jsCallback->code = ret;
2053             if (ret != DM_OK) {
2054                 LOGE("GetDeviceProfileInfoList failed, bundleName:%{public}s, ret=%{public}d",
2055                     jsCallback->bundleName.c_str(), ret);
2056             }
2057         },
2058         [](napi_env env, napi_status status, void *data) {
2059             (void)status;
2060             DeviceProfileInfosAsyncCallbackInfo *jsCallback =
2061                 reinterpret_cast<DeviceProfileInfosAsyncCallbackInfo *>(data);
2062             if (jsCallback->code == ERR_DM_CALLBACK_REGISTER_FAILED) {
2063                 if (jsCallback->deferred != nullptr) {
2064                     napi_value error = CreateBusinessError(env, jsCallback->code, false);
2065                     napi_reject_deferred(env, jsCallback->deferred, error);
2066                 } else {
2067                     LOGE("jsCallback->deferred is null");
2068                 }
2069             }
2070             napi_delete_async_work(env, jsCallback->asyncWork);
2071             delete jsCallback;
2072             jsCallback = nullptr;
2073         },
2074         (void *)asyncCallback, &asyncCallback->asyncWork);
2075     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2076     return promise;
2077 }
2078 
GetDeviceNetworkIdListPromise(napi_env env,GetDeviceNetworkIdListAsyncCallbackInfo * asyncCallback)2079 napi_value DeviceManagerNapi::GetDeviceNetworkIdListPromise(napi_env env,
2080     GetDeviceNetworkIdListAsyncCallbackInfo *asyncCallback)
2081 {
2082     napi_value promise = 0;
2083     napi_deferred deferred;
2084     napi_create_promise(env, &deferred, &promise);
2085     asyncCallback->deferred = deferred;
2086     napi_value workName;
2087     napi_create_string_latin1(env, "GetDeviceNetworkIdListPromise", NAPI_AUTO_LENGTH, &workName);
2088     napi_create_async_work(env, nullptr, workName,
2089         [](napi_env env, void *data) {
2090             GetDeviceNetworkIdListAsyncCallbackInfo *jsCallback =
2091                 reinterpret_cast<GetDeviceNetworkIdListAsyncCallbackInfo *>(data);
2092             jsCallback->code = DeviceManager::GetInstance().GetDeviceNetworkIdList(jsCallback->bundleName,
2093                 jsCallback->filterOptions, jsCallback->deviceNetworkIds);
2094         },
2095         [](napi_env env, napi_status status, void *data) {
2096             (void)status;
2097             GetDeviceNetworkIdListAsyncCallbackInfo *jsCallback =
2098                 reinterpret_cast<GetDeviceNetworkIdListAsyncCallbackInfo *>(data);
2099             if (jsCallback->code != DM_OK) {
2100                 napi_value error = CreateBusinessError(env, jsCallback->code, false);
2101                 napi_reject_deferred(env, jsCallback->deferred, error);
2102             } else {
2103                 napi_value result = nullptr;
2104                 napi_create_array(env, &result);
2105                 for (uint32_t i = 0; i < jsCallback->deviceNetworkIds.size(); i++) {
2106                     napi_value element = nullptr;
2107                     napi_create_string_utf8(env, jsCallback->deviceNetworkIds[i].c_str(), NAPI_AUTO_LENGTH, &element);
2108                     napi_set_element(env, result, i, element);
2109                 }
2110                 napi_resolve_deferred(env, jsCallback->deferred, result);
2111             }
2112             napi_delete_async_work(env, jsCallback->asyncWork);
2113             delete jsCallback;
2114             jsCallback = nullptr;
2115         },
2116         (void *)asyncCallback, &asyncCallback->asyncWork);
2117     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2118     return promise;
2119 }
2120 
JsGetDeviceNetworkIdList(napi_env env,napi_callback_info info)2121 napi_value DeviceManagerNapi::JsGetDeviceNetworkIdList(napi_env env, napi_callback_info info)
2122 {
2123     LOGI("In");
2124     if (!IsSystemApp()) {
2125         LOGE("Caller is not systemApp");
2126         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2127         return nullptr;
2128     }
2129     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2130     if (ret != DM_OK) {
2131         LOGE("Do not have correct access");
2132         CreateBusinessError(env, ret);
2133         return nullptr;
2134     }
2135     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2136     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2137 
2138     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2139     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2140         LOGE("deviceManagerWrapper is NULL");
2141         CreateBusinessError(env, ERR_DM_POINT_NULL);
2142         return nullptr;
2143     }
2144     auto *jsCallback = new GetDeviceNetworkIdListAsyncCallbackInfo();
2145     if (jsCallback == nullptr) {
2146         LOGE("jsCallback is nullptr");
2147         CreateBusinessError(env, ERR_DM_POINT_NULL);
2148         return nullptr;
2149     }
2150     NetworkIdQueryFilter filterOptions;
2151     JsToDmDeviceNetworkIdFilterOptions(env, argv[0], filterOptions);
2152     jsCallback->env = env;
2153     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2154     jsCallback->filterOptions = filterOptions;
2155     return GetDeviceNetworkIdListPromise(env, jsCallback);
2156 }
2157 
JsGetDeviceProfileInfoList(napi_env env,napi_callback_info info)2158 napi_value DeviceManagerNapi::JsGetDeviceProfileInfoList(napi_env env, napi_callback_info info)
2159 {
2160     LOGI("In");
2161     if (!IsSystemApp()) {
2162         LOGE("Caller is not systemApp");
2163         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2164         return nullptr;
2165     }
2166     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2167     if (ret != DM_OK) {
2168         CreateBusinessError(env, ret);
2169         return nullptr;
2170     }
2171 
2172     size_t argc = 0;
2173     napi_value thisVar = nullptr;
2174     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2175     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2176         return nullptr;
2177     }
2178     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2179     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2180         LOGE("deviceManagerWrapper is NULL");
2181         CreateBusinessError(env, ERR_DM_POINT_NULL);
2182         return nullptr;
2183     }
2184     napi_value argv[DM_NAPI_ARGS_ONE] = {nullptr};
2185     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2186     DmDeviceProfileInfoFilterOptions filterOptions;
2187     JsToDmDeviceProfileInfoFilterOptions(env, argv[0], filterOptions);
2188     auto *jsCallback = new DeviceProfileInfosAsyncCallbackInfo();
2189     if (jsCallback == nullptr) {
2190         LOGE("jsCallback is nullptr");
2191         CreateBusinessError(env, ERR_DM_POINT_NULL);
2192         return nullptr;
2193     }
2194 
2195     jsCallback->env = env;
2196     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2197     jsCallback->filterOptions = filterOptions;
2198     return GetDeviceProfileInfoListPromise(env, jsCallback);
2199 }
2200 
GetDeviceIconInfoPromise(napi_env env,DeviceIconInfoAsyncCallbackInfo * asyncCallback)2201 napi_value DeviceManagerNapi::GetDeviceIconInfoPromise(napi_env env, DeviceIconInfoAsyncCallbackInfo *asyncCallback)
2202 {
2203     LOGI("In");
2204     napi_value promise = 0;
2205     napi_deferred deferred;
2206     napi_create_promise(env, &deferred, &promise);
2207     asyncCallback->deferred = deferred;
2208     napi_value workName;
2209     napi_create_string_latin1(env, "GetDeviceIconInfoPromise", NAPI_AUTO_LENGTH, &workName);
2210     napi_create_async_work(env, nullptr, workName,
2211         [](napi_env env, void *data) {
2212             DeviceIconInfoAsyncCallbackInfo *jsCallback =
2213                 reinterpret_cast<DeviceIconInfoAsyncCallbackInfo *>(data);
2214             std::shared_ptr<DmNapiGetDeviceIconInfoCallback> callback =
2215                 std::make_shared<DmNapiGetDeviceIconInfoCallback>(jsCallback->env, jsCallback->bundleName,
2216             jsCallback->deferred);
2217             int32_t ret = DeviceManager::GetInstance().GetDeviceIconInfo(jsCallback->bundleName,
2218                 jsCallback->filterOptions, callback);
2219             jsCallback->code = ret;
2220             if (ret != DM_OK) {
2221                 LOGE("GetDeviceIconInfoPromise failed, bundleName:%{public}s, ret=%{public}d",
2222                     jsCallback->bundleName.c_str(), ret);
2223             }
2224         },
2225         [](napi_env env, napi_status status, void *data) {
2226             (void)status;
2227             DeviceIconInfoAsyncCallbackInfo *jsCallback =
2228                 reinterpret_cast<DeviceIconInfoAsyncCallbackInfo *>(data);
2229             if (jsCallback->code == ERR_DM_CALLBACK_REGISTER_FAILED) {
2230                 if (jsCallback->deferred != nullptr) {
2231                     napi_value error = CreateBusinessError(env, jsCallback->code, false);
2232                     napi_reject_deferred(env, jsCallback->deferred, error);
2233                 } else {
2234                     LOGE("jsCallback->deferred is null");
2235                 }
2236             }
2237             napi_delete_async_work(env, jsCallback->asyncWork);
2238             delete jsCallback;
2239             jsCallback = nullptr;
2240         },
2241         (void *)asyncCallback, &asyncCallback->asyncWork);
2242     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2243     return promise;
2244 }
2245 
JsGetDeviceIconInfo(napi_env env,napi_callback_info info)2246 napi_value DeviceManagerNapi::JsGetDeviceIconInfo(napi_env env, napi_callback_info info)
2247 {
2248     LOGI("In");
2249     if (!IsSystemApp()) {
2250         LOGE("Caller is not systemApp");
2251         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2252         return nullptr;
2253     }
2254     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2255     if (ret != DM_OK) {
2256         CreateBusinessError(env, ret);
2257         return nullptr;
2258     }
2259 
2260     size_t argc = 0;
2261     napi_value thisVar = nullptr;
2262     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2263     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2264         return nullptr;
2265     }
2266     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2267     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2268         LOGE("deviceManagerWrapper is NULL");
2269         CreateBusinessError(env, ERR_DM_POINT_NULL);
2270         return nullptr;
2271     }
2272     napi_value argv[DM_NAPI_ARGS_ONE] = {nullptr};
2273     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2274     DmDeviceIconInfoFilterOptions filterOptions;
2275     JsToDmDeviceIconInfoFilterOptions(env, argv[0], filterOptions);
2276     auto *jsCallback = new DeviceIconInfoAsyncCallbackInfo();
2277     if (jsCallback == nullptr) {
2278         LOGE("jsCallback is nullptr");
2279         CreateBusinessError(env, ERR_DM_POINT_NULL);
2280         return nullptr;
2281     }
2282 
2283     jsCallback->env = env;
2284     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2285     jsCallback->filterOptions = filterOptions;
2286     return GetDeviceIconInfoPromise(env, jsCallback);
2287 }
2288 
SetHeartbeatPolicy(napi_env env,napi_callback_info info)2289 napi_value DeviceManagerNapi::SetHeartbeatPolicy(napi_env env, napi_callback_info info)
2290 {
2291     LOGI("in");
2292     size_t argsCount = 0;
2293     napi_value thisArg = nullptr;
2294     NAPI_CALL(env, napi_get_cb_info(env, info, &argsCount, nullptr, &thisArg, nullptr));
2295     if (!CheckArgsCount(env, argsCount >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2296         return nullptr;
2297     }
2298     if (!IsSystemApp()) {
2299         LOGI("The caller is not SystemApp");
2300         CreateBusinessError(env, ERR_NOT_SYSTEM_APP);
2301         return nullptr;
2302     }
2303     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2304     napi_valuetype valueType;
2305     napi_typeof(env, argv[0], &valueType);
2306     if (!CheckArgsType(env, valueType == napi_number, "policy", "number")) {
2307         return nullptr;
2308     }
2309     int32_t policy = 0;
2310     napi_get_value_int32(env, argv[0], &policy);
2311 
2312     napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &valueType);
2313     if (!CheckArgsType(env, valueType == napi_number, "delayTime", "number")) {
2314         return nullptr;
2315     }
2316     int32_t delayTime = 0;
2317     napi_get_value_int32(env, argv[DM_NAPI_ARGS_ONE], &delayTime);
2318 
2319     napi_value result = nullptr;
2320     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2321     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2322         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2323         return result;
2324     }
2325     std::map<std::string, std::string> policyParam;
2326     policyParam[PARAM_KEY_POLICY_STRATEGY_FOR_BLE] = std::to_string(policy);
2327     policyParam[PARAM_KEY_POLICY_TIME_OUT] = std::to_string(delayTime);
2328     int32_t ret = DeviceManager::GetInstance().SetDnPolicy(deviceManagerWrapper->bundleName_, policyParam);
2329     if (ret != 0) {
2330         LOGE("bundleName %{public}s failed, ret %{public}d",
2331             deviceManagerWrapper->bundleName_.c_str(), ret);
2332         CreateBusinessError(env, ret);
2333     }
2334     napi_get_undefined(env, &result);
2335     return result;
2336 }
2337 
PutDeviceProfileInfoListPromise(napi_env env,PutDeviceProfileInfoListAsyncCallbackInfo * asyncCallback)2338 napi_value DeviceManagerNapi::PutDeviceProfileInfoListPromise(napi_env env,
2339     PutDeviceProfileInfoListAsyncCallbackInfo *asyncCallback)
2340 {
2341     LOGI("In");
2342     napi_value promise = 0;
2343     napi_deferred deferred;
2344     napi_create_promise(env, &deferred, &promise);
2345     asyncCallback->deferred = deferred;
2346     napi_value workName;
2347     napi_create_string_latin1(env, "PutDeviceProfileInfoListPromise", NAPI_AUTO_LENGTH, &workName);
2348     napi_create_async_work(env, nullptr, workName,
2349         [](napi_env env, void *data) {
2350             PutDeviceProfileInfoListAsyncCallbackInfo *jsCallback =
2351                 reinterpret_cast<PutDeviceProfileInfoListAsyncCallbackInfo *>(data);
2352             jsCallback->code = DeviceManager::GetInstance().PutDeviceProfileInfoList(jsCallback->bundleName,
2353                 jsCallback->deviceProfileInfos);
2354         },
2355         [](napi_env env, napi_status status, void *data) {
2356             (void)status;
2357             PutDeviceProfileInfoListAsyncCallbackInfo *jsCallback =
2358                 reinterpret_cast<PutDeviceProfileInfoListAsyncCallbackInfo *>(data);
2359             if (jsCallback->code != DM_OK) {
2360                 napi_value error = CreateBusinessError(env, jsCallback->code, false);
2361                 napi_reject_deferred(env, jsCallback->deferred, error);
2362             } else {
2363                 napi_value result = nullptr;
2364                 napi_create_int32(env, DM_OK, &result);
2365                 napi_resolve_deferred(env, jsCallback->deferred, result);
2366             }
2367             napi_delete_async_work(env, jsCallback->asyncWork);
2368             delete jsCallback;
2369             jsCallback = nullptr;
2370         },
2371         (void *)asyncCallback, &asyncCallback->asyncWork);
2372     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2373     return promise;
2374 }
2375 
JsPutDeviceProfileInfoList(napi_env env,napi_callback_info info)2376 napi_value DeviceManagerNapi::JsPutDeviceProfileInfoList(napi_env env, napi_callback_info info)
2377 {
2378     LOGI("In");
2379     if (!IsSystemApp()) {
2380         LOGE("Caller is not systemApp");
2381         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2382         return nullptr;
2383     }
2384     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2385     if (ret != DM_OK) {
2386         CreateBusinessError(env, ret);
2387         return nullptr;
2388     }
2389 
2390     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2391     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2392     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2393         return nullptr;
2394     }
2395     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2396     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2397         LOGE("deviceManagerWrapper is NULL");
2398         CreateBusinessError(env, ERR_DM_POINT_NULL);
2399         return nullptr;
2400     }
2401     std::vector<DmDeviceProfileInfo> deviceProfileInfos;
2402     if (!JsToDmDeviceProfileInfos(env, argv[0], deviceProfileInfos)) {
2403         LOGE("JsToDmDeviceProfileInfos fail");
2404         CreateBusinessError(env, ERR_INVALID_PARAMS);
2405         return nullptr;
2406     }
2407     auto *jsCallback = new PutDeviceProfileInfoListAsyncCallbackInfo();
2408     if (jsCallback == nullptr) {
2409         LOGE("jsCallback is nullptr");
2410         CreateBusinessError(env, ERR_DM_POINT_NULL);
2411         return nullptr;
2412     }
2413     jsCallback->env = env;
2414     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2415     jsCallback->deviceProfileInfos = deviceProfileInfos;
2416     return PutDeviceProfileInfoListPromise(env, jsCallback);
2417 }
2418 
GetLocalDisplayDeviceNamePromise(napi_env env,GetLocalDisplayDeviceNameAsyncCallbackInfo * asyncCallback)2419 napi_value DeviceManagerNapi::GetLocalDisplayDeviceNamePromise(napi_env env,
2420     GetLocalDisplayDeviceNameAsyncCallbackInfo *asyncCallback)
2421 {
2422     LOGI("In");
2423     napi_value promise = 0;
2424     napi_deferred deferred;
2425     napi_create_promise(env, &deferred, &promise);
2426     asyncCallback->deferred = deferred;
2427     napi_value workName;
2428     napi_create_string_latin1(env, "GetLocalDisplayDeviceNamePromise", NAPI_AUTO_LENGTH, &workName);
2429     napi_create_async_work(env, nullptr, workName,
2430         [](napi_env env, void *data) {
2431             GetLocalDisplayDeviceNameAsyncCallbackInfo *jsCallback =
2432                 reinterpret_cast<GetLocalDisplayDeviceNameAsyncCallbackInfo *>(data);
2433             jsCallback->code = DeviceManager::GetInstance().GetLocalDisplayDeviceName(jsCallback->bundleName,
2434                 jsCallback->maxNameLength, jsCallback->displayName);
2435         },
2436         [](napi_env env, napi_status status, void *data) {
2437             (void)status;
2438             GetLocalDisplayDeviceNameAsyncCallbackInfo *jsCallback =
2439                 reinterpret_cast<GetLocalDisplayDeviceNameAsyncCallbackInfo *>(data);
2440             if (jsCallback->code != DM_OK) {
2441                 napi_value error = CreateBusinessError(env, jsCallback->code, false);
2442                 napi_reject_deferred(env, jsCallback->deferred, error);
2443             } else {
2444                 napi_value result = nullptr;
2445                 napi_create_string_utf8(env, jsCallback->displayName.c_str(), NAPI_AUTO_LENGTH, &result);
2446                 napi_resolve_deferred(env, jsCallback->deferred, result);
2447             }
2448             napi_delete_async_work(env, jsCallback->asyncWork);
2449             delete jsCallback;
2450             jsCallback = nullptr;
2451         },
2452         (void *)asyncCallback, &asyncCallback->asyncWork);
2453     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2454     return promise;
2455 }
2456 
JsGetLocalDisplayDeviceName(napi_env env,napi_callback_info info)2457 napi_value DeviceManagerNapi::JsGetLocalDisplayDeviceName(napi_env env, napi_callback_info info)
2458 {
2459     LOGI("In");
2460     if (!IsSystemApp()) {
2461         LOGE("Caller is not systemApp");
2462         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2463         return nullptr;
2464     }
2465     int32_t ret = DeviceManager::GetInstance().CheckAPIAccessPermission();
2466     if (ret != DM_OK) {
2467         CreateBusinessError(env, ret);
2468         return nullptr;
2469     }
2470     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2471     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2472     int32_t maxNameLength = 0;
2473     if (argc >= DM_NAPI_ARGS_ONE) {
2474         napi_valuetype maxNameLengthType = napi_undefined;
2475         napi_typeof(env, argv[0], &maxNameLengthType);
2476         if (!CheckArgsType(env, maxNameLengthType == napi_number, "maxNameLength", "number")) {
2477             return nullptr;
2478         }
2479         napi_get_value_int32(env, argv[0], &maxNameLength);
2480     }
2481 
2482     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2483     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2484         LOGE("deviceManagerWrapper is NULL");
2485         CreateBusinessError(env, ERR_DM_POINT_NULL);
2486         return nullptr;
2487     }
2488     auto *jsCallback = new GetLocalDisplayDeviceNameAsyncCallbackInfo();
2489     if (jsCallback == nullptr) {
2490         LOGE("jsCallback is nullptr");
2491         CreateBusinessError(env, ERR_DM_POINT_NULL);
2492         return nullptr;
2493     }
2494 
2495     jsCallback->env = env;
2496     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2497     jsCallback->maxNameLength = maxNameLength;
2498     return GetLocalDisplayDeviceNamePromise(env, jsCallback);
2499 }
2500 
SetLocalDeviceNamePromise(napi_env env,SetLocalDeviceNameAsyncCallbackInfo * asyncCallback)2501 napi_value DeviceManagerNapi::SetLocalDeviceNamePromise(napi_env env,
2502     SetLocalDeviceNameAsyncCallbackInfo *asyncCallback)
2503 {
2504     LOGI("In");
2505     napi_value promise = 0;
2506     napi_deferred deferred;
2507     napi_create_promise(env, &deferred, &promise);
2508     asyncCallback->deferred = deferred;
2509     napi_value workName;
2510     napi_create_string_latin1(env, "SetLocalDeviceNamePromise", NAPI_AUTO_LENGTH, &workName);
2511     napi_create_async_work(env, nullptr, workName,
2512         [](napi_env env, void *data) {
2513             SetLocalDeviceNameAsyncCallbackInfo *jsCallback =
2514                 reinterpret_cast<SetLocalDeviceNameAsyncCallbackInfo *>(data);
2515             std::shared_ptr<DmNapiSetLocalDeviceNameCallback> callback =
2516                 std::make_shared<DmNapiSetLocalDeviceNameCallback>(jsCallback->env, jsCallback->bundleName,
2517                 jsCallback->deferred);
2518             int32_t ret = DeviceManager::GetInstance().SetLocalDeviceName(jsCallback->bundleName,
2519                 jsCallback->deviceName, callback);
2520             jsCallback->code = ret;
2521             if (ret != DM_OK) {
2522                 LOGE("SetLocalDeviceName failed, bundleName:%{public}s, ret=%{public}d",
2523                     jsCallback->bundleName.c_str(), ret);
2524             }
2525         },
2526         [](napi_env env, napi_status status, void *data) {
2527             (void)status;
2528             SetLocalDeviceNameAsyncCallbackInfo *jsCallback =
2529                 reinterpret_cast<SetLocalDeviceNameAsyncCallbackInfo *>(data);
2530             if (jsCallback->code == ERR_DM_CALLBACK_REGISTER_FAILED) {
2531                 if (jsCallback->deferred != nullptr) {
2532                     napi_value error = CreateBusinessError(env, jsCallback->code, false);
2533                     napi_reject_deferred(env, jsCallback->deferred, error);
2534                 } else {
2535                     LOGE("jsCallback->deferred is null");
2536                 }
2537             }
2538             napi_delete_async_work(env, jsCallback->asyncWork);
2539             delete jsCallback;
2540             jsCallback = nullptr;
2541         },
2542         (void *)asyncCallback, &asyncCallback->asyncWork);
2543     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2544     return promise;
2545 }
2546 
SetRemoteDeviceNamePromise(napi_env env,SetRemoteDeviceNameAsyncCallbackInfo * asyncCallback)2547 napi_value DeviceManagerNapi::SetRemoteDeviceNamePromise(napi_env env,
2548     SetRemoteDeviceNameAsyncCallbackInfo *asyncCallback)
2549 {
2550     LOGI("In");
2551     napi_value promise = 0;
2552     napi_deferred deferred;
2553     napi_create_promise(env, &deferred, &promise);
2554     asyncCallback->deferred = deferred;
2555     napi_value workName;
2556     napi_create_string_latin1(env, "SetRemoteDeviceNamePromise", NAPI_AUTO_LENGTH, &workName);
2557     napi_create_async_work(env, nullptr, workName,
2558         [](napi_env env, void *data) {
2559             SetRemoteDeviceNameAsyncCallbackInfo *jsCallback =
2560                 reinterpret_cast<SetRemoteDeviceNameAsyncCallbackInfo *>(data);
2561             std::shared_ptr<DmNapiSetRemoteDeviceNameCallback> callback =
2562                 std::make_shared<DmNapiSetRemoteDeviceNameCallback>(jsCallback->env, jsCallback->bundleName,
2563                 jsCallback->deferred);
2564             int32_t ret = DeviceManager::GetInstance().SetRemoteDeviceName(jsCallback->bundleName,
2565                 jsCallback->deviceId, jsCallback->deviceName, callback);
2566             jsCallback->code = ret;
2567             if (ret != DM_OK) {
2568                 LOGE("SetRemoteDeviceName failed, bundleName:%{public}s, ret=%{public}d",
2569                     jsCallback->bundleName.c_str(), ret);
2570             }
2571         },
2572         [](napi_env env, napi_status status, void *data) {
2573             (void)status;
2574             SetRemoteDeviceNameAsyncCallbackInfo *jsCallback =
2575                 reinterpret_cast<SetRemoteDeviceNameAsyncCallbackInfo *>(data);
2576             if (jsCallback->code == ERR_DM_CALLBACK_REGISTER_FAILED) {
2577                 if (jsCallback->deferred != nullptr) {
2578                     napi_value error = CreateBusinessError(env, jsCallback->code, false);
2579                     napi_reject_deferred(env, jsCallback->deferred, error);
2580                 } else {
2581                     LOGE("jsCallback->deferred is null");
2582                 }
2583             }
2584             napi_delete_async_work(env, jsCallback->asyncWork);
2585             delete jsCallback;
2586             jsCallback = nullptr;
2587         },
2588         (void *)asyncCallback, &asyncCallback->asyncWork);
2589     napi_queue_async_work_with_qos(env, asyncCallback->asyncWork, napi_qos_user_initiated);
2590     return promise;
2591 }
2592 
JsSetLocalDeviceName(napi_env env,napi_callback_info info)2593 napi_value DeviceManagerNapi::JsSetLocalDeviceName(napi_env env, napi_callback_info info)
2594 {
2595     LOGI("In");
2596     if (!IsSystemApp()) {
2597         LOGE("Caller is not systemApp");
2598         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2599         return nullptr;
2600     }
2601     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2602     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2603         return nullptr;
2604     }
2605     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2606     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2607         LOGE("deviceManagerWrapper is NULL");
2608         CreateBusinessError(env, ERR_DM_POINT_NULL);
2609         return nullptr;
2610     }
2611     std::string deviceName = "";
2612     if (!JsToStringAndCheck(env, argv[0], "deviceName", deviceName)) {
2613         return nullptr;
2614     }
2615     if (deviceName.size() > DEVICE_NAME_MAX_BYTES) {
2616         LOGE("deviceName is too long");
2617         CreateBusinessError(env, ERR_DM_INPUT_PARA_INVALID);
2618         return nullptr;
2619     }
2620     auto *jsCallback = new SetLocalDeviceNameAsyncCallbackInfo();
2621     if (jsCallback == nullptr) {
2622         LOGE("jsCallback is nullptr");
2623         CreateBusinessError(env, ERR_DM_POINT_NULL);
2624         return nullptr;
2625     }
2626     jsCallback->env = env;
2627     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2628     jsCallback->deviceName = deviceName;
2629     return SetLocalDeviceNamePromise(env, jsCallback);
2630 }
2631 
JsSetRemoteDeviceName(napi_env env,napi_callback_info info)2632 napi_value DeviceManagerNapi::JsSetRemoteDeviceName(napi_env env, napi_callback_info info)
2633 {
2634     LOGI("In");
2635     if (!IsSystemApp()) {
2636         LOGE("Caller is not systemApp");
2637         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2638         return nullptr;
2639     }
2640     GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
2641     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2")) {
2642         return nullptr;
2643     }
2644     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2645     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2646         LOGE("deviceManagerWrapper is NULL");
2647         CreateBusinessError(env, ERR_DM_POINT_NULL);
2648         return nullptr;
2649     }
2650     std::string deviceName = "";
2651     if (!JsToStringAndCheck(env, argv[0], "deviceName", deviceName)) {
2652         return nullptr;
2653     }
2654     if (deviceName.size() > DEVICE_NAME_MAX_BYTES) {
2655         LOGE("deviceName is too long");
2656         CreateBusinessError(env, ERR_DM_INPUT_PARA_INVALID);
2657         return nullptr;
2658     }
2659     std::string deviceId = "";
2660     if (!JsToStringAndCheck(env, argv[1], "deviceId", deviceId)) {
2661         return nullptr;
2662     }
2663     auto *jsCallback = new SetRemoteDeviceNameAsyncCallbackInfo();
2664     if (jsCallback == nullptr) {
2665         LOGE("jsCallback is nullptr");
2666         CreateBusinessError(env, ERR_DM_POINT_NULL);
2667         return nullptr;
2668     }
2669 
2670     jsCallback->env = env;
2671     jsCallback->bundleName = deviceManagerWrapper->bundleName_;
2672     jsCallback->deviceId = deviceId;
2673     jsCallback->deviceName = deviceName;
2674     return SetRemoteDeviceNamePromise(env, jsCallback);
2675 }
2676 
JsRestoreLocalDeviceName(napi_env env,napi_callback_info info)2677 napi_value DeviceManagerNapi::JsRestoreLocalDeviceName(napi_env env, napi_callback_info info)
2678 {
2679     LOGI("In");
2680     if (!IsSystemApp()) {
2681         LOGE("Caller is not systemApp");
2682         CreateBusinessError(env, static_cast<int32_t>(DMBussinessErrorCode::ERR_NOT_SYSTEM_APP));
2683         return nullptr;
2684     }
2685     size_t argc = 0;
2686     napi_value thisVar = nullptr;
2687     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
2688     napi_value result = nullptr;
2689     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2690     if (IsDeviceManagerNapiNull(env, thisVar, &deviceManagerWrapper)) {
2691         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2692         return result;
2693     }
2694     int32_t ret = DeviceManager::GetInstance().RestoreLocalDeviceName(deviceManagerWrapper->bundleName_);
2695     if (ret != 0) {
2696         LOGE("bundleName %{public}s failed, ret %{public}d",
2697             deviceManagerWrapper->bundleName_.c_str(), ret);
2698         CreateBusinessError(env, ret);
2699     }
2700     napi_get_undefined(env, &result);
2701     return result;
2702 }
2703 
ClearBundleCallbacks(std::string & bundleName)2704 void DeviceManagerNapi::ClearBundleCallbacks(std::string &bundleName)
2705 {
2706     LOGI("ClearBundleCallbacks start for bundleName %{public}s", bundleName.c_str());
2707     {
2708         std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
2709         g_deviceManagerMap.erase(bundleName);
2710     }
2711     {
2712         std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
2713         g_initCallbackMap.erase(bundleName);
2714     }
2715     {
2716         std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
2717         g_deviceStatusCallbackMap.erase(bundleName);
2718     }
2719     {
2720         std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
2721         g_DiscoveryCallbackMap.erase(bundleName);
2722     }
2723     {
2724         std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
2725         g_publishCallbackMap.erase(bundleName);
2726     }
2727     {
2728         std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
2729         g_authCallbackMap.erase(bundleName);
2730     }
2731     {
2732         std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
2733         g_bindCallbackMap.erase(bundleName);
2734     }
2735     return;
2736 }
2737 
ReleaseDeviceManager(napi_env env,napi_callback_info info)2738 napi_value DeviceManagerNapi::ReleaseDeviceManager(napi_env env, napi_callback_info info)
2739 {
2740     LOGI("ReleaseDeviceManager in");
2741     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2742     if (!CheckArgsCount(env, argc == DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2743         return nullptr;
2744     }
2745     napi_valuetype argvType = napi_undefined;
2746     napi_typeof(env, argv[0], &argvType);
2747     if (!CheckArgsType(env, argvType == napi_object, "DeviceManager", "object")) {
2748         return nullptr;
2749     }
2750     napi_value result = nullptr;
2751     DeviceManagerNapi *deviceManagerWrapper = nullptr;
2752     if (IsDeviceManagerNapiNull(env, argv[0], &deviceManagerWrapper)) {
2753         napi_create_uint32(env, ERR_DM_POINT_NULL, &result);
2754         return result;
2755     }
2756     LOGI("ReleaseDeviceManager for bundleName %{public}s", deviceManagerWrapper->bundleName_.c_str());
2757     int32_t ret = DeviceManager::GetInstance().UnInitDeviceManager(deviceManagerWrapper->bundleName_);
2758     if (ret != 0) {
2759         LOGE("ReleaseDeviceManager for bundleName %{public}s failed, ret %{public}d",
2760             deviceManagerWrapper->bundleName_.c_str(), ret);
2761         CreateBusinessError(env, ret);
2762         napi_create_uint32(env, static_cast<uint32_t>(ret), &result);
2763         return result;
2764     }
2765     ClearBundleCallbacks(deviceManagerWrapper->bundleName_);
2766     napi_get_undefined(env, &result);
2767     NAPI_CALL(env, napi_remove_wrap(env, argv[0], (void**)&deviceManagerWrapper));
2768     return result;
2769 }
2770 
CreateDeviceManager(napi_env env,napi_callback_info info)2771 napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info)
2772 {
2773     LOGI("In");
2774     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2775     if (!CheckArgsCount(env, argc == DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2776         return nullptr;
2777     }
2778     std::string bundleName;
2779     if (!JsToStringAndCheck(env, argv[0], "bundleName", bundleName)) {
2780         return nullptr;
2781     }
2782     std::shared_ptr<DmNapiInitCallback> initCallback = std::make_shared<DmNapiInitCallback>(env, bundleName);
2783     int32_t ret = DeviceManager::GetInstance().InitDeviceManager(bundleName, initCallback);
2784     if (ret != 0) {
2785         LOGE("CreateDeviceManager for bundleName %{public}s failed, ret %{public}d.", bundleName.c_str(), ret);
2786         CreateBusinessError(env, ret);
2787         return nullptr;
2788     }
2789     {
2790         std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
2791         CHECK_SIZE_RETURN(g_initCallbackMap, nullptr);
2792         g_initCallbackMap[bundleName] = initCallback;
2793     }
2794     napi_value ctor = nullptr;
2795     napi_value napiName = nullptr;
2796     napi_value result = nullptr;
2797     napi_get_reference_value(env, sConstructor_, &ctor);
2798     napi_create_string_utf8(env, bundleName.c_str(), NAPI_AUTO_LENGTH, &napiName);
2799     napi_status status = napi_new_instance(env, ctor, DM_NAPI_ARGS_ONE, &napiName, &result);
2800     if (status != napi_ok) {
2801         LOGE("Create DeviceManagerNapi for bundleName %{public}s failed", bundleName.c_str());
2802     }
2803     return result;
2804 }
2805 
Constructor(napi_env env,napi_callback_info info)2806 napi_value DeviceManagerNapi::Constructor(napi_env env, napi_callback_info info)
2807 {
2808     LOGI("In");
2809     GET_PARAMS(env, info, DM_NAPI_ARGS_ONE);
2810     if (!CheckArgsCount(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1")) {
2811         return nullptr;
2812     }
2813     std::string bundleName;
2814     if (!JsToStringAndCheck(env, argv[0], "bundleName", bundleName)) {
2815         return nullptr;
2816     }
2817 
2818     LOGI("Create for packageName:%{public}s", bundleName.c_str());
2819     DeviceManagerNapi *obj = new DeviceManagerNapi(env, thisVar);
2820     if (obj == nullptr) {
2821         return nullptr;
2822     }
2823 
2824     obj->bundleName_ = bundleName;
2825     std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
2826     if (g_deviceManagerMap.size() >= MAX_CONTAINER_SIZE) {
2827         LOGE("g_deviceManagerMap map size is more than max size");
2828         delete obj;
2829         obj = nullptr;
2830         return nullptr;
2831     }
2832     g_deviceManagerMap[obj->bundleName_] = obj;
2833     napi_status status = napi_wrap(
2834         env, thisVar, reinterpret_cast<void *>(obj),
2835         [](napi_env env, void *data, void *hint) {
2836             (void)env;
2837             (void)hint;
2838             DeviceManagerNapi *deviceManager = reinterpret_cast<DeviceManagerNapi *>(data);
2839             delete deviceManager;
2840             deviceManager = nullptr;
2841             LOGI("delete deviceManager");
2842         },
2843         nullptr, nullptr);
2844     if (status != napi_ok) {
2845         delete obj;
2846         obj = nullptr;
2847         LOGE("failed to wrap JS object");
2848         return nullptr;
2849     }
2850     return thisVar;
2851 }
2852 
Init(napi_env env,napi_value exports)2853 napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports)
2854 {
2855     napi_value dmClass = nullptr;
2856     napi_property_descriptor dmProperties[] = {
2857         DECLARE_NAPI_FUNCTION("getAvailableDeviceListSync", GetAvailableDeviceListSync),
2858         DECLARE_NAPI_FUNCTION("getAvailableDeviceList", GetAvailableDeviceList),
2859         DECLARE_NAPI_FUNCTION("getLocalDeviceNetworkId", GetLocalDeviceNetworkId),
2860         DECLARE_NAPI_FUNCTION("getLocalDeviceId", GetLocalDeviceId),
2861         DECLARE_NAPI_FUNCTION("getLocalDeviceName", GetLocalDeviceName),
2862         DECLARE_NAPI_FUNCTION("getLocalDeviceType", GetLocalDeviceType),
2863         DECLARE_NAPI_FUNCTION("getDeviceName", GetDeviceName),
2864         DECLARE_NAPI_FUNCTION("getDeviceType", GetDeviceType),
2865         DECLARE_NAPI_FUNCTION("startDiscovering", StartDeviceDiscover),
2866         DECLARE_NAPI_FUNCTION("stopDiscovering", StopDeviceDiscover),
2867         DECLARE_NAPI_FUNCTION("unbindTarget", UnBindTarget),
2868         DECLARE_NAPI_FUNCTION("bindTarget", BindTarget),
2869         DECLARE_NAPI_FUNCTION("replyUiAction", SetUserOperationSync),
2870         DECLARE_NAPI_FUNCTION("on", JsOn),
2871         DECLARE_NAPI_FUNCTION("off", JsOff),
2872         DECLARE_NAPI_FUNCTION("getDeviceProfileInfoList", JsGetDeviceProfileInfoList),
2873         DECLARE_NAPI_FUNCTION("getDeviceIconInfo", JsGetDeviceIconInfo),
2874         DECLARE_NAPI_FUNCTION("putDeviceProfileInfoList", JsPutDeviceProfileInfoList),
2875         DECLARE_NAPI_FUNCTION("getLocalDisplayDeviceName", JsGetLocalDisplayDeviceName),
2876         DECLARE_NAPI_FUNCTION("setLocalDeviceName", JsSetLocalDeviceName),
2877         DECLARE_NAPI_FUNCTION("setRemoteDeviceName", JsSetRemoteDeviceName),
2878         DECLARE_NAPI_FUNCTION("restoreLocalDeviceName", JsRestoreLocalDeviceName),
2879         DECLARE_NAPI_FUNCTION("restoreLocalDeivceName", JsRestoreLocalDeviceName),
2880         DECLARE_NAPI_FUNCTION("getDeviceNetworkIdList", JsGetDeviceNetworkIdList),
2881         DECLARE_NAPI_FUNCTION("setHeartbeatPolicy", SetHeartbeatPolicy)};
2882 
2883     napi_property_descriptor static_prop[] = {
2884         DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager),
2885         DECLARE_NAPI_STATIC_FUNCTION("releaseDeviceManager", ReleaseDeviceManager),
2886     };
2887 
2888     LOGI("DeviceManagerNapi::Init() is called!");
2889     NAPI_CALL(env, napi_define_class(env, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor,
2890                                      nullptr, sizeof(dmProperties) / sizeof(dmProperties[0]), dmProperties, &dmClass));
2891     NAPI_CALL(env, napi_create_reference(env, dmClass, 1, &sConstructor_));
2892     NAPI_CALL(env, napi_set_named_property(env, exports, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), dmClass));
2893     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop));
2894     LOGI("All props and functions are configured..");
2895     return exports;
2896 }
2897 
EnumTypeConstructor(napi_env env,napi_callback_info info)2898 napi_value DeviceManagerNapi::EnumTypeConstructor(napi_env env, napi_callback_info info)
2899 {
2900     size_t argc = 0;
2901     napi_value res = nullptr;
2902     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &res, nullptr));
2903     return res;
2904 }
2905 
InitDeviceStatusChangeActionEnum(napi_env env,napi_value exports)2906 napi_value DeviceManagerNapi::InitDeviceStatusChangeActionEnum(napi_env env, napi_value exports)
2907 {
2908     napi_value device_state_online;
2909     napi_value device_state_ready;
2910     napi_value device_state_offline;
2911     int32_t refCount = 1;
2912 
2913     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_ONLINE),
2914         &device_state_online);
2915     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_INFO_READY),
2916         &device_state_ready);
2917     napi_create_uint32(env, static_cast<uint32_t>(DmDeviceState::DEVICE_STATE_OFFLINE),
2918         &device_state_offline);
2919 
2920     napi_property_descriptor desc[] = {
2921         DECLARE_NAPI_STATIC_PROPERTY("UNKNOWN", device_state_online),
2922         DECLARE_NAPI_STATIC_PROPERTY("AVAILABLE", device_state_ready),
2923         DECLARE_NAPI_STATIC_PROPERTY("UNAVAILABLE", device_state_offline),
2924     };
2925 
2926     napi_value result = nullptr;
2927     napi_define_class(env, "DeviceStateChange", NAPI_AUTO_LENGTH, EnumTypeConstructor,
2928         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
2929     napi_create_reference(env, result, refCount, &deviceStateChangeActionEnumConstructor_);
2930     napi_set_named_property(env, exports, "DeviceStateChange", result);
2931     return exports;
2932 }
2933 
InitStrategyForHeartbeatEnum(napi_env env,napi_value exports)2934 napi_value DeviceManagerNapi::InitStrategyForHeartbeatEnum(napi_env env, napi_value exports)
2935 {
2936     const uint32_t stop_heartbeat = 100;
2937     const uint32_t start_heartbeat = 101;
2938 
2939     napi_value start_heartbeat_value;
2940     napi_value stop_heartbeat_value;
2941     int32_t refCount = 1;
2942 
2943     napi_create_uint32(env, start_heartbeat, &start_heartbeat_value);
2944     napi_create_uint32(env, stop_heartbeat, &stop_heartbeat_value);
2945 
2946     napi_property_descriptor desc[] = {
2947         DECLARE_NAPI_STATIC_PROPERTY("START_HEARTBEAT", start_heartbeat_value),
2948         DECLARE_NAPI_STATIC_PROPERTY("TEMP_STOP_HEARTBEAT", stop_heartbeat_value),
2949     };
2950 
2951     napi_value result = nullptr;
2952     napi_define_class(env, "StrategyForHeartbeat", NAPI_AUTO_LENGTH, EnumTypeConstructor,
2953         nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
2954     napi_create_reference(env, result, refCount, &g_strategyForHeartbeatEnumConstructor);
2955     napi_set_named_property(env, exports, "StrategyForHeartbeat", result);
2956     return exports;
2957 }
2958 
BindTargetWarpper(const std::string & pkgName,const std::string & deviceId,const std::string & bindParam,std::shared_ptr<DmNapiBindTargetCallback> callback)2959 int32_t DeviceManagerNapi::BindTargetWarpper(const std::string &pkgName, const std::string &deviceId,
2960     const std::string &bindParam, std::shared_ptr<DmNapiBindTargetCallback> callback)
2961 {
2962     if (bindParam.empty()) {
2963         return ERR_DM_INPUT_PARA_INVALID;
2964     }
2965     JsonObject bindParamObj(bindParam);
2966     if (bindParamObj.IsDiscarded()) {
2967         return ERR_DM_INPUT_PARA_INVALID;
2968     }
2969     PeerTargetId targetId;
2970     targetId.deviceId = deviceId;
2971     if (IsString(bindParamObj, PARAM_KEY_BR_MAC)) {
2972         targetId.brMac = bindParamObj[PARAM_KEY_BR_MAC].Get<std::string>();
2973     }
2974     if (IsString(bindParamObj, PARAM_KEY_BLE_MAC)) {
2975         targetId.bleMac = bindParamObj[PARAM_KEY_BLE_MAC].Get<std::string>();
2976     }
2977     if (IsString(bindParamObj, PARAM_KEY_WIFI_IP)) {
2978         targetId.wifiIp = bindParamObj[PARAM_KEY_WIFI_IP].Get<std::string>();
2979     }
2980     if (IsInt32(bindParamObj, PARAM_KEY_WIFI_PORT)) {
2981         targetId.wifiPort = (uint16_t)(bindParamObj[PARAM_KEY_WIFI_PORT].Get<int32_t>());
2982     }
2983 
2984     std::map<std::string, std::string> bindParamMap;
2985     InsertMapParames(bindParamObj, bindParamMap);
2986     return DeviceManager::GetInstance().BindTarget(pkgName, targetId, bindParamMap, callback);
2987 }
2988 
2989 /*
2990  * Function registering all props and functions of ohos.distributedhardware
2991  */
Export(napi_env env,napi_value exports)2992 static napi_value Export(napi_env env, napi_value exports)
2993 {
2994     LOGI("Export() is called!");
2995     DeviceManagerNapi::Init(env, exports);
2996     DeviceManagerNapi::InitDeviceStatusChangeActionEnum(env, exports);
2997     DeviceManagerNapi::InitStrategyForHeartbeatEnum(env, exports);
2998     return exports;
2999 }
3000 
3001 /*
3002  * module define
3003  */
3004 static napi_module g_dmModule = {.nm_version = 1,
3005                                  .nm_flags = 0,
3006                                  .nm_filename = nullptr,
3007                                  .nm_register_func = Export,
3008                                  .nm_modname = "distributedDeviceManager",
3009                                  .nm_priv = ((void *)0),
3010                                  .reserved = {0}};
3011 
3012 /*
3013  * module register
3014  */
RegisterModule(void)3015 extern "C" __attribute__((constructor)) void RegisterModule(void)
3016 {
3017     LOGI("RegisterModule() is called!");
3018     napi_module_register(&g_dmModule);
3019 }
3020 
OnResult(const OHOS::DistributedHardware::DmDeviceIconInfo & deviceIconInfo,int32_t code)3021 void DmNapiGetDeviceIconInfoCallback::OnResult(const OHOS::DistributedHardware::DmDeviceIconInfo &deviceIconInfo,
3022     int32_t code)
3023 {
3024     LOGI("In code:%{public}d", code);
3025     CHECK_NULL_VOID_RET_LOG(deferred_, "deferred_ is nullptr");
3026     uv_loop_s *loop = nullptr;
3027     napi_get_uv_event_loop(env_, &loop);
3028     if (loop == nullptr) {
3029         LOGE("get loop fail");
3030         return;
3031     }
3032     uv_work_t *work = new (std::nothrow) uv_work_t;
3033     if (work == nullptr) {
3034         LOGE("OnResult, No memory");
3035         return;
3036     }
3037     auto *jsCallback = new DeviceIconInfoAsyncCallbackInfo();
3038     if (jsCallback == nullptr) {
3039         LOGE("create jsCallback fail");
3040         DeleteUvWork(work);
3041         return;
3042     }
3043     jsCallback->env = env_;
3044     jsCallback->bundleName = bundleName_;
3045     jsCallback->deferred = deferred_;
3046     jsCallback->deviceIconInfo = deviceIconInfo;
3047     jsCallback->code = code;
3048     work->data = reinterpret_cast<void *>(jsCallback);
3049     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
3050             LOGD("OnResult uv_queue_work_with_qos");
3051     },  [] (uv_work_t *work, int status) {
3052         DeviceIconInfoAsyncCallbackInfo *callback =
3053             reinterpret_cast<DeviceIconInfoAsyncCallbackInfo *>(work->data);
3054         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName);
3055         if (deviceManagerNapi == nullptr) {
3056             LOGE("deviceManagerNapi not find for bundleName %{public}s", callback->bundleName.c_str());
3057         } else {
3058             deviceManagerNapi->OnGetDeviceIconInfoCallbackResult(callback);
3059         }
3060         delete callback;
3061         callback = nullptr;
3062         DeleteUvWork(work);
3063     }, uv_qos_user_initiated);
3064     if (ret != 0) {
3065         LOGE("Failed to execute OnBindResult work queue");
3066         delete jsCallback;
3067         jsCallback = nullptr;
3068         DeleteUvWork(work);
3069     }
3070 }
3071 
OnResult(int32_t code)3072 void DmNapiSetLocalDeviceNameCallback::OnResult(int32_t code)
3073 {
3074     LOGI("In code:%{public}d", code);
3075     CHECK_NULL_VOID_RET_LOG(deferred_, "deferred_ is nullptr");
3076     uv_loop_s *loop = nullptr;
3077     napi_get_uv_event_loop(env_, &loop);
3078     if (loop == nullptr) {
3079         LOGE("get loop fail");
3080         return;
3081     }
3082     uv_work_t *work = new (std::nothrow) uv_work_t;
3083     if (work == nullptr) {
3084         LOGE("OnResult, No memory");
3085         return;
3086     }
3087     auto *jsCallback = new SetLocalDeviceNameAsyncCallbackInfo();
3088     if (jsCallback == nullptr) {
3089         LOGE("create jsCallback fail");
3090         DeleteUvWork(work);
3091         return;
3092     }
3093     jsCallback->env = env_;
3094     jsCallback->bundleName = bundleName_;
3095     jsCallback->deferred = deferred_;
3096     jsCallback->code = code;
3097     work->data = reinterpret_cast<void *>(jsCallback);
3098     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
3099             LOGD("OnResult uv_queue_work_with_qos");
3100     },  [] (uv_work_t *work, int status) {
3101         SetLocalDeviceNameAsyncCallbackInfo *callback =
3102             reinterpret_cast<SetLocalDeviceNameAsyncCallbackInfo *>(work->data);
3103         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName);
3104         if (deviceManagerNapi == nullptr) {
3105             LOGE("deviceManagerNapi not find for bundleName %{public}s", callback->bundleName.c_str());
3106         } else {
3107             deviceManagerNapi->OnSetLocalDeviceNameCallbackResult(callback);
3108         }
3109         delete callback;
3110         callback = nullptr;
3111         DeleteUvWork(work);
3112     }, uv_qos_user_initiated);
3113     if (ret != 0) {
3114         LOGE("Failed to execute OnBindResult work queue");
3115         delete jsCallback;
3116         jsCallback = nullptr;
3117         DeleteUvWork(work);
3118     }
3119 }
3120 
OnResult(int32_t code)3121 void DmNapiSetRemoteDeviceNameCallback::OnResult(int32_t code)
3122 {
3123     LOGI("In code:%{public}d", code);
3124     CHECK_NULL_VOID_RET_LOG(deferred_, "deferred_ is nullptr");
3125     uv_loop_s *loop = nullptr;
3126     napi_get_uv_event_loop(env_, &loop);
3127     if (loop == nullptr) {
3128         LOGE("get loop fail");
3129         return;
3130     }
3131     uv_work_t *work = new (std::nothrow) uv_work_t;
3132     if (work == nullptr) {
3133         LOGE("OnResult, No memory");
3134         return;
3135     }
3136     auto *jsCallback = new SetRemoteDeviceNameAsyncCallbackInfo();
3137     if (jsCallback == nullptr) {
3138         LOGE("create jsCallback fail");
3139         DeleteUvWork(work);
3140         return;
3141     }
3142     jsCallback->env = env_;
3143     jsCallback->bundleName = bundleName_;
3144     jsCallback->deferred = deferred_;
3145     jsCallback->code = code;
3146     work->data = reinterpret_cast<void *>(jsCallback);
3147     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {
3148             LOGD("OnResult uv_queue_work_with_qos");
3149     },  [] (uv_work_t *work, int status) {
3150         SetRemoteDeviceNameAsyncCallbackInfo *callback =
3151             reinterpret_cast<SetRemoteDeviceNameAsyncCallbackInfo *>(work->data);
3152         DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(callback->bundleName);
3153         if (deviceManagerNapi == nullptr) {
3154             LOGE("deviceManagerNapi not find for bundleName %{public}s", callback->bundleName.c_str());
3155         } else {
3156             deviceManagerNapi->OnSetRemoteDeviceNameCallbackResult(callback);
3157         }
3158         delete callback;
3159         callback = nullptr;
3160         DeleteUvWork(work);
3161     }, uv_qos_user_initiated);
3162     if (ret != 0) {
3163         LOGE("Failed to execute OnBindResult work queue");
3164         delete jsCallback;
3165         jsCallback = nullptr;
3166         DeleteUvWork(work);
3167     }
3168 }
3169