1 /*
2 * Copyright (C) 2021-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 #include "bluetooth_hfp_ag.h"
16 #include "napi_bluetooth_hfp_ag.h"
17 #include "napi_bluetooth_profile.h"
18
19 namespace OHOS {
20 namespace Bluetooth {
21 using namespace std;
22
23 NapiHandsFreeAudioGatewayObserver NapiHandsFreeAudioGateway::observer_;
24 bool NapiHandsFreeAudioGateway::isRegistered_ = false;
25
DefineHandsFreeAudioGatewayJSClass(napi_env env)26 void NapiHandsFreeAudioGateway::DefineHandsFreeAudioGatewayJSClass(napi_env env)
27 {
28
29 napi_value constructor;
30 napi_property_descriptor properties[] = {
31 DECLARE_NAPI_FUNCTION("getConnectionDevices", GetConnectionDevices),
32 DECLARE_NAPI_FUNCTION("getDeviceState", GetDeviceState),
33 DECLARE_NAPI_FUNCTION("connect", Connect),
34 DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
35 DECLARE_NAPI_FUNCTION("getScoState", GetScoState),
36 DECLARE_NAPI_FUNCTION("connectSco", ConnectSco),
37 DECLARE_NAPI_FUNCTION("disconnectSco", DisconnectSco),
38 DECLARE_NAPI_FUNCTION("on", On),
39 DECLARE_NAPI_FUNCTION("off", Off),
40 DECLARE_NAPI_FUNCTION("openVoiceRecognition", OpenVoiceRecognition),
41 DECLARE_NAPI_FUNCTION("closeVoiceRecognition", CloseVoiceRecognition),
42 };
43
44 napi_define_class(env, "HandsFreeAudioGateway", NAPI_AUTO_LENGTH, HandsFreeAudioGatewayConstructor, 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(ProfileCode::CODE_BT_PROFILE_HANDS_FREE_AUDIO_GATEWAY, napiProfile);
50 HILOGI("DefineHandsFreeAudioGatewayJSClass finished");
51 }
52
HandsFreeAudioGatewayConstructor(napi_env env,napi_callback_info info)53 napi_value NapiHandsFreeAudioGateway::HandsFreeAudioGatewayConstructor(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 NapiHandsFreeAudioGateway::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<BluetoothCallbackInfo> callbackInfo = std::make_shared<BluetoothCallbackInfo>();
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
94 if (!isRegistered_) {
95 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
96 profile->RegisterObserver(&observer_);
97 isRegistered_ = true;
98 }
99
100 return ret;
101 }
102
Off(napi_env env,napi_callback_info info)103 napi_value NapiHandsFreeAudioGateway::Off(napi_env env, napi_callback_info info)
104 {
105 HILOGI("Off called");
106 size_t expectedArgsCount = ARGS_SIZE_ONE;
107 size_t argc = expectedArgsCount;
108 napi_value argv[ARGS_SIZE_ONE] = {0};
109 napi_value thisVar = nullptr;
110
111 napi_value ret = nullptr;
112 napi_get_undefined(env, &ret);
113
114 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
115 if (argc != expectedArgsCount) {
116 HILOGE("Requires 1 argument.");
117 return ret;
118 }
119 string type;
120 if (!ParseString(env, type, argv[PARAM0])) {
121 HILOGE("string expected.");
122 return ret;
123 }
124 observer_.callbackInfos_[type] = nullptr;
125
126 HILOGI("%{public}s is unregistered", type.c_str());
127
128 return ret;
129 }
130
GetConnectionDevices(napi_env env,napi_callback_info info)131 napi_value NapiHandsFreeAudioGateway::GetConnectionDevices(napi_env env, napi_callback_info info)
132 {
133
134 HILOGI("GetConnectionDevices called");
135 napi_value ret = nullptr;
136 napi_create_array(env, &ret);
137 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
138 vector<BluetoothRemoteDevice> devices = profile->GetConnectedDevices();
139 vector<string> deviceVector;
140 for (auto &device: devices) {
141 deviceVector.push_back(device.GetDeviceAddr());
142 }
143 ConvertStringVectorToJS(env, ret, deviceVector);
144 return ret;
145 }
146
GetDeviceState(napi_env env,napi_callback_info info)147 napi_value NapiHandsFreeAudioGateway::GetDeviceState(napi_env env, napi_callback_info info)
148 {
149 HILOGI("GetDeviceState called");
150
151 size_t expectedArgsCount = ARGS_SIZE_ONE;
152 size_t argc = expectedArgsCount;
153 napi_value argv[ARGS_SIZE_ONE] = {0};
154 napi_value thisVar = nullptr;
155
156 napi_value ret = nullptr;
157 napi_get_undefined(env, &ret);
158
159 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
160 if (argc != expectedArgsCount) {
161 HILOGE("Requires 1 argument.");
162 return ret;
163 }
164 string deviceId;
165 if (!ParseString(env, deviceId, argv[PARAM0])) {
166 HILOGE("string expected.");
167 return ret;
168 }
169
170 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
171 BluetoothRemoteDevice device(deviceId, 1);
172 int state = profile->GetDeviceState(device);
173 napi_value result = nullptr;
174 napi_create_int32(env, GetProfileConnectionState(state), &result);
175 return result;
176 }
177
GetScoState(napi_env env,napi_callback_info info)178 napi_value NapiHandsFreeAudioGateway::GetScoState(napi_env env, napi_callback_info info)
179 {
180 HILOGI("GetScoState called");
181
182 size_t expectedArgsCount = ARGS_SIZE_ONE;
183 size_t argc = expectedArgsCount;
184 napi_value argv[ARGS_SIZE_ONE] = {0};
185 napi_value thisVar = nullptr;
186
187 napi_value ret = nullptr;
188 napi_get_undefined(env, &ret);
189
190 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
191 if (argc != expectedArgsCount) {
192 HILOGE("Requires 1 argument.");
193 return ret;
194 }
195 string deviceId;
196 if (!ParseString(env, deviceId, argv[PARAM0])) {
197 HILOGE("string expected.");
198 return ret;
199 }
200
201 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
202 BluetoothRemoteDevice device(deviceId, 1);
203 int state = profile->GetScoState(device);
204 napi_value result = nullptr;
205 napi_create_int32(env, GetScoConnectionState(state), &result);
206 return result;
207 }
208
ConnectSco(napi_env env,napi_callback_info info)209 napi_value NapiHandsFreeAudioGateway::ConnectSco(napi_env env, napi_callback_info info)
210 {
211 HILOGI("ConnectSco called");
212
213 size_t expectedArgsCount = ARGS_SIZE_ONE;
214 size_t argc = expectedArgsCount;
215 napi_value argv[ARGS_SIZE_ONE] = {0};
216 napi_value thisVar = nullptr;
217
218 napi_value ret = nullptr;
219 napi_get_undefined(env, &ret);
220
221 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
222 if (argc != expectedArgsCount) {
223 HILOGE("Requires 1 argument.");
224 return ret;
225 }
226 string deviceId;
227 if (!ParseString(env, deviceId, argv[PARAM0])) {
228 HILOGE("string expected.");
229 return ret;
230 }
231
232 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
233 BluetoothRemoteDevice device(deviceId, 1);
234 bool isOK = profile->SetActiveDevice(device);
235 if (isOK) {
236 isOK = profile->ConnectSco();
237 }
238 napi_value result = nullptr;
239 napi_get_boolean(env, isOK, &result);
240 return result;
241 }
242
DisconnectSco(napi_env env,napi_callback_info info)243 napi_value NapiHandsFreeAudioGateway::DisconnectSco(napi_env env, napi_callback_info info)
244 {
245 HILOGI("DisconnectSco called");
246
247 size_t expectedArgsCount = ARGS_SIZE_ONE;
248 size_t argc = expectedArgsCount;
249 napi_value argv[ARGS_SIZE_ONE] = {0};
250 napi_value thisVar = nullptr;
251
252 napi_value ret = nullptr;
253 napi_get_undefined(env, &ret);
254
255 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
256 if (argc != expectedArgsCount) {
257 HILOGE("Requires 1 argument.");
258 return ret;
259 }
260 string deviceId;
261 if (!ParseString(env, deviceId, argv[PARAM0])) {
262 HILOGE("string expected.");
263 return ret;
264 }
265
266 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
267 BluetoothRemoteDevice device(deviceId, 1);
268 bool isOK = profile->SetActiveDevice(device);
269 if (isOK) {
270 isOK = profile->DisconnectSco();
271 }
272 napi_value result = nullptr;
273 napi_get_boolean(env, isOK, &result);
274 return result;
275 }
276
OpenVoiceRecognition(napi_env env,napi_callback_info info)277 napi_value NapiHandsFreeAudioGateway::OpenVoiceRecognition(napi_env env, napi_callback_info info)
278 {
279 HILOGI("OpenVoiceRecognition called");
280
281 size_t expectedArgsCount = ARGS_SIZE_ONE;
282 size_t argc = expectedArgsCount;
283 napi_value argv[ARGS_SIZE_ONE] = {0};
284 napi_value thisVar = nullptr;
285
286 napi_value ret = nullptr;
287 napi_get_undefined(env, &ret);
288
289 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
290 if (argc != expectedArgsCount) {
291 HILOGE("Requires 1 argument.");
292 return ret;
293 }
294 string deviceId;
295 if (!ParseString(env, deviceId, argv[PARAM0])) {
296 HILOGE("string expected.");
297 return ret;
298 }
299
300 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
301 BluetoothRemoteDevice device(deviceId, 1);
302 bool isOK = profile->OpenVoiceRecognition(device);
303 napi_value result = nullptr;
304 napi_get_boolean(env, isOK, &result);
305 return result;
306 }
307
CloseVoiceRecognition(napi_env env,napi_callback_info info)308 napi_value NapiHandsFreeAudioGateway::CloseVoiceRecognition(napi_env env, napi_callback_info info)
309 {
310 HILOGI("CloseVoiceRecognition called");
311
312 size_t expectedArgsCount = ARGS_SIZE_ONE;
313 size_t argc = expectedArgsCount;
314 napi_value argv[ARGS_SIZE_ONE] = {0};
315 napi_value thisVar = nullptr;
316
317 napi_value ret = nullptr;
318 napi_get_undefined(env, &ret);
319
320 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
321 if (argc != expectedArgsCount) {
322 HILOGE("Requires 1 argument.");
323 return ret;
324 }
325 string deviceId;
326 if (!ParseString(env, deviceId, argv[PARAM0])) {
327 HILOGE("string expected.");
328 return ret;
329 }
330
331 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
332 BluetoothRemoteDevice device(deviceId, 1);
333 bool isOK = profile->CloseVoiceRecognition(device);
334 napi_value result = nullptr;
335 napi_get_boolean(env, isOK, &result);
336 return result;
337 }
338
Connect(napi_env env,napi_callback_info info)339 napi_value NapiHandsFreeAudioGateway::Connect(napi_env env, napi_callback_info info)
340 {
341 HILOGI("Connect called");
342
343 size_t expectedArgsCount = ARGS_SIZE_ONE;
344 size_t argc = expectedArgsCount;
345 napi_value argv[ARGS_SIZE_ONE] = {0};
346 napi_value thisVar = nullptr;
347
348 napi_value ret = nullptr;
349 napi_get_undefined(env, &ret);
350
351 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
352 if (argc != expectedArgsCount) {
353 HILOGE("Requires 1 argument.");
354 return ret;
355 }
356 string deviceId;
357 if (!ParseString(env, deviceId, argv[PARAM0])) {
358 HILOGE("string expected.");
359 return ret;
360 }
361
362 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
363 BluetoothRemoteDevice device(deviceId, 1);
364 bool res = profile->Connect(device);
365
366 napi_value result = nullptr;
367 napi_get_boolean(env, res, &result);
368 return result;
369 }
370
Disconnect(napi_env env,napi_callback_info info)371 napi_value NapiHandsFreeAudioGateway::Disconnect(napi_env env, napi_callback_info info)
372 {
373 HILOGI("Disconnect called");
374
375 size_t expectedArgsCount = ARGS_SIZE_ONE;
376 size_t argc = expectedArgsCount;
377 napi_value argv[ARGS_SIZE_ONE] = {0};
378 napi_value thisVar = nullptr;
379
380 napi_value ret = nullptr;
381 napi_get_undefined(env, &ret);
382
383 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
384 if (argc != expectedArgsCount) {
385 HILOGE("Requires 1 argument.");
386 return ret;
387 }
388 string deviceId;
389 if (!ParseString(env, deviceId, argv[PARAM0])) {
390 HILOGE("string expected.");
391 return ret;
392 }
393
394 HandsFreeAudioGateway *profile = HandsFreeAudioGateway::GetProfile();
395 BluetoothRemoteDevice device(deviceId, 1);
396 bool res = profile->Disconnect(device);
397
398 napi_value result = nullptr;
399 napi_get_boolean(env, res, &result);
400 return result;
401 }
402 } // namespace Bluetooth
403 } // namespace OHOS