Loading src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java +52 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -45,6 +46,11 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Map; public class AudioSharingReceiver extends BroadcastReceiver { private static final String TAG = "AudioSharingReceiver"; private static final String ACTION_LE_AUDIO_SHARING_SETTINGS = Loading Loading @@ -141,6 +147,52 @@ public class AudioSharingReceiver extends BroadcastReceiver { showAddSourceNotification(context, device); } break; case ACTION_LE_AUDIO_SHARING_ADD_SOURCE: if (!BluetoothUtils.isAudioSharingUIAvailable(context)) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, feature disabled."); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } BluetoothDevice sink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE, BluetoothDevice.class); if (sink == null) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, null device"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } LocalBluetoothManager manager = Utils.getLocalBtManager(context); boolean isBroadcasting = BluetoothUtils.isBroadcasting(manager); if (!isBroadcasting) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, not broadcasting"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } Map<Integer, List<BluetoothDevice>> groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(manager); int groupId = groupedDevices.entrySet().stream().filter( entry -> entry.getValue().contains(sink)).findFirst().map( Map.Entry::getKey).orElse(BluetoothCsipSetCoordinator.GROUP_ID_INVALID); if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, no valid group id"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } List<BluetoothDevice> sinksToAdd = groupedDevices.getOrDefault(groupId, ImmutableList.of()).stream().filter( d -> !BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(d, manager)).toList(); if (sinksToAdd.isEmpty()) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, already has source"); } else if (groupedDevices.entrySet().stream().filter( entry -> entry.getKey() != groupId && entry.getValue().stream().anyMatch( d -> BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(d, manager))).toList().size() >= 2) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, already 2 sinks"); } else { AudioSharingUtils.addSourceToTargetSinks(sinksToAdd, manager); } cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); break; case ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF: int notifId = intent.getIntExtra(EXTRA_NOTIF_ID, -1); if (notifId != -1) { Loading tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java +196 −9 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -41,6 +42,8 @@ import android.app.NotificationManager; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothStatusCodes; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -55,11 +58,16 @@ import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.R; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.flags.Flags; import com.google.common.collect.ImmutableList; import org.junit.After; import org.junit.Before; import org.junit.Rule; Loading @@ -82,6 +90,8 @@ import java.util.stream.Collectors; public class AudioSharingReceiverTest { private static final String ACTION_LE_AUDIO_SHARING_STOP = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_STOP"; private static final String ACTION_LE_AUDIO_SHARING_ADD_SOURCE = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_ADD_SOURCE"; private static final String ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_CANCEL_NOTIF"; private static final String EXTRA_NOTIF_ID = "NOTIF_ID"; Loading @@ -97,7 +107,9 @@ public class AudioSharingReceiverTest { private FakeFeatureFactory mFeatureFactory; @Mock private LocalBluetoothProfileManager mLocalBtProfileManager; @Mock private LocalBluetoothLeBroadcast mBroadcast; @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private LocalBluetoothManager mLocalBtManager; @Mock private BluetoothDevice mDevice; @Mock private NotificationManager mNm; @Before Loading @@ -115,6 +127,8 @@ public class AudioSharingReceiverTest { mLocalBluetoothManager = Utils.getLocalBtManager(mContext); when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBtProfileManager); when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast); when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant); when(mDevice.getAlias()).thenReturn(TEST_DEVICE_NAME); mFeatureFactory = FakeFeatureFactory.setupForTest(); } Loading Loading @@ -297,12 +311,10 @@ public class AudioSharingReceiverTest { mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED); BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -314,12 +326,10 @@ public class AudioSharingReceiverTest { @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingDeviceConnected_showDialog() { BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(true); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -332,12 +342,10 @@ public class AudioSharingReceiverTest { @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingDeviceConnected_showNotification() { BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -346,6 +354,185 @@ public class AudioSharingReceiverTest { any(Notification.class)); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_broadcastDisabled_cancelNotif() { mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_nullArg_cancelNotif() { Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(any(BluetoothDevice.class), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_notInBroadcast_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_notConnected_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_invalidGroupId_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice); when(cachedDevice.getDevice()).thenReturn(mDevice); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_alreadyTwoSinks_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice1); BluetoothDevice device2 = mock(BluetoothDevice.class); CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(device2)).thenReturn(cachedDevice2); when(cachedDevice1.getGroupId()).thenReturn(1); when(cachedDevice1.getDevice()).thenReturn(mDevice); when(cachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME); when(cachedDevice2.getGroupId()).thenReturn(2); when(cachedDevice2.getDevice()).thenReturn(device2); when(cachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice, device2)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_alreadyHasSource_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice); when(cachedDevice.getGroupId()).thenReturn(1); when(cachedDevice.getDevice()).thenReturn(mDevice); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(mDevice)).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_addSource() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(metadata); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice1); BluetoothDevice device2 = mock(BluetoothDevice.class); CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(device2)).thenReturn(cachedDevice2); when(cachedDevice1.getGroupId()).thenReturn(1); when(cachedDevice1.getDevice()).thenReturn(mDevice); when(cachedDevice2.getGroupId()).thenReturn(2); when(cachedDevice2.getDevice()).thenReturn(device2); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice, device2)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(device2)).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant).addSource(mDevice, metadata, /* isGroupOp= */ false); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingCancelNotif_cancel() { Loading Loading
src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiver.java +52 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -45,6 +46,11 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Map; public class AudioSharingReceiver extends BroadcastReceiver { private static final String TAG = "AudioSharingReceiver"; private static final String ACTION_LE_AUDIO_SHARING_SETTINGS = Loading Loading @@ -141,6 +147,52 @@ public class AudioSharingReceiver extends BroadcastReceiver { showAddSourceNotification(context, device); } break; case ACTION_LE_AUDIO_SHARING_ADD_SOURCE: if (!BluetoothUtils.isAudioSharingUIAvailable(context)) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, feature disabled."); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } BluetoothDevice sink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE, BluetoothDevice.class); if (sink == null) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, null device"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } LocalBluetoothManager manager = Utils.getLocalBtManager(context); boolean isBroadcasting = BluetoothUtils.isBroadcasting(manager); if (!isBroadcasting) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, not broadcasting"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } Map<Integer, List<BluetoothDevice>> groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(manager); int groupId = groupedDevices.entrySet().stream().filter( entry -> entry.getValue().contains(sink)).findFirst().map( Map.Entry::getKey).orElse(BluetoothCsipSetCoordinator.GROUP_ID_INVALID); if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, no valid group id"); cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); return; } List<BluetoothDevice> sinksToAdd = groupedDevices.getOrDefault(groupId, ImmutableList.of()).stream().filter( d -> !BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(d, manager)).toList(); if (sinksToAdd.isEmpty()) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, already has source"); } else if (groupedDevices.entrySet().stream().filter( entry -> entry.getKey() != groupId && entry.getValue().stream().anyMatch( d -> BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(d, manager))).toList().size() >= 2) { Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_ADD_SOURCE, already 2 sinks"); } else { AudioSharingUtils.addSourceToTargetSinks(sinksToAdd, manager); } cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID); break; case ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF: int notifId = intent.getIntExtra(EXTRA_NOTIF_ID, -1); if (notifId != -1) { Loading
tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingReceiverTest.java +196 −9 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -41,6 +42,8 @@ import android.app.NotificationManager; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothStatusCodes; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -55,11 +58,16 @@ import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.R; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.flags.Flags; import com.google.common.collect.ImmutableList; import org.junit.After; import org.junit.Before; import org.junit.Rule; Loading @@ -82,6 +90,8 @@ import java.util.stream.Collectors; public class AudioSharingReceiverTest { private static final String ACTION_LE_AUDIO_SHARING_STOP = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_STOP"; private static final String ACTION_LE_AUDIO_SHARING_ADD_SOURCE = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_ADD_SOURCE"; private static final String ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF = "com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_CANCEL_NOTIF"; private static final String EXTRA_NOTIF_ID = "NOTIF_ID"; Loading @@ -97,7 +107,9 @@ public class AudioSharingReceiverTest { private FakeFeatureFactory mFeatureFactory; @Mock private LocalBluetoothProfileManager mLocalBtProfileManager; @Mock private LocalBluetoothLeBroadcast mBroadcast; @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private LocalBluetoothManager mLocalBtManager; @Mock private BluetoothDevice mDevice; @Mock private NotificationManager mNm; @Before Loading @@ -115,6 +127,8 @@ public class AudioSharingReceiverTest { mLocalBluetoothManager = Utils.getLocalBtManager(mContext); when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBtProfileManager); when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast); when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant); when(mDevice.getAlias()).thenReturn(TEST_DEVICE_NAME); mFeatureFactory = FakeFeatureFactory.setupForTest(); } Loading Loading @@ -297,12 +311,10 @@ public class AudioSharingReceiverTest { mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED); BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -314,12 +326,10 @@ public class AudioSharingReceiverTest { @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingDeviceConnected_showDialog() { BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(true); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -332,12 +342,10 @@ public class AudioSharingReceiverTest { @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingDeviceConnected_showNotification() { BluetoothDevice device = mock(BluetoothDevice.class); when(device.getAlias()).thenReturn(TEST_DEVICE_NAME); setAppInForeground(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, device); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); Loading @@ -346,6 +354,185 @@ public class AudioSharingReceiverTest { any(Notification.class)); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_broadcastDisabled_cancelNotif() { mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_nullArg_cancelNotif() { Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(any(BluetoothDevice.class), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_notInBroadcast_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(false); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_notConnected_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingAddSource_invalidGroupId_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice); when(cachedDevice.getDevice()).thenReturn(mDevice); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_alreadyTwoSinks_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice1); BluetoothDevice device2 = mock(BluetoothDevice.class); CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(device2)).thenReturn(cachedDevice2); when(cachedDevice1.getGroupId()).thenReturn(1); when(cachedDevice1.getDevice()).thenReturn(mDevice); when(cachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME); when(cachedDevice2.getGroupId()).thenReturn(2); when(cachedDevice2.getDevice()).thenReturn(device2); when(cachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice, device2)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_alreadyHasSource_cancelNotif() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice); when(cachedDevice.getGroupId()).thenReturn(1); when(cachedDevice.getDevice()).thenReturn(mDevice); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(mDevice)).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant, never()).addSource(eq(mDevice), any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX}) public void broadcastReceiver_receiveAudioSharingAddSource_addSource() { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(metadata); CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(mDevice)).thenReturn(cachedDevice1); BluetoothDevice device2 = mock(BluetoothDevice.class); CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class); when(deviceManager.findDevice(device2)).thenReturn(cachedDevice2); when(cachedDevice1.getGroupId()).thenReturn(1); when(cachedDevice1.getDevice()).thenReturn(mDevice); when(cachedDevice2.getGroupId()).thenReturn(2); when(cachedDevice2.getDevice()).thenReturn(device2); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice, device2)); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); when(state.getBroadcastId()).thenReturn(1); when(mAssistant.getAllSources(device2)).thenReturn(ImmutableList.of(state)); Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE); intent.setPackage(mContext.getPackageName()); intent.putExtra(EXTRA_BLUETOOTH_DEVICE, mDevice); AudioSharingReceiver audioSharingReceiver = getAudioSharingReceiver(intent); audioSharingReceiver.onReceive(mContext, intent); verify(mAssistant).addSource(mDevice, metadata, /* isGroupOp= */ false); verify(mNm).cancel(com.android.settings.R.string.share_audio_notification_title); } @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void broadcastReceiver_receiveAudioSharingCancelNotif_cancel() { Loading