leaudio: Fix possible race on start stream request from HAL

Bug: 322106376
Bug: 325181889
Test: mmm packages/modules/Bluetooth
Test: manual streaming regression tests

Change-Id: I079c9081dd165c77c7a1547c274f4c7c1d7bbf05
diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
index 87cf547..f986e1b 100644
--- a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
+++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
@@ -108,6 +108,43 @@
   return BluetoothAudioCtrlAck::FAILURE;
 }
 
+BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2(bool is_low_latency) {
+  // Check if operation is pending already
+  if (GetStartRequestState() == StartRequestState::PENDING_AFTER_RESUME) {
+    LOG_INFO("Start request is already pending. Ignore the request");
+    return BluetoothAudioCtrlAck::PENDING;
+  }
+
+  SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
+  if (stream_cb_.on_resume_(true)) {
+    std::lock_guard<std::mutex> guard(start_request_state_mutex_);
+
+    switch (start_request_state_) {
+      case StartRequestState::CONFIRMED:
+        LOG_INFO("Start completed.");
+        SetStartRequestState(StartRequestState::IDLE);
+        return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
+      case StartRequestState::CANCELED:
+        LOG_INFO("Start request failed.");
+        SetStartRequestState(StartRequestState::IDLE);
+        return BluetoothAudioCtrlAck::FAILURE;
+      case StartRequestState::PENDING_BEFORE_RESUME:
+        LOG_INFO("Start pending.");
+        SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
+        return BluetoothAudioCtrlAck::PENDING;
+      default:
+        SetStartRequestState(StartRequestState::IDLE);
+        LOG_ERROR("Unexpected state %d",
+                  static_cast<int>(start_request_state_.load()));
+        return BluetoothAudioCtrlAck::FAILURE;
+    }
+  }
+
+  SetStartRequestState(StartRequestState::IDLE);
+  LOG_INFO("On resume failed.");
+  return BluetoothAudioCtrlAck::FAILURE;
+}
+
 BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() {
   LOG(INFO) << __func__;
   if (stream_cb_.on_suspend_()) {
@@ -245,6 +282,23 @@
   return broadcast_config_;
 }
 
+bool LeAudioTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  std::lock_guard<std::mutex> guard(start_request_state_mutex_);
+  auto result = lambda(start_request_state_);
+  auto new_state = std::get<0>(result);
+  if (new_state != start_request_state_) {
+    start_request_state_ = new_state;
+  }
+
+  auto ret = std::get<1>(result);
+  LOG_VERBOSE(" new state: %d, return %s", (int)(start_request_state_.load()),
+              ret ? "true" : "false");
+
+  return ret;
+}
+
 StartRequestState LeAudioTransport::GetStartRequestState(void) {
   return start_request_state_;
 }
@@ -290,6 +344,9 @@
 LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; }
 
 BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest(bool is_low_latency) {
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    return transport_->StartRequestV2(is_low_latency);
+  }
   return transport_->StartRequest(is_low_latency);
 }
 
@@ -353,6 +410,12 @@
   return transport_->LeAudioGetBroadcastConfig();
 }
 
+bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  return transport_->IsRequestCompletedAfterUpdate(lambda);
+}
+
 StartRequestState LeAudioSinkTransport::GetStartRequestState(void) {
   return transport_->GetStartRequestState();
 }
@@ -380,6 +443,9 @@
 
 BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest(
     bool is_low_latency) {
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    return transport_->StartRequestV2(is_low_latency);
+  }
   return transport_->StartRequest(is_low_latency);
 }
 
@@ -434,6 +500,12 @@
                                              channels_count, data_interval);
 }
 
+bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  return transport_->IsRequestCompletedAfterUpdate(lambda);
+}
+
 StartRequestState LeAudioSourceTransport::GetStartRequestState(void) {
   return transport_->GetStartRequestState();
 }
diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.h b/system/audio_hal_interface/aidl/le_audio_software_aidl.h
index c75a76d..98f0dfd 100644
--- a/system/audio_hal_interface/aidl/le_audio_software_aidl.h
+++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.h
@@ -71,6 +71,7 @@
                    PcmConfiguration pcm_config);
 
   BluetoothAudioCtrlAck StartRequest(bool is_low_latency);
