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; + } }