Merge "[Audiosharing] Check broadcast id instead of BIS for sink's receive state" into main
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 616ab07..612c193 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -709,6 +709,9 @@
@WorkerThread
public static boolean hasConnectedBroadcastSourceForBtDevice(
@Nullable BluetoothDevice device, @Nullable LocalBluetoothManager localBtManager) {
+ if (Flags.audioSharingHysteresisModeFix()) {
+ return hasActiveLocalBroadcastSourceForBtDevice(device, localBtManager);
+ }
LocalBluetoothLeBroadcastAssistant assistant =
localBtManager == null
? null
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index a3f9e51..364e95c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -52,6 +52,7 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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.");
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index 8eedb35..0e060df 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -47,6 +47,7 @@
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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@Test
public void testHasConnectedBroadcastSourceForBtDevice_deviceNotConnectedToBroadcastSource() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
List<Long> bisSyncState = new ArrayList<>();
when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
@@ -702,6 +708,106 @@
}
@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);
when(mLeBroadcastReceiveState.getBroadcastId()).thenReturn(TEST_BROADCAST_ID);