Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a478ce42 authored by Andrew Cheng's avatar Andrew Cheng Committed by Gerrit Code Review
Browse files

Merge "Fix HFP client JNI NPE and concurrency issues in JNI and service"

parents 4651f228 c038399d
Loading
Loading
Loading
Loading
+71 −21
Original line number Diff line number Diff line
@@ -22,10 +22,15 @@
#include "hardware/bt_hf_client.h"
#include "utils/Log.h"

#include <shared_mutex>

namespace android {

static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL;
static std::shared_mutex interface_mutex;

static jobject mCallbacksObj = NULL;
static std::shared_mutex callbacks_mutex;

static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
@@ -68,8 +73,9 @@ static void connection_state_cb(const RawAddress* bd_addr,
                                bthf_client_connection_state_t state,
                                unsigned int peer_feat,
                                unsigned int chld_feat) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -82,8 +88,9 @@ static void connection_state_cb(const RawAddress* bd_addr,

static void audio_state_cb(const RawAddress* bd_addr,
                           bthf_client_audio_state_t state) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -93,8 +100,9 @@ static void audio_state_cb(const RawAddress* bd_addr,
}

static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -105,8 +113,9 @@ static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) {

static void network_state_cb(const RawAddress* bd_addr,
                             bthf_client_network_state_t state) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -117,7 +126,9 @@ static void network_state_cb(const RawAddress* bd_addr,

static void network_roaming_cb(const RawAddress* bd_addr,
                               bthf_client_service_type_t type) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -127,8 +138,9 @@ static void network_roaming_cb(const RawAddress* bd_addr,
}

static void network_signal_cb(const RawAddress* bd_addr, int signal) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -138,8 +150,9 @@ static void network_signal_cb(const RawAddress* bd_addr, int signal) {
}

static void battery_level_cb(const RawAddress* bd_addr, int level) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -149,8 +162,9 @@ static void battery_level_cb(const RawAddress* bd_addr, int level) {
}

static void current_operator_cb(const RawAddress* bd_addr, const char* name) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -169,8 +183,9 @@ static void current_operator_cb(const RawAddress* bd_addr, const char* name) {
}

static void call_cb(const RawAddress* bd_addr, bthf_client_call_t call) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -181,8 +196,9 @@ static void call_cb(const RawAddress* bd_addr, bthf_client_call_t call) {

static void callsetup_cb(const RawAddress* bd_addr,
                         bthf_client_callsetup_t callsetup) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -197,8 +213,9 @@ static void callsetup_cb(const RawAddress* bd_addr,

static void callheld_cb(const RawAddress* bd_addr,
                        bthf_client_callheld_t callheld) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -209,8 +226,9 @@ static void callheld_cb(const RawAddress* bd_addr,

static void resp_and_hold_cb(const RawAddress* bd_addr,
                             bthf_client_resp_and_hold_t resp_and_hold) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -220,8 +238,9 @@ static void resp_and_hold_cb(const RawAddress* bd_addr,
}

static void clip_cb(const RawAddress* bd_addr, const char* number) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -240,8 +259,9 @@ static void clip_cb(const RawAddress* bd_addr, const char* number) {
}

static void call_waiting_cb(const RawAddress* bd_addr, const char* number) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -264,8 +284,9 @@ static void current_calls_cb(const RawAddress* bd_addr, int index,
                             bthf_client_call_state_t state,
                             bthf_client_call_mpty_type_t mpty,
                             const char* number) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -285,8 +306,9 @@ static void current_calls_cb(const RawAddress* bd_addr, int index,

static void volume_change_cb(const RawAddress* bd_addr,
                             bthf_client_volume_type_t type, int volume) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -296,8 +318,9 @@ static void volume_change_cb(const RawAddress* bd_addr,

static void cmd_complete_cb(const RawAddress* bd_addr,
                            bthf_client_cmd_complete_t type, int cme) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -307,8 +330,9 @@ static void cmd_complete_cb(const RawAddress* bd_addr,

static void subscriber_info_cb(const RawAddress* bd_addr, const char* name,
                               bthf_client_subscriber_service_type_t type) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -328,8 +352,9 @@ static void subscriber_info_cb(const RawAddress* bd_addr, const char* name,

static void in_band_ring_cb(const RawAddress* bd_addr,
                            bthf_client_in_band_ring_state_t in_band) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -339,8 +364,9 @@ static void in_band_ring_cb(const RawAddress* bd_addr,

static void last_voice_tag_number_cb(const RawAddress* bd_addr,
                                     const char* number) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -359,8 +385,9 @@ static void last_voice_tag_number_cb(const RawAddress* bd_addr,
}

static void ring_indication_cb(const RawAddress* bd_addr) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -370,8 +397,9 @@ static void ring_indication_cb(const RawAddress* bd_addr) {

static void unknown_event_cb(const RawAddress* bd_addr,
                             const char* eventString) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;

  ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
  if (!addr.get()) return;
@@ -446,6 +474,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) {

static void initializeNative(JNIEnv* env, jobject object) {
  ALOGD("%s: HfpClient", __func__);
  std::unique_lock<std::shared_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_mutex> callbacks_lock(callbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
@@ -484,6 +515,9 @@ static void initializeNative(JNIEnv* env, jobject object) {
}

static void cleanupNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_mutex> callbacks_lock(callbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
@@ -504,6 +538,7 @@ static void cleanupNative(JNIEnv* env, jobject object) {
}

static jboolean connectNative(JNIEnv* env, jobject object, jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -522,6 +557,7 @@ static jboolean connectNative(JNIEnv* env, jobject object, jbyteArray address) {

static jboolean disconnectNative(JNIEnv* env, jobject object,
                                 jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -541,6 +577,7 @@ static jboolean disconnectNative(JNIEnv* env, jobject object,

static jboolean connectAudioNative(JNIEnv* env, jobject object,
                                   jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -560,6 +597,7 @@ static jboolean connectAudioNative(JNIEnv* env, jobject object,

static jboolean disconnectAudioNative(JNIEnv* env, jobject object,
                                      jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -579,6 +617,7 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject object,

static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object,
                                            jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -598,6 +637,7 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object,

static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object,
                                           jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -617,6 +657,7 @@ static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object,

static jboolean setVolumeNative(JNIEnv* env, jobject object, jbyteArray address,
                                jint volume_type, jint volume) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -636,6 +677,7 @@ static jboolean setVolumeNative(JNIEnv* env, jobject object, jbyteArray address,

static jboolean dialNative(JNIEnv* env, jobject object, jbyteArray address,
                           jstring number_str) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -664,6 +706,7 @@ static jboolean dialNative(JNIEnv* env, jobject object, jbyteArray address,

static jboolean dialMemoryNative(JNIEnv* env, jobject object,
                                 jbyteArray address, jint location) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -685,6 +728,7 @@ static jboolean dialMemoryNative(JNIEnv* env, jobject object,
static jboolean handleCallActionNative(JNIEnv* env, jobject object,
                                       jbyteArray address, jint action,
                                       jint index) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -705,6 +749,7 @@ static jboolean handleCallActionNative(JNIEnv* env, jobject object,

static jboolean queryCurrentCallsNative(JNIEnv* env, jobject object,
                                        jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -725,6 +770,7 @@ static jboolean queryCurrentCallsNative(JNIEnv* env, jobject object,

static jboolean queryCurrentOperatorNameNative(JNIEnv* env, jobject object,
                                               jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -746,6 +792,7 @@ static jboolean queryCurrentOperatorNameNative(JNIEnv* env, jobject object,

static jboolean retrieveSubscriberInfoNative(JNIEnv* env, jobject object,
                                             jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -766,6 +813,7 @@ static jboolean retrieveSubscriberInfoNative(JNIEnv* env, jobject object,

static jboolean sendDtmfNative(JNIEnv* env, jobject object, jbyteArray address,
                               jbyte code) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -786,6 +834,7 @@ static jboolean sendDtmfNative(JNIEnv* env, jobject object, jbyteArray address,

static jboolean requestLastVoiceTagNumberNative(JNIEnv* env, jobject object,
                                                jbyteArray address) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
@@ -809,6 +858,7 @@ static jboolean requestLastVoiceTagNumberNative(JNIEnv* env, jobject object,
static jboolean sendATCmdNative(JNIEnv* env, jobject object, jbyteArray address,
                                jint cmd, jint val1, jint val2,
                                jstring arg_str) {
  std::shared_lock<std::shared_mutex> lock(interface_mutex);
  if (!sBluetoothHfpClientInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, NULL);
+221 −134

File changed.

Preview size limit exceeded, changes collapsed.