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

Commit 76779745 authored by William Escande's avatar William Escande
Browse files

Add mutex and callback check on a2dp sink interface

pts-bot is flaky on some test and this crash was spotted:
```
JNI DETECTED ERROR IN APPLICATION: obj == null
backtrace:
  _JNIEnv::CallVoidMethod()
  android::bta2dp_connection_state_callback()
```

Test: atest pts-bot
Bug: 245578454
Change-Id: I2c2d624468be53aa11f2e33ffccdb77a5b98468a
parent ddeaef05
Loading
Loading
Loading
Loading
+30 −12
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

#define LOG_TAG "BluetoothA2dpSinkServiceJni"

#include <string.h>

#include <mutex>
#include <shared_mutex>

#include "com_android_bluetooth.h"
#include "hardware/bt_av.h"
#include "utils/Log.h"

#include <string.h>

namespace android {
static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
@@ -29,11 +32,15 @@ static jmethodID method_onAudioConfigChanged;

static const btav_sink_interface_t* sBluetoothA2dpInterface = NULL;
static jobject mCallbacksObj = NULL;
static std::shared_timed_mutex callbacks_mutex;

static void bta2dp_connection_state_callback(const RawAddress& bd_addr,
static void a2dp_sink_connection_state_callback(const RawAddress& bd_addr,
                                                btav_connection_state_t state,
                                                const btav_error_t& error) {
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
  if (!mCallbacksObj) return;

  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

@@ -50,9 +57,12 @@ static void bta2dp_connection_state_callback(const RawAddress& bd_addr,
                               addr.get(), (jint)state);
}

static void bta2dp_audio_state_callback(const RawAddress& bd_addr,
static void a2dp_sink_audio_state_callback(const RawAddress& bd_addr,
                                           btav_audio_state_t state) {
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
  if (!mCallbacksObj) return;

  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

@@ -69,10 +79,13 @@ static void bta2dp_audio_state_callback(const RawAddress& bd_addr,
                               addr.get(), (jint)state);
}

static void bta2dp_audio_config_callback(const RawAddress& bd_addr,
static void a2dp_sink_audio_config_callback(const RawAddress& bd_addr,
                                            uint32_t sample_rate,
                                            uint8_t channel_count) {
  ALOGI("%s", __func__);
  std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
  if (!mCallbacksObj) return;

  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

@@ -91,8 +104,10 @@ static void bta2dp_audio_config_callback(const RawAddress& bd_addr,
}

static btav_sink_callbacks_t sBluetoothA2dpCallbacks = {
    sizeof(sBluetoothA2dpCallbacks), bta2dp_connection_state_callback,
    bta2dp_audio_state_callback, bta2dp_audio_config_callback,
    sizeof(sBluetoothA2dpCallbacks),
    a2dp_sink_connection_state_callback,
    a2dp_sink_audio_state_callback,
    a2dp_sink_audio_config_callback,
};

static void classInitNative(JNIEnv* env, jclass clazz) {
@@ -110,6 +125,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {

static void initNative(JNIEnv* env, jobject object,
                       jint maxConnectedAudioDevices) {
  std::unique_lock<std::shared_timed_mutex> lock(callbacks_mutex);

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

static void cleanupNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> lock(callbacks_mutex);
  const bt_interface_t* btInf = getBluetoothInterface();

  if (btInf == NULL) {