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_onNoiseReductionEnable;
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 char null_str[] = "";
186 if (!sCallbackEnv.isValidUtf(number)) {
187 android_errorWriteLog(0x534e4554, "109838537");
188 ALOGE("%s: number is not a valid UTF string.", __func__);
189 number = null_str;
190 }
191
192 ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
193 sCallbackEnv->NewStringUTF(number));
194 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
195 js_number.get(), addr.get());
196 }
197
DtmfCmdCallback(char dtmf,RawAddress * bd_addr)198 void DtmfCmdCallback(char dtmf, RawAddress* bd_addr) override {
199 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
200 CallbackEnv sCallbackEnv(__func__);
201 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
202
203 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
204 if (!addr.get()) {
205 ALOGE("Fail to new jbyteArray bd addr for audio state");
206 return;
207 }
208
209 // TBD dtmf has changed from int to char
210 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf,
211 addr.get());
212 }
213
NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec,RawAddress * bd_addr)214 void NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec,
215 RawAddress* bd_addr) override {
216 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
217 CallbackEnv sCallbackEnv(__func__);
218 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
219
220 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
221 if (!addr.get()) {
222 ALOGE("Fail to new jbyteArray bd addr for audio state");
223 return;
224 }
225 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiseReductionEnable,
226 nrec == bluetooth::headset::BTHF_NREC_START,
227 addr.get());
228 }
229
WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config,RawAddress * bd_addr)230 void WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config,
231 RawAddress* bd_addr) override {
232 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
233 CallbackEnv sCallbackEnv(__func__);
234 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
235
236 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
237 if (addr.get() == nullptr) return;
238
239 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config,
240 addr.get());
241 }
242
AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,RawAddress * bd_addr)243 void AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,
244 RawAddress* bd_addr) override {
245 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
246 CallbackEnv sCallbackEnv(__func__);
247 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
248
249 ScopedLocalRef<jbyteArray> addr(
250 sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
251 if (!addr.get()) {
252 ALOGE("Fail to new jbyteArray bd addr for audio state");
253 return;
254 }
255
256 sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
257 (jbyte*)bd_addr);
258 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld,
259 addr.get());
260 }
261
AtCnumCallback(RawAddress * bd_addr)262 void AtCnumCallback(RawAddress* bd_addr) override {
263 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
264 CallbackEnv sCallbackEnv(__func__);
265 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
266
267 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
268 if (!addr.get()) {
269 ALOGE("Fail to new jbyteArray bd addr for audio state");
270 return;
271 }
272
273 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr.get());
274 }
275
AtCindCallback(RawAddress * bd_addr)276 void AtCindCallback(RawAddress* bd_addr) override {
277 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
278 CallbackEnv sCallbackEnv(__func__);
279 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
280
281 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
282 if (!addr.get()) {
283 ALOGE("Fail to new jbyteArray bd addr for audio state");
284 return;
285 }
286
287 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr.get());
288 }
289
AtCopsCallback(RawAddress * bd_addr)290 void AtCopsCallback(RawAddress* bd_addr) override {
291 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
292 CallbackEnv sCallbackEnv(__func__);
293 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
294
295 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
296 if (!addr.get()) {
297 ALOGE("Fail to new jbyteArray bd addr for audio state");
298 return;
299 }
300
301 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr.get());
302 }
303
AtClccCallback(RawAddress * bd_addr)304 void AtClccCallback(RawAddress* bd_addr) override {
305 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
306 CallbackEnv sCallbackEnv(__func__);
307 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
308
309 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
310 if (!addr.get()) {
311 ALOGE("Fail to new jbyteArray bd addr for audio state");
312 return;
313 }
314
315 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr.get());
316 }
317
UnknownAtCallback(char * at_string,RawAddress * bd_addr)318 void UnknownAtCallback(char* at_string, RawAddress* bd_addr) override {
319 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
320 CallbackEnv sCallbackEnv(__func__);
321 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
322
323 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
324 if (!addr.get()) {
325 ALOGE("Fail to new jbyteArray bd addr for audio state");
326 return;
327 }
328
329 char null_str[] = "";
330 if (!sCallbackEnv.isValidUtf(at_string)) {
331 android_errorWriteLog(0x534e4554, "109838537");
332 ALOGE("%s: at_string is not a valid UTF string.", __func__);
333 at_string = null_str;
334 }
335
336 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
337 sCallbackEnv->NewStringUTF(at_string));
338 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
339 js_at_string.get(), addr.get());
340 }
341
KeyPressedCallback(RawAddress * bd_addr)342 void KeyPressedCallback(RawAddress* bd_addr) override {
343 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
344 CallbackEnv sCallbackEnv(__func__);
345 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
346
347 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
348 if (!addr.get()) {
349 ALOGE("Fail to new jbyteArray bd addr for audio state");
350 return;
351 }
352
353 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed,
354 addr.get());
355 }
356
AtBindCallback(char * at_string,RawAddress * bd_addr)357 void AtBindCallback(char* at_string, RawAddress* bd_addr) override {
358 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
359 CallbackEnv sCallbackEnv(__func__);
360 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
361
362 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
363 if (addr.get() == nullptr) return;
364
365 char null_str[] = "";
366 if (!sCallbackEnv.isValidUtf(at_string)) {
367 android_errorWriteLog(0x534e4554, "109838537");
368 ALOGE("%s: at_string is not a valid UTF string.", __func__);
369 at_string = null_str;
370 }
371
372 ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
373 sCallbackEnv->NewStringUTF(at_string));
374
375 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind,
376 js_at_string.get(), addr.get());
377 }
378
AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id,int ind_value,RawAddress * bd_addr)379 void AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id,
380 int ind_value, RawAddress* bd_addr) override {
381 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
382 CallbackEnv sCallbackEnv(__func__);
383 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
384
385 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
386 if (addr.get() == nullptr) return;
387
388 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id,
389 (jint)ind_value, addr.get());
390 }
391
AtBiaCallback(bool service,bool roam,bool signal,bool battery,RawAddress * bd_addr)392 void AtBiaCallback(bool service, bool roam, bool signal, bool battery,
393 RawAddress* bd_addr) override {
394 std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
395 CallbackEnv sCallbackEnv(__func__);
396 if (!sCallbackEnv.valid() || !mCallbacksObj) return;
397
398 ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
399 if (addr.get() == nullptr) return;
400
401 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBia, service, roam,
402 signal, battery, addr.get());
403 }
404 };
405
classInitNative(JNIEnv * env,jclass clazz)406 static void classInitNative(JNIEnv* env, jclass clazz) {
407 method_onConnectionStateChanged =
408 env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
409 method_onAudioStateChanged =
410 env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
411 method_onVrStateChanged =
412 env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
413 method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
414 method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
415 method_onVolumeChanged =
416 env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
417 method_onDialCall =
418 env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
419 method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
420 method_onNoiseReductionEnable =
421 env->GetMethodID(clazz, "onNoiseReductionEnable", "(Z[B)V");
422 method_onWBS = env->GetMethodID(clazz, "onWBS", "(I[B)V");
423 method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
424 method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
425 method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
426 method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
427 method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
428 method_onUnknownAt =
429 env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
430 method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
431 method_onAtBind =
432 env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V");
433 method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V");
434 method_onAtBia = env->GetMethodID(clazz, "onAtBia", "(ZZZZ[B)V");
435
436 ALOGI("%s: succeeds", __func__);
437 }
438
initializeNative(JNIEnv * env,jobject object,jint max_hf_clients,jboolean inband_ringing_enabled)439 static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients,
440 jboolean inband_ringing_enabled) {
441 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
442 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
443
444 const bt_interface_t* btInf = getBluetoothInterface();
445 if (!btInf) {
446 ALOGE("%s: Bluetooth module is not loaded", __func__);
447 jniThrowIOException(env, EINVAL);
448 return;
449 }
450
451 if (sBluetoothHfpInterface) {
452 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing",
453 __func__);
454 sBluetoothHfpInterface->Cleanup();
455 sBluetoothHfpInterface = nullptr;
456 }
457
458 if (mCallbacksObj) {
459 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
460 env->DeleteGlobalRef(mCallbacksObj);
461 mCallbacksObj = nullptr;
462 }
463
464 sBluetoothHfpInterface =
465 (bluetooth::headset::Interface*)btInf->get_profile_interface(
466 BT_PROFILE_HANDSFREE_ID);
467 if (!sBluetoothHfpInterface) {
468 ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__);
469 jniThrowIOException(env, EINVAL);
470 return;
471 }
472 bt_status_t status =
473 sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(),
474 max_hf_clients, inband_ringing_enabled);
475 if (status != BT_STATUS_SUCCESS) {
476 ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d",
477 __func__, status);
478 sBluetoothHfpInterface = nullptr;
479 return;
480 }
481
482 mCallbacksObj = env->NewGlobalRef(object);
483 }
484
cleanupNative(JNIEnv * env,jobject object)485 static void cleanupNative(JNIEnv* env, jobject object) {
486 std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
487 std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
488
489 const bt_interface_t* btInf = getBluetoothInterface();
490 if (!btInf) {
491 ALOGW("%s: Bluetooth module is not loaded", __func__);
492 return;
493 }
494
495 if (sBluetoothHfpInterface) {
496 ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__);
497 sBluetoothHfpInterface->Cleanup();
498 sBluetoothHfpInterface = nullptr;
499 }
500
501 if (mCallbacksObj) {
502 ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
503 env->DeleteGlobalRef(mCallbacksObj);
504 mCallbacksObj = nullptr;
505 }
506 }
507
connectHfpNative(JNIEnv * env,jobject object,jbyteArray address)508 static jboolean connectHfpNative(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->Connect((RawAddress*)addr);
523 if (status != BT_STATUS_SUCCESS) {
524 ALOGE("Failed HF connection, status: %d", status);
525 }
526 env->ReleaseByteArrayElements(address, addr, 0);
527 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
528 }
529
disconnectHfpNative(JNIEnv * env,jobject object,jbyteArray address)530 static jboolean disconnectHfpNative(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->Disconnect((RawAddress*)addr);
545 if (status != BT_STATUS_SUCCESS) {
546 ALOGE("Failed HF disconnection, status: %d", status);
547 }
548 env->ReleaseByteArrayElements(address, addr, 0);
549 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
550 }
551
connectAudioNative(JNIEnv * env,jobject object,jbyteArray address)552 static jboolean connectAudioNative(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 = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr);
567 if (status != BT_STATUS_SUCCESS) {
568 ALOGE("Failed HF audio connection, status: %d", status);
569 }
570 env->ReleaseByteArrayElements(address, addr, 0);
571 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
572 }
573
disconnectAudioNative(JNIEnv * env,jobject object,jbyteArray address)574 static jboolean disconnectAudioNative(JNIEnv* env, jobject object,
575 jbyteArray address) {
576 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
577 if (!sBluetoothHfpInterface) {
578 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
579 return JNI_FALSE;
580 }
581 jbyte* addr = env->GetByteArrayElements(address, nullptr);
582 if (!addr) {
583 ALOGE("%s: failed to get device address", __func__);
584 jniThrowIOException(env, EINVAL);
585 return JNI_FALSE;
586 }
587 ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
588 bt_status_t status =
589 sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr);
590 if (status != BT_STATUS_SUCCESS) {
591 ALOGE("Failed HF audio disconnection, status: %d", status);
592 }
593 env->ReleaseByteArrayElements(address, addr, 0);
594 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
595 }
596
startVoiceRecognitionNative(JNIEnv * env,jobject object,jbyteArray address)597 static jboolean startVoiceRecognitionNative(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->StartVoiceRecognition((RawAddress*)addr);
612 if (status != BT_STATUS_SUCCESS) {
613 ALOGE("Failed to start voice recognition, status: %d", status);
614 }
615 env->ReleaseByteArrayElements(address, addr, 0);
616 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
617 }
618
stopVoiceRecognitionNative(JNIEnv * env,jobject object,jbyteArray address)619 static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object,
620 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 =
633 sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr);
634 if (status != BT_STATUS_SUCCESS) {
635 ALOGE("Failed to stop voice recognition, status: %d", status);
636 }
637 env->ReleaseByteArrayElements(address, addr, 0);
638 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
639 }
640
setVolumeNative(JNIEnv * env,jobject object,jint volume_type,jint volume,jbyteArray address)641 static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type,
642 jint volume, jbyteArray address) {
643 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
644 if (!sBluetoothHfpInterface) {
645 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
646 return JNI_FALSE;
647 }
648 jbyte* addr = env->GetByteArrayElements(address, nullptr);
649 if (!addr) {
650 ALOGE("%s: failed to get device address", __func__);
651 jniThrowIOException(env, EINVAL);
652 return JNI_FALSE;
653 }
654 bt_status_t status = sBluetoothHfpInterface->VolumeControl(
655 (bluetooth::headset::bthf_volume_type_t)volume_type, volume,
656 (RawAddress*)addr);
657 if (status != BT_STATUS_SUCCESS) {
658 ALOGE("FAILED to control volume, status: %d", status);
659 }
660 env->ReleaseByteArrayElements(address, addr, 0);
661 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
662 }
663
notifyDeviceStatusNative(JNIEnv * env,jobject object,jint network_state,jint service_type,jint signal,jint battery_charge,jbyteArray address)664 static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object,
665 jint network_state, jint service_type,
666 jint signal, jint battery_charge,
667 jbyteArray address) {
668 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
669 if (!sBluetoothHfpInterface) {
670 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
671 return JNI_FALSE;
672 }
673 jbyte* addr = env->GetByteArrayElements(address, nullptr);
674 if (!addr) {
675 ALOGE("%s: failed to get device address", __func__);
676 jniThrowIOException(env, EINVAL);
677 return JNI_FALSE;
678 }
679 bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification(
680 (bluetooth::headset::bthf_network_state_t)network_state,
681 (bluetooth::headset::bthf_service_type_t)service_type, signal,
682 battery_charge, (RawAddress*)addr);
683 env->ReleaseByteArrayElements(address, addr, 0);
684 if (status != BT_STATUS_SUCCESS) {
685 ALOGE("FAILED to notify device status, status: %d", status);
686 }
687 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
688 }
689
copsResponseNative(JNIEnv * env,jobject object,jstring operator_str,jbyteArray address)690 static jboolean copsResponseNative(JNIEnv* env, jobject object,
691 jstring operator_str, jbyteArray address) {
692 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
693 if (!sBluetoothHfpInterface) {
694 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
695 return JNI_FALSE;
696 }
697 jbyte* addr = env->GetByteArrayElements(address, nullptr);
698 if (!addr) {
699 ALOGE("%s: failed to get device address", __func__);
700 jniThrowIOException(env, EINVAL);
701 return JNI_FALSE;
702 }
703 const char* operator_name = env->GetStringUTFChars(operator_str, nullptr);
704 bt_status_t status =
705 sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr);
706 if (status != BT_STATUS_SUCCESS) {
707 ALOGE("Failed sending cops response, status: %d", status);
708 }
709 env->ReleaseByteArrayElements(address, addr, 0);
710 env->ReleaseStringUTFChars(operator_str, operator_name);
711 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
712 }
713
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)714 static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service,
715 jint num_active, jint num_held,
716 jint call_state, jint signal, jint roam,
717 jint battery_charge, jbyteArray address) {
718 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
719 if (!sBluetoothHfpInterface) {
720 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
721 return JNI_FALSE;
722 }
723 jbyte* addr = env->GetByteArrayElements(address, nullptr);
724 if (!addr) {
725 ALOGE("%s: failed to get device address", __func__);
726 jniThrowIOException(env, EINVAL);
727 return JNI_FALSE;
728 }
729 bt_status_t status = sBluetoothHfpInterface->CindResponse(
730 service, num_active, num_held,
731 (bluetooth::headset::bthf_call_state_t)call_state, signal, roam,
732 battery_charge, (RawAddress*)addr);
733 if (status != BT_STATUS_SUCCESS) {
734 ALOGE("%s: failed, status: %d", __func__, status);
735 }
736 env->ReleaseByteArrayElements(address, addr, 0);
737 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
738 }
739
atResponseStringNative(JNIEnv * env,jobject object,jstring response_str,jbyteArray address)740 static jboolean atResponseStringNative(JNIEnv* env, jobject object,
741 jstring response_str,
742 jbyteArray address) {
743 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
744 if (!sBluetoothHfpInterface) {
745 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
746 return JNI_FALSE;
747 }
748 jbyte* addr = env->GetByteArrayElements(address, nullptr);
749 if (!addr) {
750 ALOGE("%s: failed to get device address", __func__);
751 jniThrowIOException(env, EINVAL);
752 return JNI_FALSE;
753 }
754 const char* response = env->GetStringUTFChars(response_str, nullptr);
755 bt_status_t status =
756 sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr);
757 if (status != BT_STATUS_SUCCESS) {
758 ALOGE("Failed formatted AT response, status: %d", status);
759 }
760 env->ReleaseByteArrayElements(address, addr, 0);
761 env->ReleaseStringUTFChars(response_str, response);
762 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
763 }
764
atResponseCodeNative(JNIEnv * env,jobject object,jint response_code,jint cmee_code,jbyteArray address)765 static jboolean atResponseCodeNative(JNIEnv* env, jobject object,
766 jint response_code, jint cmee_code,
767 jbyteArray address) {
768 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
769 if (!sBluetoothHfpInterface) {
770 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
771 return JNI_FALSE;
772 }
773 jbyte* addr = env->GetByteArrayElements(address, nullptr);
774 if (!addr) {
775 ALOGE("%s: failed to get device address", __func__);
776 jniThrowIOException(env, EINVAL);
777 return JNI_FALSE;
778 }
779 bt_status_t status = sBluetoothHfpInterface->AtResponse(
780 (bluetooth::headset::bthf_at_response_t)response_code, cmee_code,
781 (RawAddress*)addr);
782 if (status != BT_STATUS_SUCCESS) {
783 ALOGE("Failed AT response, status: %d", status);
784 }
785 env->ReleaseByteArrayElements(address, addr, 0);
786 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
787 }
788
clccResponseNative(JNIEnv * env,jobject object,jint index,jint dir,jint callStatus,jint mode,jboolean mpty,jstring number_str,jint type,jbyteArray address)789 static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index,
790 jint dir, jint callStatus, jint mode,
791 jboolean mpty, jstring number_str, jint type,
792 jbyteArray address) {
793 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
794 if (!sBluetoothHfpInterface) {
795 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
796 return JNI_FALSE;
797 }
798 jbyte* addr = env->GetByteArrayElements(address, nullptr);
799 if (!addr) {
800 ALOGE("%s: failed to get device address", __func__);
801 jniThrowIOException(env, EINVAL);
802 return JNI_FALSE;
803 }
804 const char* number = nullptr;
805 if (number_str) {
806 number = env->GetStringUTFChars(number_str, nullptr);
807 }
808 bt_status_t status = sBluetoothHfpInterface->ClccResponse(
809 index, (bluetooth::headset::bthf_call_direction_t)dir,
810 (bluetooth::headset::bthf_call_state_t)callStatus,
811 (bluetooth::headset::bthf_call_mode_t)mode,
812 mpty ? bluetooth::headset::BTHF_CALL_MPTY_TYPE_MULTI
813 : bluetooth::headset::BTHF_CALL_MPTY_TYPE_SINGLE,
814 number, (bluetooth::headset::bthf_call_addrtype_t)type,
815 (RawAddress*)addr);
816 if (status != BT_STATUS_SUCCESS) {
817 ALOGE("Failed sending CLCC response, status: %d", status);
818 }
819 env->ReleaseByteArrayElements(address, addr, 0);
820 if (number) {
821 env->ReleaseStringUTFChars(number_str, number);
822 }
823 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
824 }
825
phoneStateChangeNative(JNIEnv * env,jobject object,jint num_active,jint num_held,jint call_state,jstring number_str,jint type,jstring name_str,jbyteArray address)826 static jboolean phoneStateChangeNative(JNIEnv* env, jobject object,
827 jint num_active, jint num_held,
828 jint call_state, jstring number_str,
829 jint type, jstring name_str,
830 jbyteArray address) {
831 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
832 if (!sBluetoothHfpInterface) {
833 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
834 return JNI_FALSE;
835 }
836 jbyte* addr = env->GetByteArrayElements(address, nullptr);
837 if (!addr) {
838 ALOGE("%s: failed to get device address", __func__);
839 jniThrowIOException(env, EINVAL);
840 return JNI_FALSE;
841 }
842 const char* number = env->GetStringUTFChars(number_str, nullptr);
843 const char* name = nullptr;
844 if (name_str != nullptr) {
845 name = env->GetStringUTFChars(name_str, nullptr);
846 }
847 bt_status_t status = sBluetoothHfpInterface->PhoneStateChange(
848 num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state,
849 number, (bluetooth::headset::bthf_call_addrtype_t)type, name,
850 (RawAddress*)addr);
851 if (status != BT_STATUS_SUCCESS) {
852 ALOGE("Failed report phone state change, status: %d", status);
853 }
854 env->ReleaseStringUTFChars(number_str, number);
855 if (name != nullptr) {
856 env->ReleaseStringUTFChars(name_str, name);
857 }
858 env->ReleaseByteArrayElements(address, addr, 0);
859 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
860 }
861
setScoAllowedNative(JNIEnv * env,jobject object,jboolean value)862 static jboolean setScoAllowedNative(JNIEnv* env, jobject object,
863 jboolean value) {
864 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
865 if (!sBluetoothHfpInterface) {
866 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
867 return JNI_FALSE;
868 }
869 bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE);
870 if (status != BT_STATUS_SUCCESS) {
871 ALOGE("Failed HF set sco allowed, status: %d", status);
872 }
873 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
874 }
875
sendBsirNative(JNIEnv * env,jobject object,jboolean value,jbyteArray address)876 static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value,
877 jbyteArray address) {
878 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
879 if (!sBluetoothHfpInterface) {
880 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
881 return JNI_FALSE;
882 }
883 jbyte* addr = env->GetByteArrayElements(address, NULL);
884 if (!addr) {
885 ALOGE("%s: failed to get device address", __func__);
886 jniThrowIOException(env, EINVAL);
887 return JNI_FALSE;
888 }
889 bt_status_t status =
890 sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr);
891 if (status != BT_STATUS_SUCCESS) {
892 ALOGE("Failed sending BSIR, value=%d, status=%d", value, status);
893 }
894 env->ReleaseByteArrayElements(address, addr, 0);
895 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
896 }
897
setActiveDeviceNative(JNIEnv * env,jobject object,jbyteArray address)898 static jboolean setActiveDeviceNative(JNIEnv* env, jobject object,
899 jbyteArray address) {
900 std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
901 if (!sBluetoothHfpInterface) {
902 ALOGW("%s: sBluetoothHfpInterface is null", __func__);
903 return JNI_FALSE;
904 }
905 jbyte* addr = env->GetByteArrayElements(address, NULL);
906 if (!addr) {
907 ALOGE("%s: failed to get device address", __func__);
908 jniThrowIOException(env, EINVAL);
909 return JNI_FALSE;
910 }
911 bt_status_t status =
912 sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr);
913 if (status != BT_STATUS_SUCCESS) {
914 ALOGE("Failed to set active device, status: %d", status);
915 }
916 env->ReleaseByteArrayElements(address, addr, 0);
917 return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
918 }
919
920 static JNINativeMethod sMethods[] = {
921 {"classInitNative", "()V", (void*)classInitNative},
922 {"initializeNative", "(IZ)V", (void*)initializeNative},
923 {"cleanupNative", "()V", (void*)cleanupNative},
924 {"connectHfpNative", "([B)Z", (void*)connectHfpNative},
925 {"disconnectHfpNative", "([B)Z", (void*)disconnectHfpNative},
926 {"connectAudioNative", "([B)Z", (void*)connectAudioNative},
927 {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
928 {"startVoiceRecognitionNative", "([B)Z",
929 (void*)startVoiceRecognitionNative},
930 {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative},
931 {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative},
932 {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative},
933 {"copsResponseNative", "(Ljava/lang/String;[B)Z",
934 (void*)copsResponseNative},
935 {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative},
936 {"atResponseStringNative", "(Ljava/lang/String;[B)Z",
937 (void*)atResponseStringNative},
938 {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative},
939 {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z",
940 (void*)clccResponseNative},
941 {"phoneStateChangeNative", "(IIILjava/lang/String;ILjava/lang/String;[B)Z",
942 (void*)phoneStateChangeNative},
943 {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative},
944 {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative},
945 {"setActiveDeviceNative", "([B)Z", (void*)setActiveDeviceNative},
946 };
947
register_com_android_bluetooth_hfp(JNIEnv * env)948 int register_com_android_bluetooth_hfp(JNIEnv* env) {
949 return jniRegisterNativeMethods(
950 env, "com/android/bluetooth/hfp/HeadsetNativeInterface", sMethods,
951 NELEM(sMethods));
952 }
953
954 } /* namespace android */
955