+  BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency);
 
   BluetoothAudioCtrlAck SuspendRequest();
 
@@ -103,6 +104,9 @@
 
   const LeAudioBroadcastConfiguration& LeAudioGetBroadcastConfig();
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
@@ -115,6 +119,7 @@
   timespec data_position_;
   PcmConfiguration pcm_config_;
   LeAudioBroadcastConfiguration broadcast_config_;
+  mutable std::mutex start_request_state_mutex_;
   std::atomic<StartRequestState> start_request_state_;
   DsaMode dsa_mode_;
 };
@@ -128,6 +133,7 @@
   ~LeAudioSinkTransport();
 
   BluetoothAudioCtrlAck StartRequest(bool is_low_latency) override;
+  BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency);
 
   BluetoothAudioCtrlAck SuspendRequest() override;
 
@@ -161,6 +167,9 @@
 
   const LeAudioBroadcastConfiguration& LeAudioGetBroadcastConfig();
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
@@ -184,6 +193,7 @@
   ~LeAudioSourceTransport();
 
   BluetoothAudioCtrlAck StartRequest(bool is_low_latency) override;
+  BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency);
 
   BluetoothAudioCtrlAck SuspendRequest() override;
 
@@ -212,6 +222,10 @@
                                       uint8_t channels_count,
                                       uint32_t data_interval);
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
+
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
diff --git a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
index 8bc4b6a..1cf3e25 100644
--- a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
+++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
@@ -134,6 +134,32 @@
   return BluetoothAudioCtrlAck::FAILURE;
 }
 
+BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2() {
+  SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
+  if (stream_cb_.on_resume_(true)) {
+    std::lock_guard<std::mutex> guard(start_request_state_mutex_);
+    if (start_request_state_ == StartRequestState::CONFIRMED) {
+      LOG_INFO("Start completed.");
+      SetStartRequestState(StartRequestState::IDLE);
+      return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
+    }
+
+    if (start_request_state_ == StartRequestState::CANCELED) {
+      LOG_INFO("Start request failed.");
+      SetStartRequestState(StartRequestState::IDLE);
+      return BluetoothAudioCtrlAck::FAILURE;
+    }
+
+    LOG_INFO("Start pending.");
+    SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
+    return BluetoothAudioCtrlAck::PENDING;
+  }
+
+  LOG_ERROR("Start request failed.");
+  SetStartRequestState(StartRequestState::IDLE);
+  return BluetoothAudioCtrlAck::FAILURE;
+}
+
 BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() {
   LOG(INFO) << __func__;
   if (stream_cb_.on_suspend_()) {
@@ -227,6 +253,22 @@
   pcm_config_.dataIntervalUs = data_interval;
 }
 
+bool LeAudioTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  std::lock_guard<std::mutex> guard(start_request_state_mutex_);
+  auto result = lambda(start_request_state_);
+  auto new_state = std::get<0>(result);
+  if (new_state != start_request_state_) {
+    start_request_state_ = new_state;
+  }
+
+  auto ret = std::get<1>(result);
+  LOG_VERBOSE("new state: %d, return: %s",
+              static_cast<int>(start_request_state_.load()), ret);
+  return ret;
+}
+
 StartRequestState LeAudioTransport::GetStartRequestState(void) {
   return start_request_state_;
 }
@@ -255,6 +297,9 @@
 LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; }
 
 BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest() {
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    return transport_->StartRequestV2();
+  }
   return transport_->StartRequest();
 }
 
@@ -299,6 +344,12 @@
                                              channels_count, data_interval);
 }
 
+bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  return transport_->IsRequestCompletedAfterUpdate(lambda);
+}
+
 StartRequestState LeAudioSinkTransport::GetStartRequestState(void) {
   return transport_->GetStartRequestState();
 }
@@ -327,6 +378,9 @@
 LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; }
 
 BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest() {
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    return transport_->StartRequestV2();
+  }
   return transport_->StartRequest();
 }
 
@@ -371,6 +425,11 @@
                                              channels_count, data_interval);
 }
 
+bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate(
+    const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
+        lambda) {
+  return transport_->IsRequestCompletedAfterUpdate(lambda);
+}
 StartRequestState LeAudioSourceTransport::GetStartRequestState(void) {
   return transport_->GetStartRequestState();
 }
