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