• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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