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