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

Commit 4f64e342 authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk Committed by Grzegorz Kolodziejczyk
Browse files

bass: Add handover related test cases

This CL adds two tests related to handover test cases. First is related
to controlling bass via LeAudioService. Second test is about controlling
bass via source stream notifications.

Tag: #feature
Test: atest LeAudioServiceTest LeAudioBroadcastServiceTest
Bug: 298080973
Bug: 308171251
Change-Id: I9e4cb5b8dbfeecc91a764446a37300563914c8b1
parent 7b63bebb
Loading
Loading
Loading
Loading
+219 −24
Original line number Diff line number Diff line
@@ -68,7 +68,9 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.flags.FeatureFlagsImpl;
import com.android.bluetooth.flags.FakeFeatureFlagsImpl;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.le_audio.LeAudioService;

import org.junit.After;
import org.junit.Assert;
@@ -136,6 +138,7 @@ public class BassClientServiceTest {
    private BluetoothDevice mCurrentDevice;
    private BluetoothDevice mCurrentDevice1;
    private BassIntentReceiver mBassIntentReceiver;
    private FakeFeatureFlagsImpl mFakeFlagsImpl;

    @Spy private BassObjectsFactory mObjectsFactory = BassObjectsFactory.getInstance();
    @Mock private AdapterService mAdapterService;
@@ -143,6 +146,7 @@ public class BassClientServiceTest {
    @Mock private BluetoothLeScannerWrapper mBluetoothLeScannerWrapper;
    @Mock private ServiceFactory mServiceFactory;
    @Mock private CsipSetCoordinatorService mCsipService;
    @Mock private LeAudioService mLeAudioService;
    @Mock private IBluetoothLeBroadcastAssistantCallback mCallback;
    @Mock private Binder mBinder;

@@ -239,11 +243,15 @@ public class BassClientServiceTest {
        doReturn(mBluetoothLeScannerWrapper).when(mObjectsFactory)
                .getBluetoothLeScannerWrapper(any());

        mBassClientService = new BassClientService(mTargetContext, new FeatureFlagsImpl());
        mFakeFlagsImpl = new FakeFeatureFlagsImpl();
        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false);

        mBassClientService = new BassClientService(mTargetContext, mFakeFlagsImpl);
        mBassClientService.doStart();

        mBassClientService.mServiceFactory = mServiceFactory;
        doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService();
        doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService();

        when(mCallback.asBinder()).thenReturn(mBinder);
        mBassClientService.registerCallback(mCallback);
@@ -444,7 +452,7 @@ public class BassClientServiceTest {

            // Inject initial broadcast source state
            BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
            injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
            injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                meta.isEncrypted() ?
                        BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -452,7 +460,7 @@ public class BassClientServiceTest {
                null);
            injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID);

            injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
            injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                meta.isEncrypted() ?
                        BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -493,9 +501,9 @@ public class BassClientServiceTest {
        }
    }

    private void injectRemoteSourceState(BassClientStateMachine sm,
    private BluetoothLeBroadcastReceiveState injectRemoteSourceState(BassClientStateMachine sm,
            BluetoothLeBroadcastMetadata meta, int sourceId, int paSynState, int encryptionState,
            byte[] badCode) {
            byte[] badCode, long bisSyncState) {
        BluetoothLeBroadcastReceiveState recvState = new BluetoothLeBroadcastReceiveState(
                sourceId,
                meta.getSourceAddressType(),
@@ -508,7 +516,7 @@ public class BassClientServiceTest {
                meta.getSubgroups().size(),
                // Bis sync states
                meta.getSubgroups().stream()
                        .map(e -> (long) 0x00000002)
                        .map(e -> bisSyncState)
                        .collect(Collectors.toList()),
                meta.getSubgroups().stream()
                                .map(e -> e.getContentMetadata())
@@ -525,9 +533,35 @@ public class BassClientServiceTest {
        stateList.add(recvState);
        doReturn(stateList).when(sm).getAllSources();

        return recvState;
    }

    private BluetoothLeBroadcastReceiveState injectRemoteSourceStateSourceAdded(
            BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId,
            int paSynState, int encryptionState, byte[] badCode) {
        BluetoothLeBroadcastReceiveState recvState =
                injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode,
                        (long) 0x00000002);

        mBassClientService.getCallbacks().notifySourceAdded(sm.getDevice(), recvState,
                        BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
        TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());

        return recvState;
    }

    private BluetoothLeBroadcastReceiveState injectRemoteSourceStateChanged(
            BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId,
            int paSynState, int encryptionState, byte[] badCode, long bisSyncState) {
        BluetoothLeBroadcastReceiveState recvState =
                injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode,
                        bisSyncState);

        mBassClientService.getCallbacks().notifyReceiveStateChanged(sm.getDevice(),
                        recvState.getSourceId(), recvState);
        TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());

        return recvState;
    }

    private void injectRemoteSourceStateRemoval(BassClientStateMachine sm, int sourceId) {
@@ -581,7 +615,7 @@ public class BassClientServiceTest {
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -596,7 +630,7 @@ public class BassClientServiceTest {
                    throw e.rethrowFromSystemServer();
                }
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -624,14 +658,14 @@ public class BassClientServiceTest {
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -678,14 +712,14 @@ public class BassClientServiceTest {
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -729,14 +763,14 @@ public class BassClientServiceTest {
        // Inject source added
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -799,7 +833,7 @@ public class BassClientServiceTest {
        BluetoothLeBroadcastMetadata newMeta = createBroadcastMetadata(TEST_BROADCAST_ID + 1);
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm : mStateMachines.values()) {
            injectRemoteSourceState(
            injectRemoteSourceStateSourceAdded(
                    sm,
                    meta,
                    TEST_SOURCE_ID,
@@ -808,7 +842,7 @@ public class BassClientServiceTest {
                            ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
                            : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                    null);
            injectRemoteSourceState(
            injectRemoteSourceStateSourceAdded(
                    sm,
                    meta,
                    TEST_SOURCE_ID + 1,
@@ -854,14 +888,14 @@ public class BassClientServiceTest {
        assertThat(mStateMachines.size()).isEqualTo(2);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -880,14 +914,14 @@ public class BassClientServiceTest {
        assertThat(mStateMachines.size()).isEqualTo(2);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta1, TEST_SOURCE_ID + 2,
                injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 2,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta1.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta1, TEST_SOURCE_ID + 3,
                injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 3,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta1.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -979,7 +1013,7 @@ public class BassClientServiceTest {

            BluetoothLeBroadcastMetadata metaOther =
                    createBroadcastMetadata(TEST_BROADCAST_ID + 20);
            injectRemoteSourceState(sm, metaOther, TEST_SOURCE_ID + 20,
            injectRemoteSourceStateSourceAdded(sm, metaOther, TEST_SOURCE_ID + 20,
                    BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                    meta.isEncrypted() ?
                            BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -1024,14 +1058,14 @@ public class BassClientServiceTest {
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1,
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
@@ -1283,4 +1317,165 @@ public class BassClientServiceTest {
        assertThat(mBassClientService.getBroadcastIdForSyncHandle(testSyncHandle))
                .isEqualTo(testBroadcastId);
    }

    @Test
    public void testSuspendResumeSourceSynchronization() {
        prepareConnectedDeviceGroup();
        BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);
            }
        }

        mBassClientService.suspendAllReceiversSourceSynchronization();

        // Inject source removed
        for (BassClientStateMachine sm: mStateMachines.values()) {
            ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
            verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());

            Optional<Message> msg = messageCaptor.getAllValues().stream()
                    .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE)
                    .findFirst();
            assertThat(msg.isPresent()).isEqualTo(true);

            if (sm.getDevice().equals(mCurrentDevice)) {
                assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID);
                injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 1);
                injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 1);
            }
        }

        mBassClientService.resumeReceiversSourceSynchronization();

        // Verify all group members getting ADD_BCAST_SOURCE message
        assertThat(mStateMachines.size()).isEqualTo(2);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
            verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());

            long count = messageCaptor.getAllValues().stream()
                    .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE)
                                        && (m.obj == meta))
                    .count();
            assertThat(count).isEqualTo(2);
        }
    }

    @Test
    public void testHandleUnicastSourceStreamStatusChange() {
        prepareConnectedDeviceGroup();
        BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
        verifyAddSourceForGroup(meta);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);

                // Update receiver state
                injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null, (long) 0x00000001);
                verify(mLeAudioService).activeBroadcastAssistantNotification(eq(true));
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null);

                // Update receiver state
                injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null, (long) 0x00000002);
            }
        }

        /* Unicast would like to stream */
        mBassClientService.handleUnicastSourceStreamStatusChange(
                0 /* STATUS_LOCAL_STREAM_REQUESTED */);

        // Inject source removed
        for (BassClientStateMachine sm: mStateMachines.values()) {
            ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
            verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());

            Optional<Message> msg = messageCaptor.getAllValues().stream()
                    .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE)
                    .findFirst();
            assertThat(msg.isPresent()).isEqualTo(true);

            if (sm.getDevice().equals(mCurrentDevice)) {
                assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID);
                injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID);
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 1);
                injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 1);
            }
        }

        /* Unicast finished streaming */
        mBassClientService.handleUnicastSourceStreamStatusChange(
                2 /* STATUS_LOCAL_STREAM_SUSPENDED */);

        // Verify all group members getting ADD_BCAST_SOURCE message
        assertThat(mStateMachines.size()).isEqualTo(2);
        for (BassClientStateMachine sm: mStateMachines.values()) {
            ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
            verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());

            long count = messageCaptor.getAllValues().stream()
                    .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE)
                                        && (m.obj == meta))
                    .count();
            assertThat(count).isEqualTo(2);
        }

        // Update receiver state with lost BIS sync
        for (BassClientStateMachine sm: mStateMachines.values()) {
            if (sm.getDevice().equals(mCurrentDevice)) {
                injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null, (long) 0x00000000);
                verify(mLeAudioService).activeBroadcastAssistantNotification(eq(false));
            } else if (sm.getDevice().equals(mCurrentDevice1)) {
                injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1,
                        BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                        meta.isEncrypted() ?
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING :
                                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                        null, (long) 0x00000000);
            }
        }
    }
}