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

Commit 67092584 authored by Rongxuan Liu's avatar Rongxuan Liu Committed by Gerrit Code Review
Browse files

Merge "broadcast: Remove redundant broadcast start" into main

parents 331c0fb7 a3eefca8
Loading
Loading
Loading
Loading
+125 −72
Original line number Diff line number Diff line
@@ -117,6 +117,9 @@ public class LeAudioService extends ProfileService {
    // Timeout for state machine thread join, to prevent potential ANR.
    private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;

    /* 5 seconds timeout for Broadcast streaming state transition */
    private static final int CREATE_BROADCAST_TIMEOUT_MS = 5000;

    private static LeAudioService sLeAudioService;

    /** Indicates group audio support for none direction */
@@ -151,9 +154,6 @@ public class LeAudioService extends ProfileService {
                    .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000)
                    .build();

    /* 5 seconds timeout for Broadcast streaming state transition */
    private static final int DIALING_OUT_TIMEOUT_MS = 5000;

    private AdapterService mAdapterService;
    private DatabaseManager mDatabaseManager;
    private HandlerThread mStateMachinesThread;
@@ -165,6 +165,8 @@ public class LeAudioService extends ProfileService {
    private final ReentrantReadWriteLock mGroupReadWriteLock = new ReentrantReadWriteLock();
    private final Lock mGroupReadLock = mGroupReadWriteLock.readLock();
    private final Lock mGroupWriteLock = mGroupReadWriteLock.writeLock();
    private CreateBroadcastTimeoutEvent mCreateBroadcastTimeoutEvent;

    ServiceFactory mServiceFactory = new ServiceFactory();

    private final LeAudioNativeInterface mNativeInterface;
@@ -182,7 +184,6 @@ public class LeAudioService extends ProfileService {
    BluetoothDevice mLeAudioDeviceInactivatedForHfpHandover = null;

    LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface = null;
    private DialingOutTimeoutEvent mDialingOutTimeoutEvent = null;
    @VisibleForTesting AudioManager mAudioManager;
    LeAudioTmapGattServer mTmapGattServer;
    int mTmapRoleMask;
@@ -653,7 +654,7 @@ public class LeAudioService extends ProfileService {
        mIsSinkStreamMonitorModeEnabled = false;
        mIsBroadcastPausedFromOutside = false;

        clearBroadcastTimeoutCallback();
        clearCreateBroadcastTimeoutCallback();

        if (!Flags.leaudioSynchronizeStart()) {
            mHandler.removeCallbacks(this::init);
@@ -1148,29 +1149,48 @@ public class LeAudioService extends ProfileService {
        return LE_AUDIO_GROUP_ID_INVALID;
    }

    /**
     * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings.
     *
     * @param broadcastSettings broadcast settings for this broadcast source
     */
    public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) {
    private int canBroadcastBeCreated(BluetoothLeBroadcastSettings broadcastSettings) {
        if (mBroadcastDescriptors.size() >= getMaximumNumberOfBroadcasts()) {
            Log.w(
                    TAG,
                    "createBroadcast reached maximum allowed broadcasts number: "
                            + getMaximumNumberOfBroadcasts());
            mHandler.post(
                    () ->
                            notifyBroadcastStartFailed(
                                    BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES));
            return;
            return BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES;
        }

        byte[] broadcastCode = broadcastSettings.getBroadcastCode();
        if (broadcastCode != null && ((broadcastCode.length > 16) || (broadcastCode.length < 4))) {
            Log.e(TAG, "Invalid broadcast code length. Should be from 4 to 16 octets long.");
            return BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_CODE;
        }

        List<BluetoothLeBroadcastSubgroupSettings> settingsList =
                broadcastSettings.getSubgroupSettings();
        if (settingsList == null || settingsList.size() < 1) {
            Log.d(TAG, "subgroup settings is not valid value");
            return BluetoothStatusCodes.ERROR_BAD_PARAMETERS;
        }

        return BluetoothStatusCodes.SUCCESS;
    }

    /**
     * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings.
     *
     * @param broadcastSettings broadcast settings for this broadcast source
     */
    public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) {
        if (mLeAudioBroadcasterNativeInterface == null) {
            Log.w(TAG, "Native interface not available.");
            return;
        }

        int canBroadcastBeCreatedReturnCode = canBroadcastBeCreated(broadcastSettings);
        if (canBroadcastBeCreatedReturnCode != BluetoothStatusCodes.SUCCESS) {
            mHandler.post(() -> notifyBroadcastStartFailed(canBroadcastBeCreatedReturnCode));
            return;
        }

        if (mAwaitingBroadcastCreateResponse) {
            mCreateBroadcastQueue.add(broadcastSettings);
            Log.i(TAG, "Broadcast creation queued due to waiting for a previous request response.");
@@ -1192,21 +1212,6 @@ public class LeAudioService extends ProfileService {
            }
        }

        byte[] broadcastCode = broadcastSettings.getBroadcastCode();
        boolean isEncrypted = (broadcastCode != null) && (broadcastCode.length != 0);
        if (isEncrypted) {
            if ((broadcastCode.length > 16) || (broadcastCode.length < 4)) {
                Log.e(TAG, "Invalid broadcast code length. Should be from 4 to 16 octets long.");
                return;
            }
        }

        List<BluetoothLeBroadcastSubgroupSettings> settingsList =
                broadcastSettings.getSubgroupSettings();
        if (settingsList == null || settingsList.size() < 1) {
            Log.d(TAG, "subgroup settings is not valid value");
            return;
        }
        mBroadcastSessionStats.put(
                INVALID_BROADCAST_ID,
                new LeAudioBroadcastSessionStats(broadcastSettings, SystemClock.elapsedRealtime()));
@@ -1214,19 +1219,37 @@ public class LeAudioService extends ProfileService {
        BluetoothLeAudioContentMetadata publicMetadata =
                broadcastSettings.getPublicBroadcastMetadata();

        Log.i(TAG, "createBroadcast: isEncrypted=" + (isEncrypted ? "true" : "false"));
        byte[] broadcastCode = broadcastSettings.getBroadcastCode();
        Log.i(
                TAG,
                "createBroadcast: isEncrypted="
                        + (((broadcastCode != null) && (broadcastCode.length != 0))
                                ? "true"
                                : "false"));

        mAwaitingBroadcastCreateResponse = true;
        if (leaudioBigDependsOnAudioState()) {
            mCreateBroadcastQueue.add(broadcastSettings);
        }

        if (leaudioBigDependsOnAudioState()) {
            /* Start timeout to recover from stucked/error create Broadcast operation */
            if (mCreateBroadcastTimeoutEvent != null) {
                Log.w(TAG, "CreateBroadcastTimeoutEvent already scheduled");
            } else {
                mCreateBroadcastTimeoutEvent = new CreateBroadcastTimeoutEvent();
                mHandler.postDelayed(mCreateBroadcastTimeoutEvent, CREATE_BROADCAST_TIMEOUT_MS);
            }
        }

        mLeAudioBroadcasterNativeInterface.createBroadcast(
                broadcastSettings.isPublicBroadcast(),
                broadcastSettings.getBroadcastName(),
                broadcastCode,
                publicMetadata == null ? null : publicMetadata.getRawMetadata(),
                getBroadcastAudioQualityPerSinkCapabilities(settingsList),
                settingsList.stream()
                getBroadcastAudioQualityPerSinkCapabilities(
                        broadcastSettings.getSubgroupSettings()),
                broadcastSettings.getSubgroupSettings().stream()
                        .map(s -> s.getContentMetadata().getRawMetadata())
                        .toArray(byte[][]::new));
    }
@@ -1280,8 +1303,8 @@ public class LeAudioService extends ProfileService {
        Log.d(TAG, "startBroadcast");

        /* Start timeout to recover from stucked/error start Broadcast operation */
        mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(broadcastId);
        mHandler.postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS);
        mCreateBroadcastTimeoutEvent = new CreateBroadcastTimeoutEvent(broadcastId);
        mHandler.postDelayed(mCreateBroadcastTimeoutEvent, CREATE_BROADCAST_TIMEOUT_MS);

        mLeAudioBroadcasterNativeInterface.startBroadcast(broadcastId);
    }
@@ -3181,19 +3204,19 @@ public class LeAudioService extends ProfileService {
        setActiveDevice(unicastDevice);
    }

    void clearBroadcastTimeoutCallback() {
    private void clearCreateBroadcastTimeoutCallback() {
        if (mHandler == null) {
            Log.e(TAG, "No callback handler");
            return;
        }

        /* Timeout callback already cleared */
        if (mDialingOutTimeoutEvent == null) {
        if (mCreateBroadcastTimeoutEvent == null) {
            return;
        }

        mHandler.removeCallbacks(mDialingOutTimeoutEvent);
        mDialingOutTimeoutEvent = null;
        mHandler.removeCallbacks(mCreateBroadcastTimeoutEvent);
        mCreateBroadcastTimeoutEvent = null;
    }

    void notifyAudioFrameworkForCodecConfigUpdate(
@@ -3669,7 +3692,10 @@ public class LeAudioService extends ProfileService {
                                if (!leaudioUseAudioModeListener()) {
                                    mQueuedInCallValue = Optional.empty();
                                }
                                startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get());
                                if (!leaudioBigDependsOnAudioState()) {
                                    startBroadcast(
                                            mBroadcastIdDeactivatedForUnicastTransition.get());
                                }
                                mBroadcastIdDeactivatedForUnicastTransition = Optional.empty();
                            }

@@ -3729,9 +3755,10 @@ 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(
@@ -3744,7 +3771,9 @@ public class LeAudioService extends ProfileService {
                if ((mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID)
                        && mCreateBroadcastQueue.isEmpty()
                        && (!Objects.equals(device, mActiveBroadcastAudioDevice))) {
                    clearBroadcastTimeoutCallback();
                    if (!leaudioBigDependsOnAudioState()) {
                        clearCreateBroadcastTimeoutCallback();
                    }
                    updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false);
                }

@@ -3755,6 +3784,9 @@ public class LeAudioService extends ProfileService {
                                .BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_CREATE_FAILED);
            }

            if (leaudioBigDependsOnAudioState()) {
                clearCreateBroadcastTimeoutCallback();
            }
            mAwaitingBroadcastCreateResponse = false;

            // In case if there were additional calls to create broadcast
@@ -3883,7 +3915,9 @@ public class LeAudioService extends ProfileService {
                        sessionStats.updateSessionStreamingTime(SystemClock.elapsedRealtime());
                    }

                    clearBroadcastTimeoutCallback();
                    if (!leaudioBigDependsOnAudioState()) {
                        clearCreateBroadcastTimeoutCallback();
                    }

                    if (previousState == LeAudioStackEvent.BROADCAST_STATE_PAUSED) {
                        if (bassClientService != null) {
@@ -5279,21 +5313,38 @@ public class LeAudioService extends ProfileService {
        return audioFrameworkCalls;
    }

    class DialingOutTimeoutEvent implements Runnable {
    private class CreateBroadcastTimeoutEvent implements Runnable {
        Integer mBroadcastId;

        DialingOutTimeoutEvent(Integer broadcastId) {
        CreateBroadcastTimeoutEvent() {}

        CreateBroadcastTimeoutEvent(Integer broadcastId) {
            mBroadcastId = broadcastId;
        }

        @Override
        public void run() {
            if (leaudioBigDependsOnAudioState()) {
                Log.w(TAG, "Failed to start Broadcast in time");

                if (getLeAudioService() == null) {
                    Log.e(TAG, "CreateBroadcastTimeoutEvent: No LE Audio service");
                    return;
                }

                if (sLeAudioService.mHandler == null) {
                    Log.w(TAG, "CreateBroadcastTimeoutEvent: No handler");
                    return;
                }

                mHandler.post(() -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
            } else {
                Log.w(TAG, "Failed to start Broadcast in time: " + mBroadcastId);

            mDialingOutTimeoutEvent = null;
                mCreateBroadcastTimeoutEvent = null;

                if (getLeAudioService() == null) {
                Log.e(TAG, "DialingOutTimeoutEvent: No LE Audio service");
                    Log.e(TAG, "CreateBroadcastTimeoutEvent: No LE Audio service");
                    return;
                }

@@ -5313,7 +5364,8 @@ public class LeAudioService extends ProfileService {
                        updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false);
                    }

                mHandler.post(() -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
                    mHandler.post(
                            () -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
                    logBroadcastSessionStatsWithStatus(
                            mBroadcastId,
                            BluetoothStatsLog
@@ -5321,6 +5373,7 @@ public class LeAudioService extends ProfileService {
                }
            }
        }
    }

    class AudioModeChangeListener implements AudioManager.OnModeChangedListener {
        @Override
+164 −140

File changed.

Preview size limit exceeded, changes collapsed.

+8 −5
Original line number Diff line number Diff line
@@ -913,6 +913,7 @@ public:
    is_iso_running_ = is_active;
    log::info("is_iso_running: {}", is_iso_running_);
    if (!is_iso_running_) {
      if (!com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
        if (queued_start_broadcast_request_) {
          auto broadcast_id = *queued_start_broadcast_request_;
          queued_start_broadcast_request_ = std::nullopt;
@@ -920,6 +921,8 @@ public:
          log::info("Start queued broadcast.");
          StartAudioBroadcast(broadcast_id);
        }
      }

      if (queued_create_broadcast_request_) {
        auto broadcast_msg = std::move(*queued_create_broadcast_request_);
        queued_create_broadcast_request_ = std::nullopt;
+36 −63
Original line number Diff line number Diff line
@@ -533,8 +533,19 @@ TEST_F(BroadcasterTest, CreateAudioBroadcastMultiGroups) {
TEST_F(BroadcasterTest, SuspendAudioBroadcast) {
  EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
          .Times(1);
  LeAudioSourceAudioHalClient::Callbacks* audio_receiver;
  EXPECT_CALL(*mock_audio_source_, Start)
          .WillOnce(DoAll(SaveArg<1>(&audio_receiver), Return(true)))
          .WillRepeatedly(Return(false));
  auto broadcast_id = InstantiateBroadcast();

  if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
    ASSERT_NE(audio_receiver, nullptr);
    audio_receiver->OnAudioResume();
  } else {
    LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  }

  Mock::VerifyAndClearExpectations(mock_codec_manager_);

  EXPECT_CALL(mock_broadcaster_callbacks_,
@@ -559,7 +570,9 @@ TEST_F(BroadcasterTest, StartAudioBroadcast) {

  EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
          .Times(1);

  auto broadcast_id = InstantiateBroadcast();
  ASSERT_NE(audio_receiver, nullptr);
  Mock::VerifyAndClearExpectations(mock_codec_manager_);

  EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
@@ -575,8 +588,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcast) {
  ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  ASSERT_NE(audio_receiver, nullptr);
  audio_receiver->OnAudioResume();

  // NOTICE: This is really an implementation specific part, we fake the BIG
  //         config as the mocked state machine does not even call the
@@ -609,6 +621,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
          .Times(1);
  auto broadcast_id =
          InstantiateBroadcast(media_metadata, default_code, {bluetooth::le_audio::QUALITY_HIGH});
  ASSERT_NE(audio_receiver, nullptr);
  Mock::VerifyAndClearExpectations(mock_codec_manager_);

  LeAudioBroadcaster::Get()->StopAudioBroadcast(broadcast_id);
@@ -626,8 +639,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
  EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, false))
          .Times(0);

  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  ASSERT_NE(audio_receiver, nullptr);
  audio_receiver->OnAudioResume();

  // NOTICE: This is really an implementation specific part, we fake the BIG
  //         config as the mocked state machine does not even call the
@@ -651,8 +663,18 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
TEST_F(BroadcasterTest, StopAudioBroadcast) {
  EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
          .Times(1);
  LeAudioSourceAudioHalClient::Callbacks* audio_receiver;
  EXPECT_CALL(*mock_audio_source_, Start)
          .WillOnce(DoAll(SaveArg<1>(&audio_receiver), Return(true)))
          .WillRepeatedly(Return(false));
  auto broadcast_id = InstantiateBroadcast();

  if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
    ASSERT_NE(audio_receiver, nullptr);
    audio_receiver->OnAudioResume();
  } else {
    LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  }

  // NOTICE: This is really an implementation specific part, we fake the BIG
  //         config as the mocked state machine does not even call the
@@ -712,7 +734,6 @@ TEST_F(BroadcasterTest, DestroyAudioBroadcast) {
  LeAudioBroadcaster::Get()->StopAudioBroadcast(broadcast_id);

  EXPECT_CALL(*mock_audio_source_, Start).Times(0);
  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);

  EXPECT_CALL(*mock_audio_source_, Stop).Times(0);
  LeAudioBroadcaster::Get()->SuspendAudioBroadcast(broadcast_id);
@@ -846,8 +867,8 @@ TEST_F(BroadcasterTest, UpdateMetadataFromAudioTrackMetadata) {
  ContentControlIdKeeper::GetInstance()->SetCcid(LeAudioContextType::MEDIA, media_ccid);
  auto broadcast_id = InstantiateBroadcast();

  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  ASSERT_NE(audio_receiver, nullptr);
  audio_receiver->OnAudioResume();

  auto sm = MockBroadcastStateMachine::GetLastInstance();
  std::vector<uint8_t> ccid_list;
@@ -1204,6 +1225,7 @@ TEST_F(BroadcasterTest, AudioActiveState) {
          .WillRepeatedly(Return(false));

  auto broadcast_id = InstantiateBroadcast();
  ASSERT_NE(audio_receiver, nullptr);
  auto sm = MockBroadcastStateMachine::GetLastInstance();
  pb_announcement = sm->GetPublicBroadcastAnnouncement();
  auto created_public_meta = types::LeAudioLtvMap(pb_announcement.metadata).RawPacket();
@@ -1218,9 +1240,6 @@ TEST_F(BroadcasterTest, AudioActiveState) {
                  });
  ON_CALL(*sm, GetPublicBroadcastAnnouncement()).WillByDefault(ReturnRef(pb_announcement));

  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  ASSERT_NE(audio_receiver, nullptr);

  // Update to true Audio Active State while audio resumed
  EXPECT_CALL(*sm, UpdatePublicBroadcastAnnouncement);
  audio_receiver->OnAudioResume();
@@ -1278,32 +1297,12 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundFromTheBeginnin
  auto broadcast_id = InstantiateBroadcast();
  EXPECT_CALL(mock_broadcaster_callbacks_,
              OnBroadcastStateChanged(broadcast_id, BroadcastState::STREAMING))
          .Times(1);
          .Times(0);
  // Timers not started
  ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  // Start Broadcast
  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  // Timers started
  ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
  ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_NE(audio_receiver, nullptr);

  // BIG termination timer execution, state machine go to CONFIGURED state so BIG terminated
  EXPECT_CALL(mock_broadcaster_callbacks_,
              OnBroadcastStateChanged(broadcast_id, BroadcastState::CONFIGURED))
          .Times(1);
  // Imitate execution of BIG termination timer
  big_terminate_timer_->cb(big_terminate_timer_->data);

  // Broadcast stop timer execution, state machine go to STOPPED state
  EXPECT_CALL(mock_broadcaster_callbacks_,
              OnBroadcastStateChanged(broadcast_id, BroadcastState::STOPPED))
          .Times(1);
  // Imitate execution of BIG termination timer
  broadcast_stop_timer_->cb(broadcast_stop_timer_->data);
}

TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {
@@ -1326,24 +1325,11 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  // Start Broadcast
  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  // Timers started
  ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
  ASSERT_NE(audio_receiver, nullptr);

  // First onAudioResume when BIG already created, not cause any state change
  EXPECT_CALL(mock_broadcaster_callbacks_, OnBroadcastStateChanged(broadcast_id, _)).Times(0);
  audio_receiver->OnAudioResume();
  // Timers cancelled
  ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
  ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  // OnAudioSuspend cause starting the BIG termination timer
  audio_receiver->OnAudioSuspend();
  ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);

@@ -1357,7 +1343,7 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {

  // OnAudioSuspend cause starting the BIG termination timer
  audio_receiver->OnAudioSuspend();
  ASSERT_EQ(6, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);

@@ -1396,24 +1382,11 @@ TEST_F(BroadcasterTest, BigCreationTerminationDependsOnAudioResumeSuspend) {
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  // Start Broadcast
  LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
  // Timers started
  ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
  ASSERT_NE(audio_receiver, nullptr);

  // First onAudioResume when BIG already created, not cause any state change
  EXPECT_CALL(mock_broadcaster_callbacks_, OnBroadcastStateChanged(broadcast_id, _)).Times(0);
  audio_receiver->OnAudioResume();
  // Timers cancelled
  ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
  ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);

  // OnAudioSuspend cause starting the BIG termination timer
  audio_receiver->OnAudioSuspend();
  ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);

@@ -1427,7 +1400,7 @@ TEST_F(BroadcasterTest, BigCreationTerminationDependsOnAudioResumeSuspend) {

  // OnAudioSuspend cause starting the BIG termination timer
  audio_receiver->OnAudioSuspend();
  ASSERT_EQ(6, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
  ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
  ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);

+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ public:
    advertising_sid_ = ++instance_counter_;

    ON_CALL(*this, Initialize).WillByDefault([this]() {
      SetState(State::CONFIGURED);
      this->cb->OnStateMachineCreateStatus(this->cfg.broadcast_id, result_);
      return result_;
    });