Home | History | Annotate | Download | only in jni
      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 
     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:
     76   static bluetooth::headset::Callbacks* GetInstance() {
     77     static bluetooth::headset::Callbacks* instance = new JniHeadsetCallbacks();
     78     return instance;
     79   }
     80 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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