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