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

Commit 90a75ade authored by Rongxuan Liu's avatar Rongxuan Liu
Browse files

[le audio] Add new APIs to get assistant local metadata for source

getSourceMetadata is introduced to allow app to get sink's broadcast
source metadata.

Bug: 375421703
Bug: 375423982
Test: atest BluetoothLeBroadcastAssistantTest
Test: atest BassClientServiceTest
Test: manual test callback with LeAudioTestApp
Change-Id: I695bc0fe42bba991b5d895b548c0d00b966d3952
parent c6eabcd4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -60,4 +60,6 @@ interface IBluetoothLeBroadcastAssistant {
    List<BluetoothLeBroadcastReceiveState> getAllSources(in BluetoothDevice sink, in AttributionSource source);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    int getMaximumSourceCapacity(in BluetoothDevice sink, in AttributionSource source);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    BluetoothLeBroadcastMetadata getSourceMetadata(in BluetoothDevice sink, in int sourceId, in AttributionSource source);
}
+33 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;

import static com.android.bluetooth.flags.Flags.leaudioAllowedContextMask;
import static com.android.bluetooth.flags.Flags.leaudioBigDependsOnAudioState;
import static com.android.bluetooth.flags.Flags.leaudioBroadcastApiGetLocalMetadata;
import static com.android.bluetooth.flags.Flags.leaudioBroadcastAssistantPeripheralEntrustment;
import static com.android.bluetooth.flags.Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine;
import static com.android.bluetooth.flags.Flags.leaudioBroadcastResyncHelper;
@@ -3273,6 +3274,27 @@ public class BassClientService extends ProfileService {
        return stateMachine.getMaximumSourceCapacity();
    }

    /**
     * Get metadata of source that stored on this Broadcast Sink
     *
     * @param sink Broadcast Sink device
     * @param sourceId Broadcast source id
     * @return metadata of source that stored on this Broadcast Sink
     */
    BluetoothLeBroadcastMetadata getSourceMetadata(BluetoothDevice sink, int sourceId) {
        if (!leaudioBroadcastApiGetLocalMetadata()) {
            return null;
        }

        log("getSourceMetadata: device = " + sink + " with source id = " + sourceId);
        BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
        if (stateMachine == null) {
            log("stateMachine is null");
            return null;
        }
        return stateMachine.getCurrentBroadcastMetadata(sourceId);
    }

    private boolean isLocalBroadcast(int broadcastId) {
        LeAudioService leAudioService = mServiceFactory.getLeAudioService();
        if (leAudioService == null) {
@@ -4630,5 +4652,16 @@ public class BassClientService extends ProfileService {
            }
            return service.getMaximumSourceCapacity(sink);
        }

        @Override
        public BluetoothLeBroadcastMetadata getSourceMetadata(
                BluetoothDevice sink, int sourceId, AttributionSource source) {
            BassClientService service = getServiceAndEnforceConnect(source);
            if (service == null) {
                Log.e(TAG, "Service is null");
                return null;
            }
            return service.getSourceMetadata(sink, sourceId);
        }
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -376,10 +376,6 @@ class BassClientStateMachine extends StateMachine {
        return mPendingSourceToSwitch != null;
    }

    BluetoothLeBroadcastMetadata getCurrentBroadcastMetadata(Integer sourceId) {
        return mCurrentMetadata.getOrDefault(sourceId, null);
    }

    private void setCurrentBroadcastMetadata(
            Integer sourceId, BluetoothLeBroadcastMetadata metadata) {
        if (metadata != null) {
@@ -2619,6 +2615,10 @@ class BassClientStateMachine extends StateMachine {
        return mNumOfBroadcastReceiverStates;
    }

    BluetoothLeBroadcastMetadata getCurrentBroadcastMetadata(Integer sourceId) {
        return mCurrentMetadata.getOrDefault(sourceId, null);
    }

    BluetoothDevice getDevice() {
        return mDevice;
    }
+34 −0
Original line number Diff line number Diff line
@@ -2039,6 +2039,40 @@ public class BassClientServiceTest {
        }
    }

    @Test
    @EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_API_GET_LOCAL_METADATA)
    public void testGetSourceMetadata() {
        prepareConnectedDeviceGroup();
        startSearchingForSources();
        onScanResult(mSourceDevice, TEST_BROADCAST_ID);
        onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
        BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);

        for (BassClientStateMachine sm : mStateMachines.values()) {
            injectRemoteSourceStateSourceAdded(
                    sm,
                    meta,
                    TEST_SOURCE_ID,
                    BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED,
                    meta.isEncrypted()
                            ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
                            : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
                    null);
            doReturn(null).when(sm).getCurrentBroadcastMetadata(eq(TEST_SOURCE_ID));
            assertThat(mBassClientService.getSourceMetadata(sm.getDevice(), TEST_SOURCE_ID))
                    .isEqualTo(null);

            doReturn(meta).when(sm).getCurrentBroadcastMetadata(eq(TEST_SOURCE_ID));
            doReturn(true).when(sm).isSyncedToTheSource(eq(TEST_SOURCE_ID));
            assertThat(mBassClientService.getSourceMetadata(sm.getDevice(), TEST_SOURCE_ID))
                    .isEqualTo(meta);
        }

        for (BassClientStateMachine sm : mStateMachines.values()) {
            injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID);
        }
    }

    /** Test whether the group operation flag is set on addSource() and removed on removeSource */
    @Test
    public void testGroupStickyFlagSetUnset() {
+1 −0
Original line number Diff line number Diff line
@@ -592,6 +592,7 @@ package android.bluetooth {
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getMaximumSourceCapacity(@NonNull android.bluetooth.BluetoothDevice);
    method @FlaggedApi("com.android.bluetooth.flags.leaudio_broadcast_api_get_local_metadata") @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothLeBroadcastMetadata getSourceMetadata(@NonNull android.bluetooth.BluetoothDevice, @IntRange(from=0, to=255) int);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isSearchInProgress();
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void modifySource(@NonNull android.bluetooth.BluetoothDevice, int, @NonNull android.bluetooth.BluetoothLeBroadcastMetadata);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothLeBroadcastAssistant.Callback);
Loading