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

Commit c668d7e1 authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge "[Audiosharing] Check broadcast id instead of BIS for sink's receive state" into main

parents 7590443d 2ec06cc5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -709,6 +709,9 @@ public class BluetoothUtils {
    @WorkerThread
    public static boolean hasConnectedBroadcastSourceForBtDevice(
            @Nullable BluetoothDevice device, @Nullable LocalBluetoothManager localBtManager) {
        if (Flags.audioSharingHysteresisModeFix()) {
            return hasActiveLocalBroadcastSourceForBtDevice(device, localBtManager);
        }
        LocalBluetoothLeBroadcastAssistant assistant =
                localBtManager == null
                        ? null
+26 −37
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.android.settingslib.R;
import com.android.settingslib.flags.Flags;

import com.google.common.collect.ImmutableList;

@@ -1134,20 +1135,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
            Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to assistant profile is null");
            return;
        }
        List<BluetoothDevice> connectedDevices = mServiceBroadcastAssistant.getConnectedDevices();
        List<BluetoothDevice> devicesInSharing =
                connectedDevices.stream()
                        .filter(
                                bluetoothDevice -> {
                                    List<BluetoothLeBroadcastReceiveState> sourceList =
                                            mServiceBroadcastAssistant.getAllSources(
                                                    bluetoothDevice);
                                    return !sourceList.isEmpty()
                                            && sourceList.stream()
                                                    .anyMatch(BluetoothUtils::isConnected);
                                })
                        .collect(Collectors.toList());
        if (devicesInSharing.isEmpty()) {
        List<BluetoothDevice> devicesInBroadcast = getDevicesInBroadcast();
        if (devicesInBroadcast.isEmpty()) {
            Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to no sinks in broadcast");
            return;
        }
@@ -1156,7 +1145,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        BluetoothDevice targetDevice = null;
        // Find the earliest connected device in sharing session.
        int targetDeviceIdx = -1;
        for (BluetoothDevice device : devicesInSharing) {
        for (BluetoothDevice device : devicesInBroadcast) {
            if (devices.contains(device)) {
                int idx = devices.indexOf(device);
                if (idx > targetDeviceIdx) {
@@ -1169,10 +1158,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
            Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, target is null");
            return;
        }
        Log.d(
                TAG,
                "updateFallbackActiveDeviceIfNeeded, set active device: "
                        + targetDevice.getAnonymizedAddress());
        CachedBluetoothDevice targetCachedDevice = mDeviceManager.findDevice(targetDevice);
        if (targetCachedDevice == null) {
            Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, fail to find cached bt device");
@@ -1180,16 +1165,37 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        }
        int fallbackActiveGroupId = getFallbackActiveGroupId();
        if (fallbackActiveGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
                && getGroupId(targetCachedDevice) == fallbackActiveGroupId) {
                && BluetoothUtils.getGroupId(targetCachedDevice) == fallbackActiveGroupId) {
            Log.d(
                    TAG,
                    "Skip updateFallbackActiveDeviceIfNeeded, already is fallback: "
                            + fallbackActiveGroupId);
            return;
        }
        Log.d(
                TAG,
                "updateFallbackActiveDeviceIfNeeded, set active device: "
                        + targetDevice.getAnonymizedAddress());
        targetCachedDevice.setActive();
    }

    private List<BluetoothDevice> getDevicesInBroadcast() {
        boolean hysteresisModeFixEnabled = Flags.audioSharingHysteresisModeFix();
        List<BluetoothDevice> connectedDevices = mServiceBroadcastAssistant.getConnectedDevices();
        return connectedDevices.stream()
                .filter(
                        bluetoothDevice -> {
                            List<BluetoothLeBroadcastReceiveState> sourceList =
                                    mServiceBroadcastAssistant.getAllSources(
                                            bluetoothDevice);
                            return !sourceList.isEmpty() && sourceList.stream().anyMatch(
                                    source -> hysteresisModeFixEnabled
                                            ? BluetoothUtils.isSourceMatched(source, mBroadcastId)
                                            : BluetoothUtils.isConnected(source));
                        })
                .collect(Collectors.toList());
    }

    private int getFallbackActiveGroupId() {
        return Settings.Secure.getInt(
                mContext.getContentResolver(),
@@ -1197,23 +1203,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
    }

    private int getGroupId(CachedBluetoothDevice cachedDevice) {
        int groupId = cachedDevice.getGroupId();
        String anonymizedAddress = cachedDevice.getDevice().getAnonymizedAddress();
        if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
            Log.d(TAG, "getGroupId by CSIP profile for device: " + anonymizedAddress);
            return groupId;
        }
        for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
            if (profile instanceof LeAudioProfile) {
                Log.d(TAG, "getGroupId by LEA profile for device: " + anonymizedAddress);
                return ((LeAudioProfile) profile).getGroupId(cachedDevice.getDevice());
            }
        }
        Log.d(TAG, "getGroupId return invalid id for device: " + anonymizedAddress);
        return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
    }

    private void notifyBroadcastStateChange(@BroadcastState int state) {
        if (!mContext.getPackageName().equals(SETTINGS_PKG)) {
            Log.d(TAG, "Skip notifyBroadcastStateChange, not triggered by Settings.");
+106 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.provider.Settings;
import android.util.Pair;

import com.android.internal.R;
import com.android.settingslib.flags.Flags;
import com.android.settingslib.widget.AdaptiveIcon;

import com.google.common.collect.ImmutableList;
@@ -605,6 +606,7 @@ public class BluetoothUtilsTest {

    @Test
    public void testHasConnectedBroadcastSource_leadDeviceConnectedToBroadcastSource() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
        CachedBluetoothDevice memberCachedDevice = mock(CachedBluetoothDevice.class);
        BluetoothDevice memberDevice = mock(BluetoothDevice.class);
@@ -630,6 +632,7 @@ public class BluetoothUtilsTest {

    @Test
    public void testHasConnectedBroadcastSource_memberDeviceConnectedToBroadcastSource() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
        CachedBluetoothDevice memberCachedDevice = mock(CachedBluetoothDevice.class);
        BluetoothDevice memberDevice = mock(BluetoothDevice.class);
@@ -655,6 +658,7 @@ public class BluetoothUtilsTest {

    @Test
    public void testHasConnectedBroadcastSource_deviceNotConnectedToBroadcastSource() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);

        List<Long> bisSyncState = new ArrayList<>();
@@ -672,6 +676,7 @@ public class BluetoothUtilsTest {

    @Test
    public void testHasConnectedBroadcastSourceForBtDevice_deviceConnectedToBroadcastSource() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        List<Long> bisSyncState = new ArrayList<>();
        bisSyncState.add(1L);
        when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
@@ -688,6 +693,7 @@ public class BluetoothUtilsTest {

    @Test
    public void testHasConnectedBroadcastSourceForBtDevice_deviceNotConnectedToBroadcastSource() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        List<Long> bisSyncState = new ArrayList<>();
        when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);

@@ -701,6 +707,106 @@ public class BluetoothUtilsTest {
                .isFalse();
    }

    @Test
    public void hasConnectedBroadcastSource_hysteresisFix_leadDeviceHasActiveLocalSource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
        CachedBluetoothDevice memberCachedDevice = mock(CachedBluetoothDevice.class);
        BluetoothDevice memberDevice = mock(BluetoothDevice.class);
        when(memberCachedDevice.getDevice()).thenReturn(memberDevice);
        Set<CachedBluetoothDevice> memberCachedDevices = new HashSet<>();
        memberCachedDevices.add(memberCachedDevice);
        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(memberCachedDevices);


        when(mBroadcast.getLatestBroadcastId()).thenReturn(TEST_BROADCAST_ID);
        when(mLeBroadcastReceiveState.getBroadcastId()).thenReturn(TEST_BROADCAST_ID);

        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(sourceList);
        when(mAssistant.getAllSources(memberDevice)).thenReturn(Collections.emptyList());

        assertThat(
                BluetoothUtils.hasConnectedBroadcastSource(
                        mCachedBluetoothDevice, mLocalBluetoothManager))
                .isTrue();
    }

    @Test
    public void hasConnectedBroadcastSource_hysteresisFix_memberDeviceHasActiveLocalSource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
        CachedBluetoothDevice memberCachedDevice = mock(CachedBluetoothDevice.class);
        BluetoothDevice memberDevice = mock(BluetoothDevice.class);
        when(memberCachedDevice.getDevice()).thenReturn(memberDevice);
        Set<CachedBluetoothDevice> memberCachedDevices = new HashSet<>();
        memberCachedDevices.add(memberCachedDevice);
        when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(memberCachedDevices);

        when(mBroadcast.getLatestBroadcastId()).thenReturn(TEST_BROADCAST_ID);
        when(mLeBroadcastReceiveState.getBroadcastId()).thenReturn(TEST_BROADCAST_ID);

        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(memberDevice)).thenReturn(sourceList);
        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(Collections.emptyList());

        assertThat(
                BluetoothUtils.hasConnectedBroadcastSource(
                        mCachedBluetoothDevice, mLocalBluetoothManager))
                .isTrue();
    }

    @Test
    public void hasConnectedBroadcastSource_hysteresisFix_deviceNoActiveLocalSource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);

        when(mBroadcast.getLatestBroadcastId()).thenReturn(UNKNOWN_VALUE_PLACEHOLDER);

        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(sourceList);

        assertThat(
                BluetoothUtils.hasConnectedBroadcastSource(
                        mCachedBluetoothDevice, mLocalBluetoothManager))
                .isFalse();
    }

    @Test
    public void hasConnectedBroadcastSourceForBtDevice_hysteresisFix_deviceHasActiveLocalSource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mBroadcast.getLatestBroadcastId()).thenReturn(TEST_BROADCAST_ID);
        when(mLeBroadcastReceiveState.getBroadcastId()).thenReturn(TEST_BROADCAST_ID);

        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(sourceList);

        assertThat(
                BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(
                        mBluetoothDevice, mLocalBluetoothManager))
                .isTrue();
    }

    @Test
    public void hasConnectedBroadcastSourceForBtDevice_hysteresisFix_deviceNoActiveLocalSource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
        when(mBroadcast.getLatestBroadcastId()).thenReturn(TEST_BROADCAST_ID);
        when(mLeBroadcastReceiveState.getBroadcastId()).thenReturn(UNKNOWN_VALUE_PLACEHOLDER);

        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(sourceList);

        assertThat(
                BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(
                        mBluetoothDevice, mLocalBluetoothManager))
                .isFalse();
    }

    @Test
    public void testHasActiveLocalBroadcastSourceForBtDevice_hasActiveLocalSource() {
        when(mBroadcast.getLatestBroadcastId()).thenReturn(TEST_BROADCAST_ID);