diff --git a/system/audio_hal_interface/hidl/le_audio_software_hidl.h b/system/audio_hal_interface/hidl/le_audio_software_hidl.h
index 80051f8..058888b 100644
--- a/system/audio_hal_interface/hidl/le_audio_software_hidl.h
+++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.h
@@ -60,6 +60,7 @@
                    PcmParameters pcm_config);
 
   BluetoothAudioCtrlAck StartRequest();
+  BluetoothAudioCtrlAck StartRequestV2();
 
   BluetoothAudioCtrlAck SuspendRequest();
 
@@ -83,6 +84,10 @@
                                       uint8_t channels_count,
                                       uint32_t data_interval);
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
+
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
@@ -94,6 +99,7 @@
   uint64_t total_bytes_processed_;
   timespec data_position_;
   PcmParameters pcm_config_;
+  mutable std::mutex start_request_state_mutex_;
   std::atomic<StartRequestState> start_request_state_;
 };
 
@@ -106,6 +112,7 @@
   ~LeAudioSinkTransport();
 
   BluetoothAudioCtrlAck StartRequest() override;
+  BluetoothAudioCtrlAck StartRequestV2();
 
   BluetoothAudioCtrlAck SuspendRequest() override;
 
@@ -129,6 +136,10 @@
                                       uint8_t channels_count,
                                       uint32_t data_interval);
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
+
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
@@ -172,6 +183,9 @@
                                       uint8_t channels_count,
                                       uint32_t data_interval);
 
+  bool IsRequestCompletedAfterUpdate(
+      const std::function<
+          std::pair<StartRequestState, bool>(StartRequestState)>& lambda);
   StartRequestState GetStartRequestState(void);
   void ClearStartRequestState(void);
   void SetStartRequestState(StartRequestState state);
diff --git a/system/audio_hal_interface/le_audio_software.cc b/system/audio_hal_interface/le_audio_software.cc
index 6a999e9..25120c7 100644
--- a/system/audio_hal_interface/le_audio_software.cc
+++ b/system/audio_hal_interface/le_audio_software.cc
@@ -262,6 +262,44 @@
   }
 }
 
+void LeAudioClientInterface::Sink::ConfirmStreamingRequestV2() {
+  auto lambda = [&](StartRequestState currect_start_request_state)
+      -> std::pair<StartRequestState, bool> {
+    switch (currect_start_request_state) {
+      case StartRequestState::IDLE:
+        LOG_WARN(", no pending start stream request");
+        return std::make_pair(StartRequestState::IDLE, false);
+      case StartRequestState::PENDING_BEFORE_RESUME:
+        LOG_INFO("Response before sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::CONFIRMED, false);
+      case StartRequestState::PENDING_AFTER_RESUME:
+        LOG_INFO("Response after sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::IDLE, true);
+      case StartRequestState::CONFIRMED:
+      case StartRequestState::CANCELED:
+        LOG_ERROR("Invalid state, start stream already confirmed");
+        return std::make_pair(currect_start_request_state, false);
+    }
+  };
+
+  if (HalVersionManager::GetHalTransport() ==
+      BluetoothAudioHalTransport::HIDL) {
+    auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance;
+    if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+      hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted(
+          hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
+    }
+
+    return;
+  }
+
+  auto aidl_instance = get_aidl_transport_instance(is_broadcaster_);
+  if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+    get_aidl_client_interface(is_broadcaster_)
+        ->StreamStarted(aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
+  }
+}
+
 void LeAudioClientInterface::Sink::CancelStreamingRequest() {
   if (HalVersionManager::GetHalTransport() ==
       BluetoothAudioHalTransport::HIDL) {
@@ -287,6 +325,33 @@
         break;
     }
   }
+}
+
+void LeAudioClientInterface::Sink::CancelStreamingRequestV2() {
+  if (HalVersionManager::GetHalTransport() ==
+      BluetoothAudioHalTransport::HIDL) {
+    auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance;
+    auto start_request_state = hidl_instance->GetStartRequestState();
+    switch (start_request_state) {
+      case StartRequestState::IDLE:
+        LOG_WARN(", no pending start stream request");
+        return;
+      case StartRequestState::PENDING_BEFORE_RESUME:
+        LOG_INFO("Response before sending PENDING to audio HAL");
+        hidl_instance->SetStartRequestState(StartRequestState::CANCELED);
+        return;
+      case StartRequestState::PENDING_AFTER_RESUME:
+        LOG_INFO("Response after sending PENDING to audio HAL");
+        hidl_instance->ClearStartRequestState();
+        hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted(
+            hidl::BluetoothAudioCtrlAck::FAILURE);
+        return;
+      case StartRequestState::CONFIRMED:
+      case StartRequestState::CANCELED:
+        LOG_ERROR("Invalid state, start stream already confirmed");
+        break;
+    }
+  }
 
   auto aidl_instance = get_aidl_transport_instance(is_broadcaster_);
   auto start_request_state = aidl_instance->GetStartRequestState();
@@ -549,6 +614,46 @@
   }
 }
 
