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

Commit aec18d0a authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Fix dumpsys race condition

Dumpsys called from another thread may break
when the service is starting or shutting down.

Bug: 269702046
Test: atest --host bluetooth_le_audio_client_test bluetooth_le_audio_test bluetooth_vc_test bluetooth_csis_test bluetooth_has_test bluetooth_test_broadcaster
Change-Id: I5edb80668b8889d55e6bdaa38fe96803f86b412e
parent 423dd861
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <hardware/bt_gatt_types.h>

#include <list>
#include <mutex>
#include <string>
#include <vector>

@@ -67,6 +68,7 @@ using bluetooth::groups::DeviceGroupsCallbacks;
namespace {
class CsisClientImpl;
CsisClientImpl* instance;
std::mutex instance_mutex;
DeviceGroupsCallbacks* device_group_callbacks;

/**
@@ -2035,6 +2037,7 @@ DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;

void CsisClient::Initialize(bluetooth::csis::CsisClientCallbacks* callbacks,
                            Closure initCb) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  if (instance) {
    LOG(ERROR) << __func__ << ": Already initialized!";
    return;
@@ -2073,6 +2076,7 @@ bool CsisClient::GetForStorage(const RawAddress& addr,
}

void CsisClient::CleanUp() {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  CsisClientImpl* ptr = instance;
  instance = nullptr;

@@ -2083,6 +2087,7 @@ void CsisClient::CleanUp() {
}

void CsisClient::DebugDump(int fd) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  dprintf(fd, "Coordinated Set Service Client:\n");
  if (instance) instance->Dump(fd);
  dprintf(fd, "\n");
+5 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <algorithm>
#include <limits>
#include <map>
#include <mutex>
#include <unordered_set>

#include "bta_groups.h"
@@ -34,6 +35,7 @@ namespace groups {

class DeviceGroupsImpl;
DeviceGroupsImpl* instance;
std::mutex instance_mutex;
static constexpr int kMaxGroupId = 0xEF;

class DeviceGroup {
@@ -328,6 +330,7 @@ class DeviceGroupsImpl : public DeviceGroups {
};

void DeviceGroups::Initialize(DeviceGroupsCallbacks* callbacks) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  if (instance == nullptr) {
    instance = new DeviceGroupsImpl(callbacks);
    return;
@@ -357,6 +360,7 @@ bool DeviceGroups::GetForStorage(const RawAddress& addr,
}

void DeviceGroups::CleanUp(DeviceGroupsCallbacks* callbacks) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  if (!instance) return;

  if (instance->Clear(callbacks)) {
@@ -377,6 +381,7 @@ std::ostream& operator<<(std::ostream& out,
}

void DeviceGroups::DebugDump(int fd) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  dprintf(fd, "Device Groups Manager:\n");
  if (instance)
    instance->Dump(fd);
+5 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <list>
#include <map>
#include <mutex>
#include <string>
#include <vector>

@@ -91,6 +92,7 @@ extern bool gatt_profile_get_eatt_support(const RawAddress& remote_bda);
namespace {
class HasClientImpl;
HasClientImpl* instance;
std::mutex instance_mutex;

/**
 * -----------------------------------------------------------------------------
@@ -2112,6 +2114,7 @@ alarm_callback_t HasCtpGroupOpCoordinator::cb = [](void*) {};

void HasClient::Initialize(bluetooth::has::HasClientCallbacks* callbacks,
                           base::Closure initCb) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  if (instance) {
    LOG(ERROR) << "Already initialized!";
    return;
@@ -2140,6 +2143,7 @@ void HasClient::AddFromStorage(const RawAddress& addr, uint8_t features,
};

void HasClient::CleanUp() {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  HasClientImpl* ptr = instance;
  instance = nullptr;

@@ -2152,6 +2156,7 @@ void HasClient::CleanUp() {
};

void HasClient::DebugDump(int fd) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  dprintf(fd, "Hearing Access Service Client:\n");
  if (instance)
    instance->Dump(fd);
+5 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <base/strings/string_number_conversions.h>  // HexEncode

#include <cstdint>
#include <mutex>
#include <vector>

#include "bta/include/bta_gatt_api.h"
@@ -125,6 +126,7 @@ inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {

class HearingAidImpl;
HearingAidImpl* instance;
std::mutex instance_mutex;
HearingAidAudioReceiver* audioReceiver;

class HearingDevices {
@@ -2018,6 +2020,7 @@ HearingAidAudioReceiverImpl audioReceiverImpl;

void HearingAid::Initialize(
    bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  if (instance) {
    LOG_ERROR("Already initialized!");
    return;
@@ -2081,6 +2084,7 @@ int HearingAid::GetDeviceCount() {
}

void HearingAid::CleanUp() {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  // Must stop audio source to make sure it doesn't call any of callbacks on our
  // soon to be  null instance
  HearingAidAudioSource::Stop();
@@ -2095,6 +2099,7 @@ void HearingAid::CleanUp() {
};

void HearingAid::DebugDump(int fd) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  dprintf(fd, "Hearing Aid Manager:\n");
  if (instance) instance->Dump(fd);
  HearingAidAudioSource::DebugDump(fd);
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@

#include <base/functional/bind.h>

#include <mutex>

#include "bta/include/bta_le_audio_api.h"
#include "bta/include/bta_le_audio_broadcaster_api.h"
#include "bta/le_audio/broadcaster/state_machine.h"
@@ -62,6 +64,7 @@ using le_audio::utils::GetAllowedAudioContextsFromSourceMetadata;
namespace {
class LeAudioBroadcasterImpl;
LeAudioBroadcasterImpl* instance;
std::mutex instance_mutex;

/* Class definitions */

@@ -1019,6 +1022,7 @@ LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl
void LeAudioBroadcaster::Initialize(
    bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks,
    base::Callback<bool()> audio_hal_verifier) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  LOG_INFO();
  if (instance) {
    LOG_ERROR("Already initialized");
@@ -1059,6 +1063,7 @@ void LeAudioBroadcaster::Stop(void) {
}

void LeAudioBroadcaster::Cleanup(void) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  LOG_INFO();

  if (instance == nullptr) return;
@@ -1071,6 +1076,7 @@ void LeAudioBroadcaster::Cleanup(void) {
}

void LeAudioBroadcaster::DebugDump(int fd) {
  std::scoped_lock<std::mutex> lock(instance_mutex);
  dprintf(fd, "Le Audio Broadcaster:\n");
  if (instance) instance->Dump(fd);
  dprintf(fd, "\n");
Loading