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

Commit 5fde1d6e authored by Rongxuan Liu's avatar Rongxuan Liu
Browse files

[le audio] Fix removing broadcast source when PA is still synced

When PA is still synced, assistant will trigger pending source remove operation with any RS update.
Pending remove should only be sent when both PA and BISes are unsynced.

Bug: 378532642
Flag: EXEMPT, trivial change covered by unit tests
Test: atest BassClientStateMachineTest
Change-Id: Icdf32676efdd6dec4f4049e66872b674b2883f23
parent c6eabcd4
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -1155,6 +1155,7 @@ class BassClientStateMachine extends StateMachine {
            log("processBroadcastReceiverState: invalid index: " + recvState.getSourceId());
            log("processBroadcastReceiverState: invalid index: " + recvState.getSourceId());
            return;
            return;
        }
        }
        int sourceId = recvState.getSourceId();
        BluetoothLeBroadcastReceiveState oldRecvState =
        BluetoothLeBroadcastReceiveState oldRecvState =
                mBluetoothLeBroadcastReceiveStates.get(characteristic.getInstanceId());
                mBluetoothLeBroadcastReceiveStates.get(characteristic.getInstanceId());
        if (oldRecvState == null) {
        if (oldRecvState == null) {
@@ -1182,7 +1183,7 @@ class BassClientStateMachine extends StateMachine {
                        .notifySourceAdded(
                        .notifySourceAdded(
                                mDevice, recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
                                mDevice, recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
                if (mPendingMetadata != null) {
                if (mPendingMetadata != null) {
                    setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata);
                    setCurrentBroadcastMetadata(sourceId, mPendingMetadata);
                    mPendingMetadata = null;
                    mPendingMetadata = null;
                }
                }
                checkAndUpdateBroadcastCode(recvState);
                checkAndUpdateBroadcastCode(recvState);
@@ -1228,28 +1229,28 @@ class BassClientStateMachine extends StateMachine {
                } else {
                } else {
                    log("update to an existing recvState");
                    log("update to an existing recvState");
                    if (mPendingMetadata != null) {
                    if (mPendingMetadata != null) {
                        setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata);
                        setCurrentBroadcastMetadata(sourceId, mPendingMetadata);
                        mPendingMetadata = null;
                        mPendingMetadata = null;
                    }
                    }
                    removeMessages(CANCEL_PENDING_SOURCE_OPERATION);
                    removeMessages(CANCEL_PENDING_SOURCE_OPERATION);
                    mService.getCallbacks()
                    mService.getCallbacks()
                            .notifySourceModified(
                            .notifySourceModified(
                                    mDevice,
                                    mDevice,
                                    recvState.getSourceId(),
                                    sourceId,
                                    BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
                                    BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
                    checkAndUpdateBroadcastCode(recvState);
                    checkAndUpdateBroadcastCode(recvState);
                    processPASyncState(recvState);
                    processPASyncState(recvState);
                    processSyncStateChangeStats(recvState);
                    processSyncStateChangeStats(recvState);


                    if (isPendingRemove(recvState.getSourceId())) {
                    if (isPendingRemove(sourceId) && !isSyncedToTheSource(sourceId)) {
                        Message message = obtainMessage(REMOVE_BCAST_SOURCE);
                        Message message = obtainMessage(REMOVE_BCAST_SOURCE);
                        message.arg1 = recvState.getSourceId();
                        message.arg1 = sourceId;
                        sendMessage(message);
                        sendMessage(message);
                    }
                    }
                }
                }
            }
            }
        }
        }
        broadcastReceiverState(recvState, recvState.getSourceId());
        broadcastReceiverState(recvState, sourceId);
    }
    }


    // Implements callback methods for GATT events that the app cares about.
    // Implements callback methods for GATT events that the app cares about.
+54 −0
Original line number Original line Diff line number Diff line
@@ -2701,6 +2701,60 @@ public class BassClientStateMachineTest {
        assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(sourceId);
        assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(sourceId);
    }
    }


    @Test
    public void updateBroadcastSource_pendingSourceToRemove() {
        prepareInitialReceiveStateForGatt();

        generateBroadcastReceiveStatesAndVerify(
                mSourceTestDevice,
                TEST_SOURCE_ID,
                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED,
                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING,
                0x1L);

        BassClientStateMachine.BluetoothGattTestableWrapper btGatt =
                Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class);
        mBassClientStateMachine.mBluetoothGatt = btGatt;
        BluetoothGattCharacteristic scanControlPoint =
                Mockito.mock(BluetoothGattCharacteristic.class);
        mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint;

        BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata();
        mBassClientStateMachine.mPendingMetadata = metadata;

        sendMessageAndVerifyTransition(
                mBassClientStateMachine.obtainMessage(
                        UPDATE_BCAST_SOURCE,
                        TEST_SOURCE_ID,
                        BassConstants.PA_SYNC_DO_NOT_SYNC,
                        metadata),
                BassClientStateMachine.ConnectedProcessing.class);
        assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(UPDATE_BCAST_SOURCE);
        assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(TEST_SOURCE_ID);

        mBassClientStateMachine.mPendingOperation = 0;
        mBassClientStateMachine.mPendingSourceId = 0;
        // Verify not removing source when PA is still synced
        generateBroadcastReceiveStatesAndVerify(
                mSourceTestDevice,
                TEST_SOURCE_ID,
                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED,
                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                0x0L);
        assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(0);
        assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(0);

        // Verify removing source when PA is unsynced
        generateBroadcastReceiveStatesAndVerify(
                mSourceTestDevice,
                TEST_SOURCE_ID,
                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
                BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                0x0L);
        assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(REMOVE_BCAST_SOURCE);
        assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(TEST_SOURCE_ID);
    }

    private void initToConnectingState() {
    private void initToConnectingState() {
        allowConnection(true);
        allowConnection(true);
        allowConnectGatt(true);
        allowConnectGatt(true);