+void LeAudioClientInterface::Source::ConfirmStreamingRequestV2() {
+  LOG_INFO("Rymek source");
+
+  auto lambda = [&](StartRequestState currect_start_request_state)
+      -> std::pair<StartRequestState, bool> {
+    switch (currect_start_request_state) {
+      case StartRequestState::IDLE:
+        LOG_WARN(", no pending start stream request");
+        return std::make_pair(StartRequestState::IDLE, false);
+      case StartRequestState::PENDING_BEFORE_RESUME:
+        LOG_INFO("Response before sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::CONFIRMED, false);
+      case StartRequestState::PENDING_AFTER_RESUME:
+        LOG_INFO("Response after sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::IDLE, true);
+      case StartRequestState::CONFIRMED:
+      case StartRequestState::CANCELED:
+        LOG_ERROR("Invalid state, start stream already confirmed");
+        return std::make_pair(currect_start_request_state, false);
+    }
+  };
+
+  if (HalVersionManager::GetHalTransport() ==
+      BluetoothAudioHalTransport::HIDL) {
+    auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance;
+
+    if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+      hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
+          hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
+    }
+    return;
+  }
+
+  auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance;
+  if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+    aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
+        aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
+  }
+}
+
 void LeAudioClientInterface::Source::CancelStreamingRequest() {
   if (HalVersionManager::GetHalTransport() ==
       BluetoothAudioHalTransport::HIDL) {
@@ -598,6 +703,43 @@
   }
 }
 
