• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "scan_callback.h"
17 #include "napi/native_node_api.h"
18 #include "napi_scan_utils.h"
19 #include "scan_log.h"
20 #include "scanner_info_helper.h"
21 
22 namespace OHOS::Scan {
ScanCallback(napi_env env,napi_ref ref)23 ScanCallback::ScanCallback(napi_env env, napi_ref ref) : env_(env), ref_(ref), callbackFunction_(nullptr)
24 {
25 }
26 
ScanCallback(std::function<void (std::vector<ScanDeviceInfo> & infos)> callbackFunction)27 ScanCallback::ScanCallback(std::function<void(std::vector<ScanDeviceInfo> &infos)>
28     callbackFunction) : env_(nullptr), ref_(nullptr), callbackFunction_(callbackFunction)
29 {
30 }
31 
~ScanCallback()32 ScanCallback::~ScanCallback()
33 {
34     std::lock_guard<std::mutex> autoLock(mutex_);
35     if (env_ == nullptr || ref_ == nullptr) {
36         return;
37     }
38     SCAN_HILOGI("callback has been destroyed");
39     Param *param = new (std::nothrow) Param;
40     if (param == nullptr) {
41         return;
42     }
43     param->env = env_;
44     param->callbackRef = ref_;
45     auto task = [param]() {
46         SCAN_HILOGI("napi_send_event ScanCallback DeleteReference");
47         if (param == nullptr) {
48             return;
49         }
50         napi_handle_scope scope = nullptr;
51         napi_open_handle_scope(param->env, &scope);
52         if (scope == nullptr) {
53             delete param;
54             return;
55         }
56         napi_ref callbackRef = param->callbackRef;
57         NapiScanUtils::DeleteReference(param->env, callbackRef);
58         napi_close_handle_scope(param->env, scope);
59         delete param;
60     };
61     if (napi_send_event(env_, task, napi_eprio_low) != napi_ok) {
62         SCAN_HILOGE("Failed to send event");
63         delete param;
64     }
65 }
66 
InitialCallbackParam(napi_env & env_,napi_ref & ref_,std::mutex & mutex_)67 void CallbackParam::InitialCallbackParam(napi_env &env_, napi_ref &ref_, std::mutex &mutex_)
68 {
69     std::lock_guard<std::mutex> lock(mutex_);
70     this->env = env_;
71     this->ref = ref_;
72     this->mutexPtr = &mutex_;
73 }
74 
SetCallbackParam(uint32_t & state,const ScanDeviceInfo & deviceInfo)75 void CallbackParam::SetCallbackParam(uint32_t &state, const ScanDeviceInfo &deviceInfo)
76 {
77     this->state = state;
78     this->deviceInfo = deviceInfo;
79 }
80 
SetCallbackSyncParam(uint32_t & state,const ScanDeviceInfoSync & deviceInfoSync)81 void CallbackParam::SetCallbackSyncParam(uint32_t &state, const ScanDeviceInfoSync &deviceInfoSync)
82 {
83     this->state = state;
84     this->deviceInfoSync = deviceInfoSync;
85 }
86 
ExecuteNapiEventWork(CallbackParam * param,std::function<void (CallbackParam *)> workFunc)87 bool ScanCallback::ExecuteNapiEventWork(CallbackParam* param, std::function<void(CallbackParam*)> workFunc)
88 {
89     auto task = [param, workFunc]() {
90         if (param == nullptr) {
91             SCAN_HILOGE("param is a nullptr");
92             return;
93         }
94         napi_handle_scope scope = nullptr;
95         napi_open_handle_scope(param->env, &scope);
96         if (scope == nullptr) {
97             delete param;
98             return;
99         }
100         std::lock_guard<std::mutex> autoLock(*param->mutexPtr);
101         napi_value callbackFunc = NapiScanUtils::GetReference(param->env, param->ref);
102         if (callbackFunc != nullptr) {
103             workFunc(param);
104             SCAN_HILOGD("run napi call deviceInfo callback fun success");
105         } else {
106             SCAN_HILOGE("get reference failed");
107         }
108         napi_close_handle_scope(param->env, scope);
109         delete param;
110     };
111 
112     napi_status ret = napi_send_event(env_, task, napi_eprio_immediate);
113     if (ret != napi_ok) {
114         SCAN_HILOGE("napi_send_event fail");
115         delete param;
116         return false;
117     }
118     return true;
119 }
120 
NapiCallFunction(CallbackParam * cbParam,size_t argcCount,napi_value * callbackValues)121 void ScanCallback::NapiCallFunction(CallbackParam* cbParam, size_t argcCount, napi_value* callbackValues)
122 {
123     if (cbParam == nullptr) {
124         SCAN_HILOGE("cbParam is a nullptr");
125         return;
126     }
127     napi_value callbackFunc = NapiScanUtils::GetReference(cbParam->env, cbParam->ref);
128     if (callbackFunc != nullptr) {
129         napi_call_function(cbParam->env, nullptr, callbackFunc,
130             argcCount, callbackValues, nullptr);
131     }
132 }
133 
OnCallback(uint32_t state,const ScanDeviceInfo & info)134 bool ScanCallback::OnCallback(uint32_t state, const ScanDeviceInfo &info)
135 {
136     SCAN_HILOGD("Enter OnCallback::ScanDeviceInfo");
137 
138     CallbackParam *param = new (std::nothrow) CallbackParam;
139     if (param == nullptr) {
140         SCAN_HILOGE("Failed to create callback parameter");
141         return false;
142     }
143 
144     param->InitialCallbackParam(env_, ref_, mutex_);
145     param->SetCallbackParam(state, info);
146 
147     auto workFunc = [this](CallbackParam* cbParam) {
148         napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 };
149         callbackValues[0] = ScannerInfoHelper::MakeJsObject(cbParam->env, cbParam->deviceInfo);
150         NapiCallFunction(cbParam, NapiScanUtils::ARGC_ONE, callbackValues);
151     };
152 
153     return ExecuteNapiEventWork(param, workFunc);
154 }
155 
OnCallbackSync(uint32_t state,const ScanDeviceInfoSync & info)156 bool ScanCallback::OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info)
157 {
158     SCAN_HILOGD("Enter OnCallback::ScanDeviceInfo");
159 
160     CallbackParam *param = new (std::nothrow) CallbackParam;
161     if (param == nullptr) {
162         SCAN_HILOGE("Failed to create callback parameter");
163         return false;
164     }
165 
166     param->InitialCallbackParam(env_, ref_, mutex_);
167     param->SetCallbackSyncParam(state, info);
168 
169     auto workFunc = [this](CallbackParam* cbParam) {
170         napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 };
171         callbackValues[0] = ScannerInfoSyncHelper::MakeJsObject(cbParam->env, cbParam->deviceInfoSync);
172         NapiCallFunction(cbParam, NapiScanUtils::ARGC_ONE, callbackValues);
173     };
174 
175     return ExecuteNapiEventWork(param, workFunc);
176 }
177 
OnGetDevicesList(std::vector<ScanDeviceInfo> & infos)178 bool ScanCallback::OnGetDevicesList(std::vector<ScanDeviceInfo> &infos)
179 {
180     SCAN_HILOGI("Enter OnGetDevicesList");
181     if (callbackFunction_ == nullptr) {
182         SCAN_HILOGE("callbackFunction_ is a nullptr");
183         return false;
184     }
185     callbackFunction_(infos);
186     return true;
187 }
188 } // namespace OHOS::Scan
189