• 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 "bluetooth_opp.h"
17 #include "bluetooth_log.h"
18 #include "napi_bluetooth_opp_observer.h"
19 #include "napi_bluetooth_utils.h"
20 #include "napi_bluetooth_profile.h"
21 #include "napi_bluetooth_opp.h"
22 
23 namespace OHOS {
24 namespace Bluetooth {
25 using namespace std;
26 NapiBluetoothOppObserver NapiBluetoothOpp::observer_;
27 bool NapiBluetoothOpp::isRegistered_ = false;
28 
DefineOppJSClass(napi_env env)29 void NapiBluetoothOpp::DefineOppJSClass(napi_env env)
30 {
31     HILOGI("NapiBluetoothOpp::DefineOppJSClass called");
32     napi_value constructor;
33     napi_property_descriptor properties[] = {
34         DECLARE_NAPI_FUNCTION("on", NapiBluetoothOpp::On),
35         DECLARE_NAPI_FUNCTION("off", NapiBluetoothOpp::Off),
36         DECLARE_NAPI_FUNCTION("sendFile", NapiBluetoothOpp::SendFile),
37         DECLARE_NAPI_FUNCTION("setIncomingFileConfirmation", NapiBluetoothOpp::SetIncomingFileConfirmation),
38         DECLARE_NAPI_FUNCTION("getCurrentTransferInformation", NapiBluetoothOpp::GetCurrentTransferInformation),
39         DECLARE_NAPI_FUNCTION("cancelTransfer", NapiBluetoothOpp::CancelTransfer),
40         DECLARE_NAPI_FUNCTION("getConnectionDevices", GetConnectionDevices),
41         DECLARE_NAPI_FUNCTION("getDeviceState", GetDeviceState),
42     };
43 
44     napi_define_class(env, "NapiBluetoothOpp", NAPI_AUTO_LENGTH, NapiBluetoothOpp::OppConstructor, nullptr,
45         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
46 
47     napi_value napiProfile;
48     napi_new_instance(env, constructor, 0, nullptr, &napiProfile);
49     NapiProfile::SetProfile(env, ProfileId::PROFILE_OPP, napiProfile);
50     Opp *profile = Opp::GetProfile();
51     profile->RegisterObserver(&observer_);
52     HILOGI("DefineOppJSClass finished");
53 }
54 
OppConstructor(napi_env env,napi_callback_info info)55 napi_value NapiBluetoothOpp::OppConstructor(napi_env env, napi_callback_info info)
56 {
57     napi_value thisVar = nullptr;
58     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
59     return thisVar;
60 }
61 
On(napi_env env,napi_callback_info info)62 napi_value NapiBluetoothOpp::On(napi_env env, napi_callback_info info)
63 {
64     HILOGI("On called");
65     size_t expectedArgsCount = ARGS_SIZE_TWO;
66     size_t argc = expectedArgsCount;
67     napi_value argv[ARGS_SIZE_TWO] = {0};
68     napi_value thisVar = nullptr;
69 
70     napi_value ret = nullptr;
71     napi_get_undefined(env, &ret);
72 
73     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
74     if (argc != expectedArgsCount) {
75         HILOGE("Requires 2 argument.");
76         return ret;
77     }
78     string type;
79     if (!ParseString(env, type, argv[PARAM0])) {
80         HILOGE("string expected.");
81         return ret;
82     }
83     std::shared_ptr<TransforInformationCallbackInfo> callbackInfo = std::make_shared<TransforInformationCallbackInfo>();
84     callbackInfo->env_ = env;
85 
86     napi_valuetype valueType = napi_undefined;
87     napi_typeof(env, argv[PARAM1], &valueType);
88     if (valueType != napi_function) {
89         HILOGE("Wrong argument type. Function expected.");
90         return ret;
91     }
92     napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
93     observer_.callbackInfos_[type] = callbackInfo;
94     HILOGI("%{public}s is registered", type.c_str());
95     return ret;
96 }
97 
Off(napi_env env,napi_callback_info info)98 napi_value NapiBluetoothOpp::Off(napi_env env, napi_callback_info info)
99 {
100     HILOGI("Off called");
101     size_t expectedArgsCount = ARGS_SIZE_ONE;
102     size_t argc = expectedArgsCount;
103     napi_value argv[ARGS_SIZE_ONE] = {0};
104     napi_value thisVar = nullptr;
105 
106     napi_value ret = nullptr;
107     napi_get_undefined(env, &ret);
108 
109     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
110     if (argc != expectedArgsCount) {
111         HILOGE("Requires 1 argument.");
112         return ret;
113     }
114     string type;
115     if (!ParseString(env, type, argv[PARAM0])) {
116         HILOGE("string expected.");
117         return ret;
118     }
119 
120     if (observer_.callbackInfos_[type] != nullptr) {
121         std::shared_ptr<BluetoothCallbackInfo> callbackInfo = observer_.callbackInfos_[type];
122         napi_delete_reference(env, callbackInfo->callback_);
123     }
124     observer_.callbackInfos_[type] = nullptr;
125     HILOGI("%{public}s is unregistered", type.c_str());
126     return ret;
127 }
128 
ParseStringArrayParameters(const napi_env & env,napi_value & args,std::vector<std::string> & params)129 static bool ParseStringArrayParameters(const napi_env &env, napi_value &args, std::vector<std::string> &params)
130 {
131     HILOGI("%{public}s, enter", __func__);
132     if (args == nullptr) {
133         return NapiGetNull(env);
134     }
135 
136     bool isArray = false;
137     std::string fileParam;
138     napi_is_array(env, args, &isArray);
139     if (isArray) {
140         uint32_t length = 0;
141         napi_get_array_length(env, args, &length);
142         for (size_t i = 0; i < length; i++) {
143             napi_value result;
144             napi_get_element(env, args, i, &result);
145             if (!ParseString(env, fileParam, result)) {
146                 return false;
147             }
148             params.push_back(fileParam);
149         }
150     } else {
151         return false;
152     }
153     return true;
154 }
155 
SendFile(napi_env env,napi_callback_info info)156 napi_value NapiBluetoothOpp::SendFile(napi_env env, napi_callback_info info)
157 {
158     HILOGI("SendFile called");
159 
160     size_t expectedArgsCount = ARGS_SIZE_THREE;
161     size_t argc = expectedArgsCount;
162     napi_value argv[ARGS_SIZE_THREE] = {};
163     napi_value thisVar = nullptr;
164 
165     napi_value ret = nullptr;
166     napi_get_undefined(env, &ret);
167 
168     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
169     if (argc != expectedArgsCount) {
170         HILOGE("Requires 3 argument.");
171         return ret;
172     }
173     std::string device;
174     if (!ParseString(env, device, argv[PARAM0])) {
175         HILOGE("string expected.");
176         return ret;
177     }
178     std::vector<std::string> filePaths;
179     if (argv[PARAM1] != nullptr) {
180         if (!ParseStringArrayParameters(env, argv[PARAM1], filePaths)) {
181             return ret;
182         }
183     }
184     std::vector<std::string> mimeTypes;
185     if (argv[PARAM2] != nullptr) {
186         if (!ParseStringArrayParameters(env, argv[PARAM2], mimeTypes)) {
187             return ret;
188         }
189     }
190     Opp *profile = Opp::GetProfile();
191     bool isOK = profile->SendFile(device, filePaths, mimeTypes);
192     napi_value result = nullptr;
193     napi_get_boolean(env, isOK, &result);
194     return result;
195 }
196 
SetIncomingFileConfirmation(napi_env env,napi_callback_info info)197 napi_value NapiBluetoothOpp::SetIncomingFileConfirmation(napi_env env, napi_callback_info info)
198 {
199     HILOGI("SetIncomingFileConfirmation called");
200 
201     size_t expectedArgsCount = ARGS_SIZE_ONE;
202     size_t argc = expectedArgsCount;
203     napi_value argv[ARGS_SIZE_ONE] = {};
204     napi_value thisVar = nullptr;
205 
206     napi_value ret = nullptr;
207     napi_get_undefined(env, &ret);
208 
209     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
210     if (argc != expectedArgsCount) {
211         HILOGE("Requires 1 argument.");
212         return ret;
213     }
214     bool accept;
215     if (!ParseBool(env, accept, argv[PARAM0])) {
216         HILOGE("Bool expected.");
217         return ret;
218     }
219     Opp *profile = Opp::GetProfile();
220     bool isOk = profile->SetIncomingFileConfirmation(accept);
221     napi_value result = nullptr;
222     napi_get_boolean(env, isOk, &result);
223     return result;
224 }
225 
GetCurrentTransferInformation(napi_env env,napi_callback_info info)226 napi_value NapiBluetoothOpp::GetCurrentTransferInformation(napi_env env, napi_callback_info info)
227 {
228     HILOGI("GetCurrentTransferInformation called");
229 
230     size_t expectedArgsCount = ARGS_SIZE_ZERO;
231     size_t argc = expectedArgsCount;
232     napi_value argv[ARGS_SIZE_ZERO] = {};
233     napi_value thisVar = nullptr;
234 
235     napi_value ret = nullptr;
236     napi_get_undefined(env, &ret);
237 
238     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
239     if (argc != expectedArgsCount) {
240         HILOGE("No Requires argument.");
241         return ret;
242     }
243     Opp *profile = Opp::GetProfile();
244     BluetoothOppTransferInformation information = profile->GetCurrentTransferInformation();
245     napi_value obj = nullptr;
246     napi_create_object(env, &obj);
247     ConvertOppTransferInformationToJS(env, obj, information);
248     return obj;
249 }
250 
CancelTransfer(napi_env env,napi_callback_info info)251 napi_value NapiBluetoothOpp::CancelTransfer(napi_env env, napi_callback_info info)
252 {
253     HILOGI("CancelTransfer called");
254 
255     size_t expectedArgsCount = ARGS_SIZE_ZERO;
256     size_t argc = expectedArgsCount;
257     napi_value argv[ARGS_SIZE_ZERO] = {};
258     napi_value thisVar = nullptr;
259 
260     napi_value ret = nullptr;
261     napi_get_undefined(env, &ret);
262 
263     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
264     if (argc != expectedArgsCount) {
265         HILOGE("No Requires argument.");
266         return ret;
267     }
268     Opp *profile = Opp::GetProfile();
269     bool isOk = profile->CancelTransfer();
270     napi_value result = nullptr;
271     napi_get_boolean(env, isOk, &result);
272     return result;
273 }
274 
GetConnectionDevices(napi_env env,napi_callback_info info)275 napi_value NapiBluetoothOpp::GetConnectionDevices(napi_env env, napi_callback_info info)
276 {
277     HILOGI("GetConnectionDevices called");
278 
279     size_t expectedArgsCount = ARGS_SIZE_ZERO;
280     size_t argc = expectedArgsCount;
281     napi_value argv[ARGS_SIZE_ZERO] = {};
282     napi_value thisVar = nullptr;
283 
284     napi_value ret = nullptr;
285     napi_get_undefined(env, &ret);
286 
287     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
288     if (argc != expectedArgsCount) {
289         HILOGE("No Requires argument.");
290         return ret;
291     }
292     napi_create_array(env, &ret);
293     Opp *profile = Opp::GetProfile();
294     vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
295     vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
296     vector<string> deviceVector;
297     for (auto &device : devices) {
298         deviceVector.push_back(device.GetDeviceAddr());
299     }
300     ConvertStringVectorToJS(env, ret, deviceVector);
301     return ret;
302 }
303 
GetDeviceState(napi_env env,napi_callback_info info)304 napi_value NapiBluetoothOpp::GetDeviceState(napi_env env, napi_callback_info info)
305 {
306     HILOGI("GetDeviceState called");
307     size_t expectedArgsCount = ARGS_SIZE_ONE;
308     size_t argc = expectedArgsCount;
309     napi_value argv[ARGS_SIZE_ONE] = {0};
310     napi_value thisVar = nullptr;
311 
312     napi_value ret = nullptr;
313     napi_get_undefined(env, &ret);
314 
315     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
316     if (argc != expectedArgsCount) {
317         HILOGE("Requires 1 argument.");
318         return ret;
319     }
320     string deviceId;
321     if (!ParseString(env, deviceId, argv[PARAM0])) {
322         HILOGE("string expected.");
323         return ret;
324     }
325 
326     Opp *profile = Opp::GetProfile();
327     BluetoothRemoteDevice device(deviceId, 1);
328     int state = profile->GetDeviceState(device);
329     int profileState = GetProfileConnectionState(state);
330     napi_value result = nullptr;
331     napi_create_int32(env, profileState, &result);
332     return result;
333 }
334 }  // namespace Bluetooth
335 }  // namespace OHOS