1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "BluetoothHeadsetServiceJni"
18
19 #define LOG_NDEBUG 0
20
21 #include "android_runtime/AndroidRuntime.h"
22 #include "com_android_bluetooth.h"
23 #include "hardware/bluetooth_headset_callbacks.h"
24 #include "hardware/bluetooth_headset_interface.h"
25 #include "hardware/bt_hf.h"
26 #include "utils/Log.h"
27
28 #include <mutex>
29 #include <shared_mutex>
30
31 namespace android {
32
33 static jmethodID method_onConnectionStateChanged;
34 static jmethodID method_onAudioStateChanged;
35 static jmethodID method_onVrStateChanged;
36 static jmethodID method_onAnswerCall;
37 static jmethodID method_onHangupCall;
38 static jmethodID method_onVolumeChanged;
39 static jmethodID method_onDialCall;
40 static jmethodID method_onSendDtmf;
41 static jmethodID method_onNoiceReductionEnable;
42 static jmethodID method_onWBS;
43 static jmethodID method_onAtChld;
44 static jmethodID method_onAtCnum;
45 static jmethodID method_onAtCind;
46 static jmethodID method_onAtCops;
47 static jmethodID method_onAtClcc;
48 static jmethodID method_onUnknownAt;
49 static jmethodID method_onKeyPressed;
50 static jmethodID method_onAtBind;
51 static jmethodID method_onAtBiev;
52 static jmethodID method_onAtBia;
53
54 static bluetooth::headset::Interface* sBluetoothHfpInterface = nullptr;
55 static std::shared_timed_mutex interface_mutex;
56
57 static jobject mCallbacksObj = nullptr;
58 static std::shared_timed_mutex callbacks_mutex;
59
marshall_bda(RawAddress * bd_addr)60 static jbyteArray marshall_bda(RawAddress* bd_addr) {
61 CallbackEnv sCallbackEnv(__func__);
62 if (!sCallbackEnv.valid()) return nullptr;
63
64 jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
65 if (!addr) {
66 ALOGE("Fail to new jbyteArray bd addr");
67 return nullptr;
68 }
69 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
70 (jbyte*)bd_addr);
71 return addr;
72 }
73
74 class JniHeadsetCallbacks : bluetooth::headset::Callbacks {
75 public:
GetInstance()76 static bluetooth::headset::Callbacks* GetInstance() {
77 static bluetooth::headset::Callbacks* instance = new JniHeadsetCallbacks();
78 return instance;
79 }
80
ConnectionStateCallback(bluetooth::headset::bthf_connection_state_t state,RawAddress * bd_addr)81 void ConnectionStateCallback(
82 bluetooth::headset::bthf_connection_state_t state,
83 RawAddress* bd_addr) override {
84 ALOGI("%s %d for %s", __func__, state, bd_addr->ToString().c_str());
85
86 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
87 CallbackEnv sCallbackEnv(__func__);
88 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
89
90 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
91 if (!addr.get()) return;
92
93 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
94 (jint)state, addr.get());
95 }
96
AudioStateCallback(bluetooth::headset::bthf_audio_state_t state,RawAddress * bd_addr)97 void AudioStateCallback(bluetooth::headset::bthf_audio_state_t state,
98 RawAddress* bd_addr) override {
99 ALOGI("%s, %d for %s", __func__, state, bd_addr->ToString().c_str());
100
101 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
102 CallbackEnv sCallbackEnv(__func__);
103 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
104
105 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
106 if (!addr.get()) return;
107
108 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged,
109 (jint)state, addr.get());
110 }
111
VoiceRecognitionCallback(bluetooth::headset::bthf_vr_state_t state,RawAddress * bd_addr)112 void VoiceRecognitionCallback(bluetooth::headset::bthf_vr_state_t state,
113 RawAddress* bd_addr) override {
114 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
115 CallbackEnv sCallbackEnv(__func__);
116 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
117
118 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
119 if (!addr.get()) {
120 ALOGE("Fail to new jbyteArray bd addr for audio state");
121 return;
122 }
123
124 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged,
125 (jint)state, addr.get());
126 }
127
AnswerCallCallback(RawAddress * bd_addr)128 void AnswerCallCallback(RawAddress* bd_addr) override {
129 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
130 CallbackEnv sCallbackEnv(__func__);
131 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
132
133 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
134 if (!addr.get()) {
135 ALOGE("Fail to new jbyteArray bd addr for audio state");
136 return;
137 }
138
139 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall,
140 addr.get());
141 }
142
HangupCallCallback(RawAddress * bd_addr)143 void HangupCallCallback(RawAddress* bd_addr) override {
144 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
145 CallbackEnv sCallbackEnv(__func__);
146 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
147
148 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
149 if (!addr.get()) {
150 ALOGE("Fail to new jbyteArray bd addr for audio state");
151 return;
152 }
153
154 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall,
155 addr.get());
156 }
157
VolumeControlCallback(bluetooth::headset::bthf_volume_type_t type,int volume,RawAddress * bd_addr)158 void VolumeControlCallback(bluetooth::headset::bthf_volume_type_t type,
159 int volume, RawAddress* bd_addr) override {
160 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
161 CallbackEnv sCallbackEnv(__func__);
162 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
163
164 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
165 if (!addr.get()) {
166 ALOGE("Fail to new jbyteArray bd addr for audio state");
167 return;
168 }
169
170 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged,
171 (jint)type, (jint)volume, addr.get());
172 }
173
DialCallCallback(char * number,RawAddress * bd_addr)174 void DialCallCallback(char* number, RawAddress* bd_addr) override {
175 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
176 CallbackEnv sCallbackEnv(__func__);
177 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
178
179 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
180 if (!addr.get()) {
181 ALOGE("Fail to new jbyteArray bd addr for audio state");
182 return;
183 }
184
185 ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
186 sCallbackEnv->NewStringUTF(number));
187 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
188 js_number.get(), addr.get());
189 }
190
DtmfCmdCallback(char dtmf,RawAddress * bd_addr)191 void DtmfCmdCallback(char dtmf, RawAddress* bd_addr) override {
192 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
193 CallbackEnv sCallbackEnv(__func__);
194 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
195
196 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
197 if (!addr.get()) {
198 ALOGE("Fail to new jbyteArray bd addr for audio state");
199 return;
200 }
201
202 // TBD dtmf has changed from int to char
203 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf,
204 addr.get());
205 }
206
NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec,RawAddress * bd_addr)207 void NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec,
208 RawAddress* bd_addr) override {
209 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
210 CallbackEnv sCallbackEnv(__func__);
211 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
212
213 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
214 if (!addr.get()) {
215 ALOGE("Fail to new jbyteArray bd addr for audio state");
216 return;
217 }
218 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiceReductionEnable,
219 nrec == bluetooth::headset::BTHF_NREC_START,
220 addr.get());
221 }
222
WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config,RawAddress * bd_addr)223 void WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config,
224 RawAddress* bd_addr) override {
225 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
226 CallbackEnv sCallbackEnv(__func__);
227 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
228
229 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
230 if (addr.get() == nullptr) return;
231
232 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config,
233 addr.get());
234 }
235
AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,RawAddress * bd_addr)236 void AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,
237 RawAddress* bd_addr) override {
238 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
239 CallbackEnv sCallbackEnv(__func__);
240 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
241
242 ScopedLocalRef<jbyteArray> addr(
243 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
244 if (!addr.get()) {
245 ALOGE("Fail to new jbyteArray bd addr for audio state");
246 return;
247 }
248
249 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
250 (jbyte*)bd_addr);
251 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld,
252 addr.get());
253 }
254
AtCnumCallback(RawAddress * bd_addr)255 void AtCnumCallback(RawAddress* bd_addr) override {
256 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
257 CallbackEnv sCallbackEnv(__func__);
258 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
259
260 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
261 if (!addr.get()) {
262 ALOGE("Fail to new jbyteArray bd addr for audio state");
263 return;
264 }
265
266 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr.get());
267 }
268
AtCindCallback(RawAddress * bd_addr)269 void AtCindCallback(RawAddress* bd_addr) override {
270 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
271 CallbackEnv sCallbackEnv(__func__);
272 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
273
274 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
275 if (!addr.get()) {
276 ALOGE("Fail to new jbyteArray bd addr for audio state");
277 return;
278 }
279
280 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr.get());
281 }
282
AtCopsCallback(RawAddress * bd_addr)283 void AtCopsCallback(RawAddress* bd_addr) override {
284 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
285 CallbackEnv sCallbackEnv(__func__);
286 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
287
288 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
289 if (!addr.get()) {
290 ALOGE("Fail to new jbyteArray bd addr for audio state");
291 return;
292 }
293
294 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr.get());
295 }
296
AtClccCallback(RawAddress * bd_addr)297 void AtClccCallback(RawAddress* bd_addr) override {
298 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
299 CallbackEnv sCallbackEnv(__func__);
300 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
301
302 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
303 if (!addr.get()) {
304 ALOGE("Fail to new jbyteArray bd addr for audio state");
305 return;
306 }
307
308 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr.get());
309 }
310
UnknownAtCallback(char * at_string,RawAddress * bd_addr)311 void UnknownAtCallback(char* at_string, RawAddress* bd_addr) override {
312 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
313 CallbackEnv sCallbackEnv(__func__);
314 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
315
316 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
317 if (!addr.get()) {
318 ALOGE("Fail to new jbyteArray bd addr for audio state");
319 return;
320 }
321
322 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
323 sCallbackEnv->NewStringUTF(at_string));
324 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
325 js_at_string.get(), addr.get());
326 }
327
KeyPressedCallback(RawAddress * bd_addr)328 void KeyPressedCallback(RawAddress* bd_addr) override {
329 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
330 CallbackEnv sCallbackEnv(__func__);
331 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
332
333 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
334 if (!addr.get()) {
335 ALOGE("Fail to new jbyteArray bd addr for audio state");
336 return;
337 }
338
339 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed,
340 addr.get());
341 }
342
AtBindCallback(char * at_string,RawAddress * bd_addr)343 void AtBindCallback(char* at_string, RawAddress* bd_addr) override {
344 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
345 CallbackEnv sCallbackEnv(__func__);
346 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
347
348 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
349 if (addr.get() == nullptr) return;
350
351 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
352 sCallbackEnv->NewStringUTF(at_string));
353
354 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind,
355 js_at_string.get(), addr.get());
356 }
357
AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id,int ind_value,RawAddress * bd_addr)358 void AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id,
359 int ind_value, RawAddress* bd_addr) override {
360 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
361 CallbackEnv sCallbackEnv(__func__);
362 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
363
364 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
365 if (addr.get() == nullptr) return;
366
367 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id,
368 (jint)ind_value, addr.get());
369 }
370
AtBiaCallback(bool service,bool roam,bool signal,bool battery,RawAddress * bd_addr)371 void AtBiaCallback(bool service, bool roam, bool signal, bool battery,
372 RawAddress* bd_addr) override {
373 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
374 CallbackEnv sCallbackEnv(__func__);
375 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
376
377 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
378 if (addr.get() == nullptr) return;
379
380 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBia, service, roam,
381 signal, battery, addr.get());
382 }
383 };
384
classInitNative(JNIEnv * env,jclass clazz)385 static void classInitNative(JNIEnv* env, jclass clazz) {
386 method_onConnectionStateChanged =
387 env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
388 method_onAudioStateChanged =
389 env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
390 method_onVrStateChanged =
391 env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
392 method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
393 method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
394 method_onVolumeChanged =
395 env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
396 method_onDialCall =
397 env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
398 method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
399 method_onNoiceReductionEnable =
400 env->GetMethodID(clazz, "onNoiceReductionEnable", "(Z[B)V");
401 method_onWBS = env->GetMethodID(clazz, "onWBS", "(I[B)V");
402 method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
403 method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
404 method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
405 method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
406 method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
407 method_onUnknownAt =
408 env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
409 method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
410 method_onAtBind =
411 env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V");
412 method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V");
413 method_onAtBia = env->GetMethodID(clazz, "onAtBia", "(ZZZZ[B)V");
414
415 ALOGI("%s: succeeds", __func__);
416 }
417
initializeNative(JNIEnv * env,jobject object,jint max_hf_clients,jboolean inband_ringing_enabled)418 static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients,
419 jboolean inband_ringing_enabled) {
420 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
421 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
422
423 const bt_interface_t* btInf = getBluetoothInterface();
424 if (!btInf) {
425 ALOGE("%s: Bluetooth module is not loaded", __func__);
426 jniThrowIOException(env, EINVAL);
427 return;
428 }
429
430 if (sBluetoothHfpInterface) {
431 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing",
432 __func__);
433 sBluetoothHfpInterface->Cleanup();
434 sBluetoothHfpInterface = nullptr;
435 }
436
437 if (mCallbacksObj) {
438 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
439 env->DeleteGlobalRef(mCallbacksObj);
440 mCallbacksObj = nullptr;
441 }
442
443 sBluetoothHfpInterface =
444 (bluetooth::headset::Interface*)btInf->get_profile_interface(
445 BT_PROFILE_HANDSFREE_ID);
446 if (!sBluetoothHfpInterface) {
447 ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__);
448 jniThrowIOException(env, EINVAL);
449 }
450 bt_status_t status =
451 sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(),
452 max_hf_clients, inband_ringing_enabled);
453 if (status != BT_STATUS_SUCCESS) {
454 ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d",
455 __func__, status);
456 sBluetoothHfpInterface = nullptr;
457 return;
458 }
459
460 mCallbacksObj = env->NewGlobalRef(object);
461 }
462
cleanupNative(JNIEnv * env,jobject object)463 static void cleanupNative(JNIEnv* env, jobject object) {
464 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
465 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
466
467 const bt_interface_t* btInf = getBluetoothInterface();
468 if (!btInf) {
469 ALOGW("%s: Bluetooth module is not loaded", __func__);
470 return;
471 }
472
473 if (sBluetoothHfpInterface) {
474 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__);
475 sBluetoothHfpInterface->Cleanup();
476 sBluetoothHfpInterface = nullptr;
477 }
478
479 if (mCallbacksObj) {
480 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
481 env->DeleteGlobalRef(mCallbacksObj);
482 mCallbacksObj = nullptr;
483 }
484 }
485
connectHfpNative(JNIEnv * env,jobject object,jbyteArray address)486 static jboolean connectHfpNative(JNIEnv* env, jobject object,
487 jbyteArray address) {
488 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
489 if (!sBluetoothHfpInterface) {
490 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
491 return JNI_FALSE;
492 }
493 jbyte* addr = env->GetByteArrayElements(address, nullptr);
494 if (!addr) {
495 ALOGE("%s: failed to get device address", __func__);
496 jniThrowIOException(env, EINVAL);
497 return JNI_FALSE;
498 }
499 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
500 bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr);
501 if (status != BT_STATUS_SUCCESS) {
502 ALOGE("Failed HF connection, status: %d", status);
503 }
504 env->ReleaseByteArrayElements(address, addr, 0);
505 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
506 }
507
disconnectHfpNative(JNIEnv * env,jobject object,jbyteArray address)508 static jboolean disconnectHfpNative(JNIEnv* env, jobject object,
509 jbyteArray address) {
510 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
511 if (!sBluetoothHfpInterface) {
512 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
513 return JNI_FALSE;
514 }
515 jbyte* addr = env->GetByteArrayElements(address, nullptr);
516 if (!addr) {
517 ALOGE("%s: failed to get device address", __func__);
518 jniThrowIOException(env, EINVAL);
519 return JNI_FALSE;
520 }
521 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
522 bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr);
523 if (status != BT_STATUS_SUCCESS) {
524 ALOGE("Failed HF disconnection, status: %d", status);
525 }
526 env->ReleaseByteArrayElements(address, addr, 0);
527 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
528 }
529
connectAudioNative(JNIEnv * env,jobject object,jbyteArray address)530 static jboolean connectAudioNative(JNIEnv* env, jobject object,
531 jbyteArray address) {
532 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
533 if (!sBluetoothHfpInterface) {
534 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
535 return JNI_FALSE;
536 }
537 jbyte* addr = env->GetByteArrayElements(address, nullptr);
538 if (!addr) {
539 ALOGE("%s: failed to get device address", __func__);
540 jniThrowIOException(env, EINVAL);
541 return JNI_FALSE;
542 }
543 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
544 bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr);
545 if (status != BT_STATUS_SUCCESS) {
546 ALOGE("Failed HF audio connection, status: %d", status);
547 }
548 env->ReleaseByteArrayElements(address, addr, 0);
549 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
550 }
551
disconnectAudioNative(JNIEnv * env,jobject object,jbyteArray address)552 static jboolean disconnectAudioNative(JNIEnv* env, jobject object,
553 jbyteArray address) {
554 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
555 if (!sBluetoothHfpInterface) {
556 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
557 return JNI_FALSE;
558 }
559 jbyte* addr = env->GetByteArrayElements(address, nullptr);
560 if (!addr) {
561 ALOGE("%s: failed to get device address", __func__);
562 jniThrowIOException(env, EINVAL);
563 return JNI_FALSE;
564 }
565 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
566 bt_status_t status =
567 sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr);
568 if (status != BT_STATUS_SUCCESS) {
569 ALOGE("Failed HF audio disconnection, status: %d", status);
570 }
571 env->ReleaseByteArrayElements(address, addr, 0);
572 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
573 }
574
startVoiceRecognitionNative(JNIEnv * env,jobject object,jbyteArray address)575 static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object,
576 jbyteArray address) {
577 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
578 if (!sBluetoothHfpInterface) {
579 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
580 return JNI_FALSE;
581 }
582 jbyte* addr = env->GetByteArrayElements(address, nullptr);
583 if (!addr) {
584 ALOGE("%s: failed to get device address", __func__);
585 jniThrowIOException(env, EINVAL);
586 return JNI_FALSE;
587 }
588 bt_status_t status =
589 sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr);
590 if (status != BT_STATUS_SUCCESS) {
591 ALOGE("Failed to start voice recognition, status: %d", status);
592 }
593 env->ReleaseByteArrayElements(address, addr, 0);
594 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
595 }
596
stopVoiceRecognitionNative(JNIEnv * env,jobject object,jbyteArray address)597 static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object,
598 jbyteArray address) {
599 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
600 if (!sBluetoothHfpInterface) {
601 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
602 return JNI_FALSE;
603 }
604 jbyte* addr = env->GetByteArrayElements(address, nullptr);
605 if (!addr) {
606 ALOGE("%s: failed to get device address", __func__);
607 jniThrowIOException(env, EINVAL);
608 return JNI_FALSE;
609 }
610 bt_status_t status =
611 sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr);
612 if (status != BT_STATUS_SUCCESS) {
613 ALOGE("Failed to stop voice recognition, status: %d", status);
614 }
615 env->ReleaseByteArrayElements(address, addr, 0);
616 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
617 }
618
setVolumeNative(JNIEnv * env,jobject object,jint volume_type,jint volume,jbyteArray address)619 static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type,
620 jint volume, jbyteArray address) {
621 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
622 if (!sBluetoothHfpInterface) {
623 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
624 return JNI_FALSE;
625 }
626 jbyte* addr = env->GetByteArrayElements(address, nullptr);
627 if (!addr) {
628 ALOGE("%s: failed to get device address", __func__);
629 jniThrowIOException(env, EINVAL);
630 return JNI_FALSE;
631 }
632 bt_status_t status = sBluetoothHfpInterface->VolumeControl(
633 (bluetooth::headset::bthf_volume_type_t)volume_type, volume,
634 (RawAddress*)addr);
635 if (status != BT_STATUS_SUCCESS) {
636 ALOGE("FAILED to control volume, status: %d", status);
637 }
638 env->ReleaseByteArrayElements(address, addr, 0);
639 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
640 }
641
notifyDeviceStatusNative(JNIEnv * env,jobject object,jint network_state,jint service_type,jint signal,jint battery_charge,jbyteArray address)642 static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object,
643 jint network_state, jint service_type,
644 jint signal, jint battery_charge,
645 jbyteArray address) {
646 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
647 if (!sBluetoothHfpInterface) {
648 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
649 return JNI_FALSE;
650 }
651 jbyte* addr = env->GetByteArrayElements(address, nullptr);
652 if (!addr) {
653 ALOGE("%s: failed to get device address", __func__);
654 jniThrowIOException(env, EINVAL);
655 return JNI_FALSE;
656 }
657 bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification(
658 (bluetooth::headset::bthf_network_state_t)network_state,
659 (bluetooth::headset::bthf_service_type_t)service_type, signal,
660 battery_charge, (RawAddress*)addr);
661 env->ReleaseByteArrayElements(address, addr, 0);
662 if (status != BT_STATUS_SUCCESS) {
663 ALOGE("FAILED to notify device status, status: %d", status);
664 }
665 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
666 }
667
copsResponseNative(JNIEnv * env,jobject object,jstring operator_str,jbyteArray address)668 static jboolean copsResponseNative(JNIEnv* env, jobject object,
669 jstring operator_str, jbyteArray address) {
670 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
671 if (!sBluetoothHfpInterface) {
672 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
673 return JNI_FALSE;
674 }
675 jbyte* addr = env->GetByteArrayElements(address, nullptr);
676 if (!addr) {
677 ALOGE("%s: failed to get device address", __func__);
678 jniThrowIOException(env, EINVAL);
679 return JNI_FALSE;
680 }
681 const char* operator_name = env->GetStringUTFChars(operator_str, nullptr);
682 bt_status_t status =
683 sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr);
684 if (status != BT_STATUS_SUCCESS) {
685 ALOGE("Failed sending cops response, status: %d", status);
686 }
687 env->ReleaseByteArrayElements(address, addr, 0);
688 env->ReleaseStringUTFChars(operator_str, operator_name);
689 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
690 }
691
cindResponseNative(JNIEnv * env,jobject object,jint service,jint num_active,jint num_held,jint call_state,jint signal,jint roam,jint battery_charge,jbyteArray address)692 static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service,
693 jint num_active, jint num_held,
694 jint call_state, jint signal, jint roam,
695 jint battery_charge, jbyteArray address) {
696 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
697 if (!sBluetoothHfpInterface) {
698 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
699 return JNI_FALSE;
700 }
701 jbyte* addr = env->GetByteArrayElements(address, nullptr);
702 if (!addr) {
703 ALOGE("%s: failed to get device address", __func__);
704 jniThrowIOException(env, EINVAL);
705 return JNI_FALSE;
706 }
707 bt_status_t status = sBluetoothHfpInterface->CindResponse(
708 service, num_active, num_held,
709 (bluetooth::headset::bthf_call_state_t)call_state, signal, roam,
710 battery_charge, (RawAddress*)addr);
711 if (status != BT_STATUS_SUCCESS) {
712 ALOGE("%s: failed, status: %d", __func__, status);
713 }
714 env->ReleaseByteArrayElements(address, addr, 0);
715 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
716 }
717
atResponseStringNative(JNIEnv * env,jobject object,jstring response_str,jbyteArray address)718 static jboolean atResponseStringNative(JNIEnv* env, jobject object,
719 jstring response_str,
720 jbyteArray address) {
721 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
722 if (!sBluetoothHfpInterface) {
723 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
724 return JNI_FALSE;
725 }
726 jbyte* addr = env->GetByteArrayElements(address, nullptr);
727 if (!addr) {
728 ALOGE("%s: failed to get device address", __func__);
729 jniThrowIOException(env, EINVAL);
730 return JNI_FALSE;
731 }
732 const char* response = env->GetStringUTFChars(response_str, nullptr);
733 bt_status_t status =
734 sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr);
735 if (status != BT_STATUS_SUCCESS) {
736 ALOGE("Failed formatted AT response, status: %d", status);
737 }
738 env->ReleaseByteArrayElements(address, addr, 0);
739 env->ReleaseStringUTFChars(response_str, response);
740 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
741 }
742
atResponseCodeNative(JNIEnv * env,jobject object,jint response_code,jint cmee_code,jbyteArray address)743 static jboolean atResponseCodeNative(JNIEnv* env, jobject object,
744 jint response_code, jint cmee_code,
745 jbyteArray address) {
746 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
747 if (!sBluetoothHfpInterface) {
748 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
749 return JNI_FALSE;
750 }
751 jbyte* addr = env->GetByteArrayElements(address, nullptr);
752 if (!addr) {
753 ALOGE("%s: failed to get device address", __func__);
754 jniThrowIOException(env, EINVAL);
755 return JNI_FALSE;
756 }
757 bt_status_t status = sBluetoothHfpInterface->AtResponse(
758 (bluetooth::headset::bthf_at_response_t)response_code, cmee_code,
759 (RawAddress*)addr);
760 if (status != BT_STATUS_SUCCESS) {
761 ALOGE("Failed AT response, status: %d", status);
762 }
763 env->ReleaseByteArrayElements(address, addr, 0);
764 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
765 }
766
clccResponseNative(JNIEnv * env,jobject object,jint index,jint dir,jint callStatus,jint mode,jboolean mpty,jstring number_str,jint type,jbyteArray address)767 static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index,
768 jint dir, jint callStatus, jint mode,
769 jboolean mpty, jstring number_str, jint type,
770 jbyteArray address) {
771 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
772 if (!sBluetoothHfpInterface) {
773 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
774 return JNI_FALSE;
775 }
776 jbyte* addr = env->GetByteArrayElements(address, nullptr);
777 if (!addr) {
778 ALOGE("%s: failed to get device address", __func__);
779 jniThrowIOException(env, EINVAL);
780 return JNI_FALSE;
781 }
782 const char* number = nullptr;
783 if (number_str) {
784 number = env->GetStringUTFChars(number_str, nullptr);
785 }
786 bt_status_t status = sBluetoothHfpInterface->ClccResponse(
787 index, (bluetooth::headset::bthf_call_direction_t)dir,
788 (bluetooth::headset::bthf_call_state_t)callStatus,
789 (bluetooth::headset::bthf_call_mode_t)mode,
790 mpty ? bluetooth::headset::BTHF_CALL_MPTY_TYPE_MULTI
791 : bluetooth::headset::BTHF_CALL_MPTY_TYPE_SINGLE,
792 number, (bluetooth::headset::bthf_call_addrtype_t)type,
793 (RawAddress*)addr);
794 if (status != BT_STATUS_SUCCESS) {
795 ALOGE("Failed sending CLCC response, status: %d", status);
796 }
797 env->ReleaseByteArrayElements(address, addr, 0);
798 if (number) {
799 env->ReleaseStringUTFChars(number_str, number);
800 }
801 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
802 }
803
phoneStateChangeNative(JNIEnv * env,jobject object,jint num_active,jint num_held,jint call_state,jstring number_str,jint type,jbyteArray address)804 static jboolean phoneStateChangeNative(JNIEnv* env, jobject object,
805 jint num_active, jint num_held,
806 jint call_state, jstring number_str,
807 jint type, jbyteArray address) {
808 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
809 if (!sBluetoothHfpInterface) {
810 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
811 return JNI_FALSE;
812 }
813 jbyte* addr = env->GetByteArrayElements(address, nullptr);
814 if (!addr) {
815 ALOGE("%s: failed to get device address", __func__);
816 jniThrowIOException(env, EINVAL);
817 return JNI_FALSE;
818 }
819 const char* number = env->GetStringUTFChars(number_str, nullptr);
820 bt_status_t status = sBluetoothHfpInterface->PhoneStateChange(
821 num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state,
822 number, (bluetooth::headset::bthf_call_addrtype_t)type,
823 (RawAddress*)addr);
824 if (status != BT_STATUS_SUCCESS) {
825 ALOGE("Failed report phone state change, status: %d", status);
826 }
827 env->ReleaseStringUTFChars(number_str, number);
828 env->ReleaseByteArrayElements(address, addr, 0);
829 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
830 }
831
setScoAllowedNative(JNIEnv * env,jobject object,jboolean value)832 static jboolean setScoAllowedNative(JNIEnv* env, jobject object,
833 jboolean value) {
834 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
835 if (!sBluetoothHfpInterface) {
836 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
837 return JNI_FALSE;
838 }
839 bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE);
840 if (status != BT_STATUS_SUCCESS) {
841 ALOGE("Failed HF set sco allowed, status: %d", status);
842 }
843 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
844 }
845
sendBsirNative(JNIEnv * env,jobject object,jboolean value,jbyteArray address)846 static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value,
847 jbyteArray address) {
848 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
849 if (!sBluetoothHfpInterface) {
850 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
851 return JNI_FALSE;
852 }
853 jbyte* addr = env->GetByteArrayElements(address, NULL);
854 if (!addr) {
855 ALOGE("%s: failed to get device address", __func__);
856 jniThrowIOException(env, EINVAL);
857 return JNI_FALSE;
858 }
859 bt_status_t status =
860 sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr);
861 if (status != BT_STATUS_SUCCESS) {
862 ALOGE("Failed sending BSIR, value=%d, status=%d", value, status);
863 }
864 env->ReleaseByteArrayElements(address, addr, 0);
865 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
866 }
867
setActiveDeviceNative(JNIEnv * env,jobject object,jbyteArray address)868 static jboolean setActiveDeviceNative(JNIEnv* env, jobject object,
869 jbyteArray address) {
870 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
871 if (!sBluetoothHfpInterface) {
872 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
873 return JNI_FALSE;
874 }
875 jbyte* addr = env->GetByteArrayElements(address, NULL);
876 if (!addr) {
877 ALOGE("%s: failed to get device address", __func__);
878 jniThrowIOException(env, EINVAL);
879 return JNI_FALSE;
880 }
881 bt_status_t status =
882 sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr);
883 if (status != BT_STATUS_SUCCESS) {
884 ALOGE("Failed to set active device, status: %d", status);
885 }
886 env->ReleaseByteArrayElements(address, addr, 0);
887 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
888 }
889
890 static JNINativeMethod sMethods[] = {
891 {"classInitNative", "()V", (void*)classInitNative},
892 {"initializeNative", "(IZ)V", (void*)initializeNative},
893 {"cleanupNative", "()V", (void*)cleanupNative},
894 {"connectHfpNative", "([B)Z", (void*)connectHfpNative},
895 {"disconnectHfpNative", "([B)Z", (void*)disconnectHfpNative},
896 {"connectAudioNative", "([B)Z", (void*)connectAudioNative},
897 {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
898 {"startVoiceRecognitionNative", "([B)Z",
899 (void*)startVoiceRecognitionNative},
900 {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative},
901 {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative},
902 {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative},
903 {"copsResponseNative", "(Ljava/lang/String;[B)Z",
904 (void*)copsResponseNative},
905 {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative},
906 {"atResponseStringNative", "(Ljava/lang/String;[B)Z",
907 (void*)atResponseStringNative},
908 {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative},
909 {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z",
910 (void*)clccResponseNative},
911 {"phoneStateChangeNative", "(IIILjava/lang/String;I[B)Z",
912 (void*)phoneStateChangeNative},
913 {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative},
914 {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative},
915 {"setActiveDeviceNative", "([B)Z", (void*)setActiveDeviceNative},
916 };
917
register_com_android_bluetooth_hfp(JNIEnv * env)918 int register_com_android_bluetooth_hfp(JNIEnv* env) {
919 return jniRegisterNativeMethods(
920 env, "com/android/bluetooth/hfp/HeadsetNativeInterface", sMethods,
921 NELEM(sMethods));
922 }
923
924 } /* namespace android */
925