Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +0 −12 Original line number Original line Diff line number Diff line Loading @@ -235,18 +235,6 @@ public class BluetoothEventManager { LocalBluetoothLeBroadcast broadcast = mBtManager == null ? null LocalBluetoothLeBroadcast broadcast = mBtManager == null ? null : mBtManager.getProfileManager().getLeAudioBroadcastProfile(); : mBtManager.getProfileManager().getLeAudioBroadcastProfile(); LocalBluetoothLeBroadcastAssistant assistant = mBtManager == null ? null : mBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); // Trigger updateFallbackActiveDeviceIfNeeded when ASSISTANT profile disconnected when // audio sharing is enabled. if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT && state == BluetoothAdapter.STATE_DISCONNECTED && BluetoothUtils.isAudioSharingUIAvailable(mContext) && broadcast != null && assistant != null && broadcast.isProfileReady() && assistant.isProfileReady()) { Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, ASSISTANT profile disconnected"); broadcast.updateFallbackActiveDeviceIfNeeded(); } // Dispatch handleOnProfileStateChanged to local broadcast profile // Dispatch handleOnProfileStateChanged to local broadcast profile if (Flags.promoteAudioSharingForSecondAutoConnectedLeaDevice() if (Flags.promoteAudioSharingForSecondAutoConnectedLeaDevice() && broadcast != null && broadcast != null Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +0 −110 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settingslib.bluetooth; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static com.android.settingslib.Utils.isAudioModeOngoingCall; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED_BY_RECEIVER; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED_BY_RECEIVER; Loading Loading @@ -74,17 +73,14 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.HashSet; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.Set; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; /** /** * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of Loading Loading @@ -334,7 +330,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", sourceId = " + ", sourceId = " + sourceId); + sourceId); } } updateFallbackActiveDeviceIfNeeded(); } } @Override @Override Loading Loading @@ -1205,111 +1200,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } } } } /** Update fallback active device if needed. */ public void updateFallbackActiveDeviceIfNeeded() { if (Flags.disableAudioSharingAutoPickFallbackInUi() || (mContext != null && Flags.audioSharingDeveloperOption() && BluetoothUtils.getAudioSharingPreviewValue(mContext.getContentResolver()))) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, disable flag is on"); return; } if (mIsWorkProfile) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile."); return; } if (isAudioModeOngoingCall(mContext)) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to ongoing call"); return; } Map<Integer, List<BluetoothDevice>> deviceGroupsInBroadcast = getDeviceGroupsInBroadcast(); if (deviceGroupsInBroadcast.isEmpty()) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to no sinks in broadcast"); return; } int targetGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; int fallbackActiveGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( mContext.getContentResolver()); if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)) { int userPreferredPrimaryGroupId = getUserPreferredPrimaryGroupId(); if (userPreferredPrimaryGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID && deviceGroupsInBroadcast.containsKey(userPreferredPrimaryGroupId)) { if (userPreferredPrimaryGroupId == fallbackActiveGroupId) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, already user preferred"); return; } else { targetGroupId = userPreferredPrimaryGroupId; } } if (targetGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { // If there is no user preferred primary device, set the earliest connected // device in sharing session as the fallback. targetGroupId = getEarliestConnectedDeviceGroup(deviceGroupsInBroadcast); } } else { // Set the earliest connected device in sharing session as the fallback. targetGroupId = getEarliestConnectedDeviceGroup(deviceGroupsInBroadcast); } Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, target group id = " + targetGroupId); if (targetGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return; if (targetGroupId == fallbackActiveGroupId) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, already is fallback"); return; } CachedBluetoothDevice targetCachedDevice = getMainDevice( deviceGroupsInBroadcast.get(targetGroupId)); if (targetCachedDevice == null) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, fail to find main device"); return; } Log.d( TAG, "updateFallbackActiveDeviceIfNeeded, set active device: " + targetCachedDevice.getDevice()); targetCachedDevice.setActive(); } @NonNull private Map<Integer, List<BluetoothDevice>> getDeviceGroupsInBroadcast() { if (mServiceBroadcastAssistant == null) return new HashMap<>(); boolean hysteresisModeFixEnabled = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext); List<BluetoothDevice> connectedDevices = mServiceBroadcastAssistant.getConnectedDevices(); return connectedDevices.stream() .filter( device -> { List<BluetoothLeBroadcastReceiveState> sourceList = mServiceBroadcastAssistant.getAllSources(device); return !sourceList.isEmpty() && sourceList.stream().anyMatch( source -> hysteresisModeFixEnabled ? BluetoothUtils.isSourceMatched(source, mBroadcastId) : BluetoothUtils.isConnected(source)); }) .collect(Collectors.groupingBy( device -> BluetoothUtils.getGroupId(mDeviceManager.findDevice(device)))); } private int getEarliestConnectedDeviceGroup( @NonNull Map<Integer, List<BluetoothDevice>> deviceGroups) { List<BluetoothDevice> devices = BluetoothAdapter.getDefaultAdapter().getMostRecentlyConnectedDevices(); // Find the earliest connected device in sharing session. int targetDeviceIdx = -1; int targetGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; for (Map.Entry<Integer, List<BluetoothDevice>> entry : deviceGroups.entrySet()) { for (BluetoothDevice device : entry.getValue()) { if (devices.contains(device)) { int idx = devices.indexOf(device); if (idx > targetDeviceIdx) { targetDeviceIdx = idx; targetGroupId = entry.getKey(); } } } } Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, earliest group id = " + targetGroupId); return targetGroupId; } @Nullable @Nullable private CachedBluetoothDevice getMainDevice(@Nullable List<BluetoothDevice> devices) { private CachedBluetoothDevice getMainDevice(@Nullable List<BluetoothDevice> devices) { if (devices == null || devices.isEmpty()) return null; if (devices == null || devices.isEmpty()) return null; Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +4 −67 Original line number Original line Diff line number Diff line Loading @@ -221,8 +221,7 @@ public class BluetoothEventManagerTest { /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * LocalBluetoothLeBroadcast}#handleProfileConnected when audio sharing flag is off. * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when audio sharing flag is off. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -234,15 +233,13 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * LocalBluetoothLeBroadcast}#handleProfileConnected when the device does not support audio * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when the device does not support * sharing. * audio sharing. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -254,50 +251,12 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when audio sharing profile is * LocalBluetoothLeBroadcast}#handleProfileConnected when triggered for work profile. * not ready. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_profileNotReady_noUpdateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ false, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); } /** * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when triggered for profile * other than LE_AUDIO_BROADCAST_ASSISTANT or state other than STATE_DISCONNECTED. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_notAssistantProfile_noUpdateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ true, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); } /** * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when triggered for work profile. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -309,26 +268,6 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } /** * dispatchProfileConnectionStateChanged should call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when assistant profile is * disconnected and audio sharing is enabled. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_assistDisconnected_updateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ true, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } Loading @@ -347,14 +286,12 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast).handleProfileConnected(mCachedBluetoothDevice, verify(mBroadcast).handleProfileConnected(mCachedBluetoothDevice, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, mBtManager); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, mBtManager); } } private void setUpAudioSharing(boolean enableFlag, boolean enableFeature, private void setUpAudioSharing(boolean enableFlag, boolean enableFeature, boolean enableProfile, boolean workProfile) { boolean enableProfile, boolean workProfile) { mSetFlagsRule.disableFlags(Flags.FLAG_DISABLE_AUDIO_SHARING_AUTO_PICK_FALLBACK_IN_UI); if (enableFlag) { if (enableFlag) { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); } else { } else { Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +0 −12 Original line number Original line Diff line number Diff line Loading @@ -235,18 +235,6 @@ public class BluetoothEventManager { LocalBluetoothLeBroadcast broadcast = mBtManager == null ? null LocalBluetoothLeBroadcast broadcast = mBtManager == null ? null : mBtManager.getProfileManager().getLeAudioBroadcastProfile(); : mBtManager.getProfileManager().getLeAudioBroadcastProfile(); LocalBluetoothLeBroadcastAssistant assistant = mBtManager == null ? null : mBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); // Trigger updateFallbackActiveDeviceIfNeeded when ASSISTANT profile disconnected when // audio sharing is enabled. if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT && state == BluetoothAdapter.STATE_DISCONNECTED && BluetoothUtils.isAudioSharingUIAvailable(mContext) && broadcast != null && assistant != null && broadcast.isProfileReady() && assistant.isProfileReady()) { Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, ASSISTANT profile disconnected"); broadcast.updateFallbackActiveDeviceIfNeeded(); } // Dispatch handleOnProfileStateChanged to local broadcast profile // Dispatch handleOnProfileStateChanged to local broadcast profile if (Flags.promoteAudioSharingForSecondAutoConnectedLeaDevice() if (Flags.promoteAudioSharingForSecondAutoConnectedLeaDevice() && broadcast != null && broadcast != null Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +0 −110 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settingslib.bluetooth; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static com.android.settingslib.Utils.isAudioModeOngoingCall; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED_BY_RECEIVER; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED_BY_RECEIVER; Loading Loading @@ -74,17 +73,14 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.HashSet; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.Set; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; /** /** * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of * LocalBluetoothLeBroadcast provides an interface between the Settings app and the functionality of Loading Loading @@ -334,7 +330,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", sourceId = " + ", sourceId = " + sourceId); + sourceId); } } updateFallbackActiveDeviceIfNeeded(); } } @Override @Override Loading Loading @@ -1205,111 +1200,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { } } } } /** Update fallback active device if needed. */ public void updateFallbackActiveDeviceIfNeeded() { if (Flags.disableAudioSharingAutoPickFallbackInUi() || (mContext != null && Flags.audioSharingDeveloperOption() && BluetoothUtils.getAudioSharingPreviewValue(mContext.getContentResolver()))) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, disable flag is on"); return; } if (mIsWorkProfile) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile."); return; } if (isAudioModeOngoingCall(mContext)) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to ongoing call"); return; } Map<Integer, List<BluetoothDevice>> deviceGroupsInBroadcast = getDeviceGroupsInBroadcast(); if (deviceGroupsInBroadcast.isEmpty()) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to no sinks in broadcast"); return; } int targetGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; int fallbackActiveGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( mContext.getContentResolver()); if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)) { int userPreferredPrimaryGroupId = getUserPreferredPrimaryGroupId(); if (userPreferredPrimaryGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID && deviceGroupsInBroadcast.containsKey(userPreferredPrimaryGroupId)) { if (userPreferredPrimaryGroupId == fallbackActiveGroupId) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, already user preferred"); return; } else { targetGroupId = userPreferredPrimaryGroupId; } } if (targetGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { // If there is no user preferred primary device, set the earliest connected // device in sharing session as the fallback. targetGroupId = getEarliestConnectedDeviceGroup(deviceGroupsInBroadcast); } } else { // Set the earliest connected device in sharing session as the fallback. targetGroupId = getEarliestConnectedDeviceGroup(deviceGroupsInBroadcast); } Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, target group id = " + targetGroupId); if (targetGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return; if (targetGroupId == fallbackActiveGroupId) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, already is fallback"); return; } CachedBluetoothDevice targetCachedDevice = getMainDevice( deviceGroupsInBroadcast.get(targetGroupId)); if (targetCachedDevice == null) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, fail to find main device"); return; } Log.d( TAG, "updateFallbackActiveDeviceIfNeeded, set active device: " + targetCachedDevice.getDevice()); targetCachedDevice.setActive(); } @NonNull private Map<Integer, List<BluetoothDevice>> getDeviceGroupsInBroadcast() { if (mServiceBroadcastAssistant == null) return new HashMap<>(); boolean hysteresisModeFixEnabled = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext); List<BluetoothDevice> connectedDevices = mServiceBroadcastAssistant.getConnectedDevices(); return connectedDevices.stream() .filter( device -> { List<BluetoothLeBroadcastReceiveState> sourceList = mServiceBroadcastAssistant.getAllSources(device); return !sourceList.isEmpty() && sourceList.stream().anyMatch( source -> hysteresisModeFixEnabled ? BluetoothUtils.isSourceMatched(source, mBroadcastId) : BluetoothUtils.isConnected(source)); }) .collect(Collectors.groupingBy( device -> BluetoothUtils.getGroupId(mDeviceManager.findDevice(device)))); } private int getEarliestConnectedDeviceGroup( @NonNull Map<Integer, List<BluetoothDevice>> deviceGroups) { List<BluetoothDevice> devices = BluetoothAdapter.getDefaultAdapter().getMostRecentlyConnectedDevices(); // Find the earliest connected device in sharing session. int targetDeviceIdx = -1; int targetGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; for (Map.Entry<Integer, List<BluetoothDevice>> entry : deviceGroups.entrySet()) { for (BluetoothDevice device : entry.getValue()) { if (devices.contains(device)) { int idx = devices.indexOf(device); if (idx > targetDeviceIdx) { targetDeviceIdx = idx; targetGroupId = entry.getKey(); } } } } Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, earliest group id = " + targetGroupId); return targetGroupId; } @Nullable @Nullable private CachedBluetoothDevice getMainDevice(@Nullable List<BluetoothDevice> devices) { private CachedBluetoothDevice getMainDevice(@Nullable List<BluetoothDevice> devices) { if (devices == null || devices.isEmpty()) return null; if (devices == null || devices.isEmpty()) return null; Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +4 −67 Original line number Original line Diff line number Diff line Loading @@ -221,8 +221,7 @@ public class BluetoothEventManagerTest { /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * LocalBluetoothLeBroadcast}#handleProfileConnected when audio sharing flag is off. * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when audio sharing flag is off. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -234,15 +233,13 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * LocalBluetoothLeBroadcast}#handleProfileConnected when the device does not support audio * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when the device does not support * sharing. * audio sharing. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -254,50 +251,12 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } /** /** * dispatchProfileConnectionStateChanged should not call {@link * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when audio sharing profile is * LocalBluetoothLeBroadcast}#handleProfileConnected when triggered for work profile. * not ready. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_profileNotReady_noUpdateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ false, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); } /** * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when triggered for profile * other than LE_AUDIO_BROADCAST_ASSISTANT or state other than STATE_DISCONNECTED. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_notAssistantProfile_noUpdateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ true, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); } /** * dispatchProfileConnectionStateChanged should not call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded and * {@link LocalBluetoothLeBroadcast}#handleProfileConnected when triggered for work profile. */ */ @Test @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) Loading @@ -309,26 +268,6 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } /** * dispatchProfileConnectionStateChanged should call {@link * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when assistant profile is * disconnected and audio sharing is enabled. */ @Test @EnableFlags(Flags.FLAG_PROMOTE_AUDIO_SHARING_FOR_SECOND_AUTO_CONNECTED_LEA_DEVICE) public void dispatchProfileConnectionStateChanged_assistDisconnected_updateFallbackDevice() { setUpAudioSharing(/* enableFlag= */ true, /* enableFeature= */ true, /* enableProfile= */ true, /* workProfile= */ false); mBluetoothEventManager.dispatchProfileConnectionStateChanged( mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); verify(mBroadcast, never()).handleProfileConnected(any(), anyInt(), any()); } } Loading @@ -347,14 +286,12 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); verify(mBroadcast, never()).updateFallbackActiveDeviceIfNeeded(); verify(mBroadcast).handleProfileConnected(mCachedBluetoothDevice, verify(mBroadcast).handleProfileConnected(mCachedBluetoothDevice, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, mBtManager); BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, mBtManager); } } private void setUpAudioSharing(boolean enableFlag, boolean enableFeature, private void setUpAudioSharing(boolean enableFlag, boolean enableFeature, boolean enableProfile, boolean workProfile) { boolean enableProfile, boolean workProfile) { mSetFlagsRule.disableFlags(Flags.FLAG_DISABLE_AUDIO_SHARING_AUTO_PICK_FALLBACK_IN_UI); if (enableFlag) { if (enableFlag) { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); } else { } else { Loading