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

Commit 3d0dcd57 authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk Committed by Grzegorz Kolodziejczyk (xWF)
Browse files

broadcaster: Introduce STOPPED audio state

This change introduces STOPPED audio state to cover blocking Audio
Framework calls of suspend, resume callbacks while broadcast is paused.

Bug: 349310336
Bug: 347204335
Flag: com.android.bluetooth.flags.leaudio_big_depends_on_audio_state
Test: atest bluetooth_test_broadcaster
Change-Id: Ifb1052d759eb739005ed4e1e8b1616458207ec58
parent 8234b73e
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -1303,9 +1303,14 @@ public class LeAudioService extends ProfileService {

        Log.d(TAG, "startBroadcast");

        /* For BIG dependent on Audio State, this timer is scheduled in
         * LeAudioService#createBroadcast
         */
        if (!leaudioBigDependsOnAudioState()) {
            /* Start timeout to recover from stucked/error start Broadcast operation */
            mCreateBroadcastTimeoutEvent = new CreateBroadcastTimeoutEvent(broadcastId);
            mHandler.postDelayed(mCreateBroadcastTimeoutEvent, CREATE_BROADCAST_TIMEOUT_MS);
        }

        mLeAudioBroadcasterNativeInterface.startBroadcast(broadcastId);
    }
@@ -3709,10 +3714,7 @@ public class LeAudioService extends ProfileService {
                                if (!leaudioUseAudioModeListener()) {
                                    mQueuedInCallValue = Optional.empty();
                                }
                                if (!leaudioBigDependsOnAudioState()) {
                                    startBroadcast(
                                            mBroadcastIdDeactivatedForUnicastTransition.get());
                                }
                                startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get());
                                mBroadcastIdDeactivatedForUnicastTransition = Optional.empty();
                            }

@@ -3772,10 +3774,8 @@ public class LeAudioService extends ProfileService {
                    mBroadcastSessionStats.put(broadcastId, sessionStats);
                }

                if (!leaudioBigDependsOnAudioState()) {
                // Start sending the actual stream
                startBroadcast(broadcastId);
                }
            } else {
                // TODO: Improve reason reporting or extend the native stack event with reason code
                Log.e(
+7 −14
Original line number Diff line number Diff line
@@ -264,10 +264,7 @@ public class LeAudioBroadcastServiceTest {
        create_event.valueBool1 = true;
        mService.messageFromNative(create_event);

        if (!Flags.leaudioBigDependsOnAudioState()) {
            // Verify if broadcast is auto-started on start
        verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
        }

        // Notify initial paused state
        LeAudioStackEvent state_event =
@@ -1237,11 +1234,11 @@ public class LeAudioBroadcastServiceTest {
        if (Flags.leaudioBigDependsOnAudioState()) {
            /* Verify if broadcast triggers transition */
            Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
        } else {
        }

        /* Verify if broadcast is auto-started on start */
        verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
    }
    }

    @Test
    public void testBroadcastResumeUnicastGroupChangeRequestDriven() {
@@ -1251,10 +1248,7 @@ public class LeAudioBroadcastServiceTest {

        prepareHandoverStreamingBroadcast(groupId, broadcastId, code);

        if (!Flags.leaudioBigDependsOnAudioState()) {
            /* Verify if broadcast is auto-started on start */
        verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
        }

        /* Imitate group change request by Bluetooth Sink HAL resume request */
        LeAudioStackEvent create_event =
@@ -1316,10 +1310,9 @@ public class LeAudioBroadcastServiceTest {
        if (Flags.leaudioBigDependsOnAudioState()) {
            /* Verify if broadcast triggers transition */
            Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
        } else {
            /* Verify if broadcast is auto-started on start */
            verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
        }

        verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
    }

    @Test
+50 −27
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ std::mutex instance_mutex;
 * for test purposes.
 */
class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
  enum class AudioState { SUSPENDED, ACTIVE };
  enum class AudioState { STOPPED, SUSPENDED, ACTIVE };

public:
  LeAudioBroadcasterImpl(bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_)
@@ -695,7 +695,9 @@ public:
          le_audio_source_hal_client_->Stop();
        }
      }
      audio_state_ = AudioState::SUSPENDED;

      /* Block AF requests to resume/suspend stream */
      audio_state_ = AudioState::STOPPED;
      broadcasts_[broadcast_id]->SetMuted(true);
      broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND, nullptr);
    } else {
@@ -718,6 +720,10 @@ public:
  void StartAudioBroadcast(uint32_t broadcast_id) override {
    log::info("Starting broadcast_id={}", broadcast_id);

    if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
      /* Enable possibility for AF to drive stream */
      audio_state_ = AudioState::SUSPENDED;
    } else {
      if (queued_start_broadcast_request_) {
        log::error("Not processed yet start broadcast request");
        return;
@@ -752,6 +758,7 @@ public:
        log::error("No such broadcast_id={}", broadcast_id);
      }
    }
  }

  void StopAudioBroadcast(uint32_t broadcast_id) override {
    if (broadcasts_.count(broadcast_id) == 0) {
@@ -1286,6 +1293,11 @@ private:

      log::verbose("Received {} bytes.", data.size());

      if (instance->audio_state_ == AudioState::STOPPED) {
        log::warn("audio stopped, skip audio data ready callback");
        return;
      }

      if (!broadcast_config_.has_value() || (broadcast_config_->subgroups.size() == 0)) {
        log::error("Codec was not configured properly");
        return;
@@ -1328,6 +1340,11 @@ private:
        return;
      }

      if (instance->audio_state_ == AudioState::STOPPED) {
        log::warn("audio stopped, skip suspend request");
        return;
      }

      instance->audio_state_ = AudioState::SUSPENDED;
      if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
        instance->UpdateAudioActiveStateInPublicAnnouncement();
@@ -1341,6 +1358,12 @@ private:
        return;
      }

      if (instance->audio_state_ == AudioState::STOPPED) {
        log::warn("audio stopped, skip resume request");
        instance->le_audio_source_hal_client_->CancelStreamingRequest();
        return;
      }

      instance->audio_state_ = AudioState::ACTIVE;
      if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
        instance->cancelBroadcastTimers();