+void LeAudioClientInterface::Source::CancelStreamingRequestV2() {
+  auto lambda = [&](StartRequestState currect_start_request_state)
+      -> std::pair<StartRequestState, bool> {
+    switch (currect_start_request_state) {
+      case StartRequestState::IDLE:
+        LOG_WARN(", no pending start stream request");
+        return std::make_pair(StartRequestState::IDLE, false);
+      case StartRequestState::PENDING_BEFORE_RESUME:
+        LOG_INFO("Response before sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::CANCELED, false);
+      case StartRequestState::PENDING_AFTER_RESUME:
+        LOG_INFO("Response after sending PENDING to audio HAL");
+        return std::make_pair(StartRequestState::IDLE, true);
+      case StartRequestState::CONFIRMED:
+      case StartRequestState::CANCELED:
+        LOG_ERROR("Invalid state, start stream already confirmed");
+        return std::make_pair(currect_start_request_state, false);
+    }
+  };
+
+  if (HalVersionManager::GetHalTransport() ==
+      BluetoothAudioHalTransport::HIDL) {
+    auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance;
+    if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+      hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
+          hidl::BluetoothAudioCtrlAck::FAILURE);
+    }
+    return;
+  }
+
+  auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance;
+  if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
+    aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
+        aidl::BluetoothAudioCtrlAck::FAILURE);
+  }
+}
+
 void LeAudioClientInterface::Source::StopSession() {
   LOG(INFO) << __func__ << " source";
   if (HalVersionManager::GetHalTransport() ==
diff --git a/system/audio_hal_interface/le_audio_software.h b/system/audio_hal_interface/le_audio_software.h
index 4544387..56c6f75 100644
--- a/system/audio_hal_interface/le_audio_software.h
+++ b/system/audio_hal_interface/le_audio_software.h
@@ -22,6 +22,8 @@
 #include <hardware/audio.h>
 #endif
 
+#include <android_bluetooth_flags.h>
+
 #include <functional>
 
 #include "bta/le_audio/codec_manager.h"
@@ -87,6 +89,8 @@
     virtual void StopSession() = 0;
     virtual void ConfirmStreamingRequest() = 0;
     virtual void CancelStreamingRequest() = 0;
+    virtual void ConfirmStreamingRequestV2() = 0;
+    virtual void CancelStreamingRequestV2() = 0;
     virtual void UpdateAudioConfigToHal(
         const ::le_audio::offload_config& config) = 0;
     virtual void SuspendedForReconfiguration() = 0;
@@ -106,6 +110,8 @@
     void StopSession() override;
     void ConfirmStreamingRequest() override;
     void CancelStreamingRequest() override;
+    void ConfirmStreamingRequestV2() override;
+    void CancelStreamingRequestV2() override;
     void UpdateAudioConfigToHal(
         const ::le_audio::offload_config& config) override;
     void UpdateBroadcastAudioConfigToHal(
@@ -130,6 +136,8 @@
     void StopSession() override;
     void ConfirmStreamingRequest() override;
     void CancelStreamingRequest() override;
+    void ConfirmStreamingRequestV2() override;
+    void CancelStreamingRequestV2() override;
     void UpdateAudioConfigToHal(
         const ::le_audio::offload_config& config) override;
     void SuspendedForReconfiguration() override;
diff --git a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
index 7f0abeb..ab9dc77 100644
--- a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
@@ -177,6 +177,8 @@
 void LeAudioClientInterface::Sink::StopSession() {}
 void LeAudioClientInterface::Sink::ConfirmStreamingRequest(){};
 void LeAudioClientInterface::Sink::CancelStreamingRequest(){};
+void LeAudioClientInterface::Sink::ConfirmStreamingRequestV2(){};
+void LeAudioClientInterface::Sink::CancelStreamingRequestV2(){};
 void LeAudioClientInterface::Sink::UpdateAudioConfigToHal(
     const ::le_audio::offload_config& config){};
 void LeAudioClientInterface::Sink::UpdateBroadcastAudioConfigToHal(
@@ -192,6 +194,8 @@
 void LeAudioClientInterface::Source::StopSession() {}
 void LeAudioClientInterface::Source::ConfirmStreamingRequest(){};
 void LeAudioClientInterface::Source::CancelStreamingRequest(){};
+void LeAudioClientInterface::Source::ConfirmStreamingRequestV2(){};
+void LeAudioClientInterface::Source::CancelStreamingRequestV2(){};
 void LeAudioClientInterface::Source::UpdateAudioConfigToHal(
     const ::le_audio::offload_config& config){};
 void LeAudioClientInterface::Source::SuspendedForReconfiguration() {}
diff --git a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
index ac51648..3ed2225 100644
--- a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
@@ -257,7 +257,11 @@
   }
 
   LOG_INFO();
-  halSourceInterface_->ConfirmStreamingRequest();
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    halSourceInterface_->ConfirmStreamingRequestV2();
+  } else {
+    halSourceInterface_->ConfirmStreamingRequest();
+  }
 }
 
 void SinkImpl::SuspendedForReconfiguration() {
@@ -290,7 +294,11 @@
   }
 
   LOG_INFO();
-  halSourceInterface_->CancelStreamingRequest();
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    halSourceInterface_->CancelStreamingRequestV2();
+  } else {
+    halSourceInterface_->CancelStreamingRequest();
+  }
 }
 
 void SinkImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) {
diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
index 1e5e7e2..7290297 100644
--- a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
@@ -381,7 +381,11 @@
   }
 
   LOG_INFO();
-  halSinkInterface_->ConfirmStreamingRequest();
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    halSinkInterface_->ConfirmStreamingRequestV2();
+  } else {
+    halSinkInterface_->ConfirmStreamingRequest();
+  }
   if (CodecManager::GetInstance()->GetCodecLocation() !=
       types::CodecLocation::HOST)
     return;
@@ -419,7 +423,11 @@
   }
 
   LOG_INFO();
-  halSinkInterface_->CancelStreamingRequest();
+  if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) {
+    halSinkInterface_->CancelStreamingRequestV2();
+  } else {
+    halSinkInterface_->CancelStreamingRequest();
+  }
 }
 
 void SourceImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) {