From 22e3f5178497da9b41df656c310faf7900b3a10e Mon Sep 17 00:00:00 2001 From: Yiyi Shen Date: Wed, 6 Dec 2023 16:11:02 +0800 Subject: [PATCH] [Audiosharing] Update media devices section. 1. Filter out the media devices in audio sharing from the section. 2. During the audio sharing, click the media device will lead to stopping the sharing. Flagged with enable_le_audio_sharing Bug: 305620450 Test: atest AvailableMediaBluetoothDeviceUpdaterTest.java Change-Id: I0676fd5aa98e593c6a5458845fc1b1631a5a6698 --- .../AvailableMediaBluetoothDeviceUpdater.java | 59 +++- .../audiosharing/AudioSharingUtils.java | 17 + ...ilableMediaBluetoothDeviceUpdaterTest.java | 310 ++++++++++++++---- .../shadow/ShadowBluetoothAdapter.java | 20 ++ 4 files changed, 320 insertions(+), 86 deletions(-) diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java index 99ebd7b0bbd..13990325d98 100644 --- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java +++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java @@ -23,11 +23,11 @@ import android.util.Log; import androidx.preference.Preference; import com.android.settings.connecteddevice.DevicePreferenceCallback; +import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.LocalBluetoothManager; -/** - * Controller to maintain available media Bluetooth devices - */ +/** Controller to maintain available media Bluetooth devices */ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater implements Preference.OnPreferenceClickListener { @@ -37,11 +37,15 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater private static final String PREF_KEY = "available_media_bt"; private final AudioManager mAudioManager; + private final LocalBluetoothManager mLocalBtManager; - public AvailableMediaBluetoothDeviceUpdater(Context context, - DevicePreferenceCallback devicePreferenceCallback, int metricsCategory) { + public AvailableMediaBluetoothDeviceUpdater( + Context context, + DevicePreferenceCallback devicePreferenceCallback, + int metricsCategory) { super(context, devicePreferenceCallback, metricsCategory); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + mLocalBtManager = Utils.getLocalBtManager(context); } @Override @@ -69,14 +73,30 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater if (DBG) { Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile); } - // If device is Hearing Aid or LE Audio, it is compatible with HFP and A2DP. + // If device is Hearing Aid, it is compatible with HFP and A2DP. // It would show in Available Devices group. - if (cachedDevice.isConnectedAshaHearingAidDevice() - || cachedDevice.isConnectedLeAudioDevice()) { - Log.d(TAG, "isFilterMatched() device : " + - cachedDevice.getName() + ", the profile is connected."); + if (cachedDevice.isConnectedAshaHearingAidDevice()) { + Log.d( + TAG, + "isFilterMatched() device : " + + cachedDevice.getName() + + ", the Hearing Aid profile is connected."); return true; } + // If device is LE Audio, it is compatible with HFP and A2DP. + // It would show in Available Devices group if the audio sharing flag is disabled or + // the device is not in the audio sharing session. + if (cachedDevice.isConnectedLeAudioDevice()) { + if (!AudioSharingUtils.isFeatureEnabled() + || !AudioSharingUtils.hasBroadcastSource(cachedDevice, mLocalManager)) { + Log.d( + TAG, + "isFilterMatched() device : " + + cachedDevice.getName() + + ", the LE Audio profile is connected and not in sharing."); + return true; + } + } // According to the current audio profile type, // this page will show the bluetooth device that have corresponding profile. // For example: @@ -92,8 +112,12 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater break; } if (DBG) { - Log.d(TAG, "isFilterMatched() device : " + - cachedDevice.getName() + ", isFilterMatched : " + isFilterMatched); + Log.d( + TAG, + "isFilterMatched() device : " + + cachedDevice.getName() + + ", isFilterMatched : " + + isFilterMatched); } } return isFilterMatched; @@ -102,8 +126,15 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater @Override public boolean onPreferenceClick(Preference preference) { mMetricsFeatureProvider.logClickedPreference(preference, mMetricsCategory); - final CachedBluetoothDevice device = ((BluetoothDevicePreference) preference) - .getBluetoothDevice(); + final CachedBluetoothDevice device = + ((BluetoothDevicePreference) preference).getBluetoothDevice(); + if (AudioSharingUtils.isFeatureEnabled() + && AudioSharingUtils.isBroadcasting(mLocalBtManager)) { + if (DBG) { + Log.d(TAG, "onPreferenceClick stop broadcasting."); + } + AudioSharingUtils.stopBroadcasting(mLocalBtManager); + } return device.setActive(); } diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java index 656d9f507b8..b5361f22057 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java @@ -29,6 +29,7 @@ import com.android.settings.flags.Flags; import com.android.settingslib.bluetooth.BluetoothUtils; 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.utils.ThreadUtils; @@ -298,4 +299,20 @@ public class AudioSharingUtils { targetDevice.setActive(); } } + + /** Returns if the broadcast is on-going. */ + public static boolean isBroadcasting(LocalBluetoothManager manager) { + if (manager == null) return false; + LocalBluetoothLeBroadcast broadcast = + manager.getProfileManager().getLeAudioBroadcastProfile(); + return broadcast != null && broadcast.isEnabled(null); + } + + /** Stops the latest broadcast. */ + public static void stopBroadcasting(LocalBluetoothManager manager) { + if (manager == null) return; + LocalBluetoothLeBroadcast broadcast = + manager.getProfileManager().getLeAudioBroadcastProfile(); + broadcast.stopBroadcast(broadcast.getLatestBroadcastId()); + } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java index d69b5d4d3bd..dceadeb97aa 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java @@ -16,6 +16,7 @@ package com.android.settings.bluetooth; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -24,20 +25,36 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Pair; import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.flags.Flags; import com.android.settings.testutils.shadow.ShadowAudioManager; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; -import com.android.settings.testutils.shadow.ShadowCachedBluetoothDeviceManager; +import com.android.settings.testutils.shadow.ShadowBluetoothUtils; 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.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -51,21 +68,29 @@ import java.util.ArrayList; import java.util.Collection; @RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class, - ShadowCachedBluetoothDeviceManager.class}) +@Config( + shadows = { + ShadowAudioManager.class, + ShadowBluetoothAdapter.class, + ShadowBluetoothUtils.class + }) public class AvailableMediaBluetoothDeviceUpdaterTest { + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; - @Mock - private DashboardFragment mDashboardFragment; - @Mock - private DevicePreferenceCallback mDevicePreferenceCallback; - @Mock - private CachedBluetoothDevice mCachedBluetoothDevice; - @Mock - private BluetoothDevice mBluetoothDevice; - @Mock - private Drawable mDrawable; + @Mock private DashboardFragment mDashboardFragment; + @Mock private DevicePreferenceCallback mDevicePreferenceCallback; + @Mock private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock private BluetoothDevice mBluetoothDevice; + @Mock private Drawable mDrawable; + @Mock private LocalBluetoothManager mLocalBtManager; + @Mock private LocalBluetoothProfileManager mLocalBtProfileManager; + @Mock private CachedBluetoothDeviceManager mCachedDeviceManager; + @Mock private LocalBluetoothLeBroadcast mBroadcast; + @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; + @Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState; private Context mContext; private AvailableMediaBluetoothDeviceUpdater mBluetoothDeviceUpdater; @@ -73,7 +98,6 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { private AudioManager mAudioManager; private BluetoothDevicePreference mPreference; private ShadowBluetoothAdapter mShadowBluetoothAdapter; - private ShadowCachedBluetoothDeviceManager mShadowCachedBluetoothDeviceManager; @Before public void setUp() { @@ -81,25 +105,33 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { mContext = RuntimeEnvironment.application; mAudioManager = mContext.getSystemService(AudioManager.class); + ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; + mLocalBtManager = Utils.getLocalBtManager(mContext); + when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); mShadowBluetoothAdapter.setEnabled(true); - mShadowCachedBluetoothDeviceManager = Shadow.extract( - Utils.getLocalBtManager(mContext).getCachedDeviceManager()); mCachedDevices = new ArrayList<>(); mCachedDevices.add(mCachedBluetoothDevice); - mShadowCachedBluetoothDeviceManager.setCachedDevicesCopy(mCachedDevices); + when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices); Pair pairs = new Pair<>(mDrawable, "fake_device"); doReturn(mContext).when(mDashboardFragment).getContext(); when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS); when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pairs); + when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(ImmutableSet.of()); - mBluetoothDeviceUpdater = spy(new AvailableMediaBluetoothDeviceUpdater(mContext, - mDevicePreferenceCallback, /* metricsCategory= */ 0)); + mBluetoothDeviceUpdater = + spy( + new AvailableMediaBluetoothDeviceUpdater( + mContext, mDevicePreferenceCallback, /* metricsCategory= */ 0)); mBluetoothDeviceUpdater.setPrefContext(mContext); - mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, false, - BluetoothDevicePreference.SortType.TYPE_DEFAULT); + mPreference = + new BluetoothDevicePreference( + mContext, + mCachedBluetoothDevice, + false, + BluetoothDevicePreference.SortType.TYPE_DEFAULT); doNothing().when(mBluetoothDeviceUpdater).addPreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference(any()); } @@ -107,8 +139,8 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onAudioModeChanged_hfpDeviceConnected_inCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true); mBluetoothDeviceUpdater.onAudioModeChanged(); @@ -119,8 +151,8 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onAudioModeChanged_hfpDeviceConnected_notInCall_removePreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true); mBluetoothDeviceUpdater.onAudioModeChanged(); @@ -131,8 +163,8 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onAudioModeChanged_a2dpDeviceConnected_inCall_removePreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true); mBluetoothDeviceUpdater.onAudioModeChanged(); @@ -143,8 +175,8 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onAudioModeChanged_a2dpDeviceConnected_notInCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true); mBluetoothDeviceUpdater.onAudioModeChanged(); @@ -155,12 +187,12 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_a2dpDeviceConnected_notInCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } @@ -168,12 +200,12 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_a2dpDeviceConnected_inCall_removePreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); } @@ -181,12 +213,12 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_hfpDeviceConnected_notInCall_removePreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); } @@ -194,12 +226,12 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_hfpDeviceConnected_inCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } @@ -207,12 +239,14 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_ashaHearingAidConnected_notInCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.HEARING_AID); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } @@ -220,53 +254,137 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_ashaHearingAidConnected_inCall_addPreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater. - isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.HEARING_AID); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void onProfileConnectionStateChanged_leAudioDeviceConnected_notInCall_addsPreference() { + setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false); mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater - .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void onProfileConnectionStateChanged_leAudioDeviceConnected_inCall_addsPreference() { + setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false); mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater - .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); } + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void + onProfileConnectionStateChanged_leaDeviceConnected_notInCall_notInBroadcast_addsPref() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false); + mAudioManager.setMode(AudioManager.MODE_NORMAL); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); + when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); + + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); + + verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void + onProfileConnectionStateChanged_leaDeviceConnected_inCall_notInBroadcast_addsPref() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false); + mAudioManager.setMode(AudioManager.MODE_IN_CALL); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); + when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); + + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); + + verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void + onProfileConnectionStateChanged_leaDeviceConnected_notInCall_inBroadcast_removesPref() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true); + mAudioManager.setMode(AudioManager.MODE_NORMAL); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); + when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); + + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); + + verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void + onProfileConnectionStateChanged_leaDeviceConnected_inCall_inBroadcast_removesPref() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true); + mAudioManager.setMode(AudioManager.MODE_IN_CALL); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); + when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); + + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); + + verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); + } + @Test public void onProfileConnectionStateChanged_deviceIsNotInList_notInCall_invokesRemovePreference() { mAudioManager.setMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater - .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); mCachedDevices.clear(); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); } @@ -274,30 +392,78 @@ public class AvailableMediaBluetoothDeviceUpdaterTest { @Test public void onProfileConnectionStateChanged_deviceIsNotInList_inCall_invokesRemovePreference() { mAudioManager.setMode(AudioManager.MODE_IN_CALL); - when(mBluetoothDeviceUpdater - .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); + when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))) + .thenReturn(true); when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true); mCachedDevices.clear(); - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.LE_AUDIO); verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); } @Test public void onProfileConnectionStateChanged_deviceDisconnected_removePreference() { - mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice, - BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP); + mBluetoothDeviceUpdater.onProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP); verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); } @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void onClick_Preference_setActive() { + setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false); mBluetoothDeviceUpdater.onPreferenceClick(mPreference); verify(mCachedBluetoothDevice).setActive(); } -} + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void onClick_Preference_isNotBroadcasting_setActive() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false); + mBluetoothDeviceUpdater.onPreferenceClick(mPreference); + + verify(mCachedBluetoothDevice).setActive(); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) + public void onClick_Preference_isBroadcasting_stopBroadcastingAndSetActive() { + setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true); + doNothing().when(mBroadcast).stopBroadcast(anyInt()); + mBluetoothDeviceUpdater.onPreferenceClick(mPreference); + + verify(mBroadcast).stopBroadcast(anyInt()); + verify(mCachedBluetoothDevice).setActive(); + } + + private void setUpBroadcast(boolean isSupported, boolean isBroadcasting) { + if (isSupported) { + mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBtProfileManager); + when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast); + when(mBroadcast.isEnabled(null)).thenReturn(isBroadcasting); + when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()) + .thenReturn(mAssistant); + if (isBroadcasting) { + when(mAssistant.getAllSources(any())) + .thenReturn(ImmutableList.of(mBroadcastReceiveState)); + } else { + when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of()); + } + } else { + mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED); + mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED); + } + } +} diff --git a/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java index 9de5c7fc2da..20021ea8ca6 100644 --- a/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java +++ b/tests/robotests/testutils/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java @@ -31,6 +31,8 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto private int mState; private List mSupportedProfiles = new ArrayList<>(); private List mMostRecentlyConnectedDevices = new ArrayList<>(); + private int mIsLeAudioBroadcastSourceSupported; + private int mIsLeAudioBroadcastAssistantSupported; @Implementation protected List getSupportedProfiles() { @@ -67,4 +69,22 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto public void setMostRecentlyConnectedDevices(List list) { mMostRecentlyConnectedDevices = list; } + + @Implementation + protected int isLeAudioBroadcastSourceSupported() { + return mIsLeAudioBroadcastSourceSupported; + } + + public void setIsLeAudioBroadcastSourceSupported(int isSupported) { + mIsLeAudioBroadcastSourceSupported = isSupported; + } + + @Implementation + protected int isLeAudioBroadcastAssistantSupported() { + return mIsLeAudioBroadcastAssistantSupported; + } + + public void setIsLeAudioBroadcastAssistantSupported(int isSupported) { + mIsLeAudioBroadcastAssistantSupported = isSupported; + } }