diff --git a/src/com/android/settings/sound/AudioSwitchPreferenceController.java b/src/com/android/settings/sound/AudioSwitchPreferenceController.java index 5b70d16a7a7..38fecfc5bc2 100644 --- a/src/com/android/settings/sound/AudioSwitchPreferenceController.java +++ b/src/com/android/settings/sound/AudioSwitchPreferenceController.java @@ -45,6 +45,7 @@ import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -214,6 +215,25 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont return a2dpProfile.getConnectedDevices(); } + /** + * Get LE Audio profile connected devices + */ + protected List getConnectedLeAudioDevices() { + final List connectedDevices = new ArrayList<>(); + final LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile(); + if (leAudioProfile == null) { + Log.d(TAG, "LeAudioProfile is null"); + return connectedDevices; + } + final List devices = leAudioProfile.getConnectedDevices(); + for (BluetoothDevice device : devices) { + if (device.isConnected()) { + connectedDevices.add(device); + } + } + return connectedDevices; + } + /** * get hearing aid profile connected device, exclude other devices with same hiSyncId. */ @@ -259,6 +279,24 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont return null; } + /** + * Find active LE Audio device + */ + protected BluetoothDevice findActiveLeAudioDevice() { + final LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile(); + + if (leAudioProfile != null) { + List activeDevices = leAudioProfile.getActiveDevices(); + for (BluetoothDevice leAudioDevice : activeDevices) { + if (leAudioDevice != null) { + return leAudioDevice; + } + } + } + Log.d(TAG, "There is no LE audio profile or no active LE audio device"); + return null; + } + /** * Find the active device from the corresponding profile. * diff --git a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java index 15f47cf2593..35cc65fafe7 100644 --- a/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java +++ b/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java @@ -103,6 +103,7 @@ public class HandsFreeProfileOutputPreferenceController extends AudioSwitchPrefe mConnectedDevices.clear(); mConnectedDevices.addAll(getConnectedHfpDevices()); mConnectedDevices.addAll(getConnectedHearingAidDevices()); + mConnectedDevices.addAll(getConnectedLeAudioDevices()); final int numDevices = mConnectedDevices.size(); if (numDevices == 0) { @@ -181,12 +182,22 @@ public class HandsFreeProfileOutputPreferenceController extends AudioSwitchPrefe @Override public BluetoothDevice findActiveDevice() { - BluetoothDevice activeDevice = findActiveHearingAidDevice(); + BluetoothDevice haActiveDevice = findActiveHearingAidDevice(); + BluetoothDevice leAudioActiveDevice = findActiveLeAudioDevice(); final HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile(); - if (activeDevice == null && headsetProfile != null) { - activeDevice = headsetProfile.getActiveDevice(); + if (haActiveDevice != null) { + return haActiveDevice; } - return activeDevice; + + if (leAudioActiveDevice != null) { + return leAudioActiveDevice; + } + + if (headsetProfile != null && headsetProfile.getActiveDevice() != null) { + return headsetProfile.getActiveDevice(); + } + + return null; } } diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java index 4ec00e358a9..758f7e33383 100644 --- a/src/com/android/settings/sound/MediaOutputPreferenceController.java +++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java @@ -88,9 +88,11 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro // Find active device and set its name as the preference's summary List connectedA2dpDevices = getConnectedA2dpDevices(); List connectedHADevices = getConnectedHearingAidDevices(); + List connectedLeAudioDevices = getConnectedLeAudioDevices(); if (mAudioManager.getMode() == AudioManager.MODE_NORMAL && ((connectedA2dpDevices != null && !connectedA2dpDevices.isEmpty()) - || (connectedHADevices != null && !connectedHADevices.isEmpty()))) { + || (connectedHADevices != null && !connectedHADevices.isEmpty()) + || (connectedLeAudioDevices != null && !connectedLeAudioDevices.isEmpty()))) { activeDevice = findActiveDevice(); } mPreference.setTitle(mContext.getString(R.string.media_output_label_title, @@ -103,13 +105,23 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro @Override public BluetoothDevice findActiveDevice() { - BluetoothDevice activeDevice = findActiveHearingAidDevice(); + BluetoothDevice haActiveDevice = findActiveHearingAidDevice(); + BluetoothDevice leAudioActiveDevice = findActiveLeAudioDevice(); final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); - if (activeDevice == null && a2dpProfile != null) { - activeDevice = a2dpProfile.getActiveDevice(); + if (haActiveDevice != null) { + return haActiveDevice; } - return activeDevice; + + if (leAudioActiveDevice != null) { + return leAudioActiveDevice; + } + + if (a2dpProfile != null && a2dpProfile.getActiveDevice() != null) { + return a2dpProfile.getActiveDevice(); + } + + return null; } /** diff --git a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java index b04a2cd21bf..77ddfbd6ef9 100644 --- a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java @@ -53,12 +53,12 @@ import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -74,7 +74,6 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class, @@ -102,6 +101,8 @@ public class AudioOutputSwitchPreferenceControllerTest { private HeadsetProfile mHeadsetProfile; @Mock private HearingAidProfile mHearingAidProfile; + @Mock + private LeAudioProfile mLeAudioProfile; private Context mContext; private PreferenceScreen mScreen; @@ -117,6 +118,7 @@ public class AudioOutputSwitchPreferenceControllerTest { private AudioSwitchPreferenceController mController; private List mProfileConnectedDevices; private List mHearingAidActiveDevices; + private List mLeAudioActiveDevices; private List mEmptyDevices; private ShadowPackageManager mPackageManager; @@ -136,6 +138,7 @@ public class AudioOutputSwitchPreferenceControllerTest { when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); when(mLocalBluetoothProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile); + when(mLocalBluetoothProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); mPackageManager = Shadow.extract(mContext.getPackageManager()); mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true); @@ -156,6 +159,7 @@ public class AudioOutputSwitchPreferenceControllerTest { mPreference = new ListPreference(mContext); mProfileConnectedDevices = new ArrayList<>(); mHearingAidActiveDevices = new ArrayList<>(2); + mLeAudioActiveDevices = new ArrayList<>(); mEmptyDevices = new ArrayList<>(2); when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); @@ -391,6 +395,55 @@ public class AudioOutputSwitchPreferenceControllerTest { assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice); } + @Test + public void getConnectedLeAudioDevices_connectedLeAudioDevice_shouldAddDeviceToList() { + mEmptyDevices.clear(); + mProfileConnectedDevices.clear(); + mProfileConnectedDevices.add(mBluetoothDevice); + when(mLeAudioProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); + + mEmptyDevices.addAll(mController.getConnectedLeAudioDevices()); + + assertThat(mEmptyDevices).containsExactly(mBluetoothDevice); + } + + @Test + public void getConnectedLeAudioDevices_disconnectedLeAudioDevice_shouldNotAddDeviceToList() { + BluetoothDevice connectdBtLeAduioDevice = + spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2)); + when(connectdBtLeAduioDevice.isConnected()).thenReturn(true); + BluetoothDevice disonnectdBtLeAduioDevice = + spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3)); + when(disonnectdBtLeAduioDevice.isConnected()).thenReturn(false); + mEmptyDevices.clear(); + mProfileConnectedDevices.clear(); + mProfileConnectedDevices.add(mBluetoothDevice); + mProfileConnectedDevices.add(connectdBtLeAduioDevice); + mProfileConnectedDevices.add(disonnectdBtLeAduioDevice); + when(mLeAudioProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); + + mEmptyDevices.addAll(mController.getConnectedLeAudioDevices()); + + assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, connectdBtLeAduioDevice); + } + + @Test + public void findActiveLeAudioDevice_noActiveDevice_returnNull() { + mLeAudioActiveDevices.clear(); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveLeAudioDevice()).isNull(); + } + + @Test + public void findActiveLeAudioDevice_withActiveDevice_returnActiveDevice() { + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(mBluetoothDevice); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveLeAudioDevice()).isEqualTo(mBluetoothDevice); + } + private class AudioSwitchPreferenceControllerTestable extends AudioSwitchPreferenceController { AudioSwitchPreferenceControllerTestable(Context context, String key) { diff --git a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java index 2580bfd8786..7543b5f83a5 100644 --- a/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/HandsFreeProfileOutputPreferenceControllerTest.java @@ -16,6 +16,7 @@ package com.android.settings.sound; +import static android.media.AudioSystem.DEVICE_OUT_BLE_HEADSET; import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID; @@ -46,19 +47,18 @@ import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowBluetoothDevice; @@ -66,7 +66,6 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class, @@ -78,10 +77,12 @@ public class HandsFreeProfileOutputPreferenceControllerTest { private static final String TEST_DEVICE_NAME_2 = "Test_HFP_BT_Device_NAME_2"; private static final String TEST_HAP_DEVICE_NAME_1 = "Test_HAP_BT_Device_NAME_1"; private static final String TEST_HAP_DEVICE_NAME_2 = "Test_HAP_BT_Device_NAME_2"; + private static final String TEST_LE_AUDIO_DEVICE_NAME_1 = "Test_LE_AUDIO_Device_NAME_1"; private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1"; private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2"; private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3"; private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4"; + private static final String TEST_DEVICE_ADDRESS_5 = "00:E5:E5:E5:E5:E5"; private final static long HISYNCID1 = 10; private final static long HISYNCID2 = 11; @@ -96,6 +97,8 @@ public class HandsFreeProfileOutputPreferenceControllerTest { @Mock private HearingAidProfile mHearingAidProfile; @Mock + private LeAudioProfile mLeAudioProfile; + @Mock private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback; private Context mContext; @@ -113,6 +116,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest { private HandsFreeProfileOutputPreferenceController mController; private List mProfileConnectedDevices; private List mHearingAidActiveDevices; + private List mLeAudioActiveDevices; @Before public void setUp() { @@ -129,24 +133,29 @@ public class HandsFreeProfileOutputPreferenceControllerTest { when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); when(mLocalBluetoothProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile); when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mLocalBluetoothProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); mBluetoothManager = mContext.getSystemService(BluetoothManager.class); mBluetoothAdapter = mBluetoothManager.getAdapter(); mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1)); when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1); + when(mBluetoothDevice.getAlias()).thenReturn(TEST_DEVICE_NAME_1); when(mBluetoothDevice.isConnected()).thenReturn(true); mSecondBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2)); when(mSecondBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_2); + when(mSecondBluetoothDevice.getAlias()).thenReturn(TEST_DEVICE_NAME_2); when(mSecondBluetoothDevice.isConnected()).thenReturn(true); mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3)); when(mLeftBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_1); + when(mLeftBluetoothHapDevice.getAlias()).thenReturn(TEST_HAP_DEVICE_NAME_1); when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true); mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_4)); when(mRightBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_2); + when(mRightBluetoothHapDevice.getAlias()).thenReturn(TEST_HAP_DEVICE_NAME_2); when(mRightBluetoothHapDevice.isConnected()).thenReturn(true); mController = new HandsFreeProfileOutputPreferenceController(mContext, TEST_KEY); @@ -154,6 +163,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest { mPreference = new ListPreference(mContext); mProfileConnectedDevices = new ArrayList<>(); mHearingAidActiveDevices = new ArrayList<>(2); + mLeAudioActiveDevices = new ArrayList<>(); when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); when(mScreen.getContext()).thenReturn(mContext); @@ -245,7 +255,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * Preference summary should be the activated device name */ @Test - @Ignore public void updateState_oneHeadsetsAvailableAndActivated_shouldSetDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO); @@ -267,7 +276,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * Preference summary should be the activated device name */ @Test - @Ignore public void updateState_moreThanOneHfpBtDevicesAreAvailable_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO); @@ -328,7 +336,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * Preference summary should be the activated device name */ @Test - @Ignore public void updateState_oneHapBtDeviceAreAvailable_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); @@ -353,7 +360,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * Preference summary should be the activated device name */ @Test - @Ignore public void updateState_moreThanOneHapBtDevicesAreAvailable_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); @@ -382,7 +388,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * ConnectedDevice should not contain second HAP device with same HisyncId */ @Test - @Ignore public void updateState_hapBtDeviceWithSameId_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); @@ -416,7 +421,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * ConnectedDevice should not contain second HAP device with same HisyncId */ @Test - @Ignore public void updateState_hapBtDeviceWithSameIdButDifferentOrder_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); @@ -449,7 +453,6 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * ConnectedDevice should contain both HAP device with different HisyncId */ @Test - @Ignore public void updateState_hapBtDeviceWithDifferentId_shouldSetActivatedDeviceName() { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); @@ -473,6 +476,25 @@ public class HandsFreeProfileOutputPreferenceControllerTest { mLeftBluetoothHapDevice, mRightBluetoothHapDevice); } + @Test + public void updateState_leAudioDeviceActive_shouldSetActivatedDeviceName() { + mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLE_HEADSET); + when(mBluetoothDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + when(mBluetoothDevice.getAlias()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mProfileConnectedDevices.clear(); + mProfileConnectedDevices.add(mBluetoothDevice); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(mBluetoothDevice); + when(mLeAudioProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + mController.updateState(mPreference); + + assertThat(mPreference.isVisible()).isTrue(); + assertThat(mPreference.getSummary()).isEqualTo(mBluetoothDevice.getName()); + } + @Test public void findActiveDevice_onlyHeadsetDeviceActive_returnHeadsetDevice() { when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(null); @@ -489,12 +511,60 @@ public class HandsFreeProfileOutputPreferenceControllerTest { assertThat(mController.findActiveDevice()).isNull(); } + @Test + public void findActiveDevice_allProfilesWithActiveDevice_returnHADevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mController.mConnectedDevices.clear(); + mController.mConnectedDevices.add(mBluetoothDevice); + mController.mConnectedDevices.add(mLeftBluetoothHapDevice); + mController.mConnectedDevices.add(btLeDevice); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1); + when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(mLeftBluetoothHapDevice); + } + + @Test + public void findActiveDevice_headsetDeviceAndLeAudioDeviceActive_returnLeAudioDevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(btLeDevice); + } + + @Test + public void findActiveDevice_onlyLeAudioDeviceActive_returnLeAudioDevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mHeadsetProfile.getActiveDevice()).thenReturn(null); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(btLeDevice); + } + + /** * One Bluetooth devices are available, and select the device. * Preference summary should be device name. */ @Test - @Ignore public void onPreferenceChange_toBtDevice_shouldSetBtDeviceName() { mController.mConnectedDevices.clear(); mController.mConnectedDevices.add(mBluetoothDevice); @@ -509,16 +579,10 @@ public class HandsFreeProfileOutputPreferenceControllerTest { * Preference summary should be second device name. */ @Test - @Ignore public void onPreferenceChange_toBtDevices_shouldSetSecondBtDeviceName() { - ShadowBluetoothDevice shadowBluetoothDevice; - BluetoothDevice secondBluetoothDevice; - secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2); - shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice); - shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2); mController.mConnectedDevices.clear(); mController.mConnectedDevices.add(mBluetoothDevice); - mController.mConnectedDevices.add(secondBluetoothDevice); + mController.mConnectedDevices.add(mSecondBluetoothDevice); mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2); diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java index 10471cb405b..036d58c2cd5 100644 --- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java @@ -16,6 +16,7 @@ package com.android.settings.sound; +import static android.media.AudioSystem.DEVICE_OUT_BLE_HEADSET; import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; import static android.media.AudioSystem.DEVICE_OUT_EARPIECE; import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID; @@ -56,13 +57,13 @@ import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.MediaOutputConstants; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -79,7 +80,6 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -@Ignore @Config(shadows = { ShadowAudioManager.class, ShadowBluetoothUtils.class, @@ -91,10 +91,12 @@ public class MediaOutputPreferenceControllerTest { private static final String TEST_DEVICE_NAME_2 = "Test_A2DP_BT_Device_NAME_2"; private static final String TEST_HAP_DEVICE_NAME_1 = "Test_HAP_BT_Device_NAME_1"; private static final String TEST_HAP_DEVICE_NAME_2 = "Test_HAP_BT_Device_NAME_2"; + private static final String TEST_LE_AUDIO_DEVICE_NAME_1 = "Test_LE_AUDIO_Device_NAME_1"; private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1"; private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2"; private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3"; private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4"; + private static final String TEST_DEVICE_ADDRESS_5 = "00:E5:E5:E5:E5:E5"; private static final String TEST_PACKAGE_NAME = "com.test.packagename"; private static final String TEST_APPLICATION_LABEL = "APP Test Label"; @@ -109,6 +111,8 @@ public class MediaOutputPreferenceControllerTest { @Mock private HearingAidProfile mHearingAidProfile; @Mock + private LeAudioProfile mLeAudioProfile; + @Mock private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback; @Mock private MediaSessionManager mMediaSessionManager; @@ -130,6 +134,7 @@ public class MediaOutputPreferenceControllerTest { private MediaOutputPreferenceController mController; private List mProfileConnectedDevices; private List mHearingAidActiveDevices; + private List mLeAudioActiveDevices; private List mMediaControllers = new ArrayList<>(); private MediaController.PlaybackInfo mPlaybackInfo; private PlaybackState mPlaybackState; @@ -170,12 +175,14 @@ public class MediaOutputPreferenceControllerTest { when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mLocalBluetoothProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); mBluetoothManager = mContext.getSystemService(BluetoothManager.class); mBluetoothAdapter = mBluetoothManager.getAdapter(); mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1)); when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1); + when(mBluetoothDevice.getAlias()).thenReturn(TEST_DEVICE_NAME_1); when(mBluetoothDevice.isConnected()).thenReturn(true); mSecondBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2)); @@ -184,6 +191,7 @@ public class MediaOutputPreferenceControllerTest { mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3)); when(mLeftBluetoothHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME_1); + when(mLeftBluetoothHapDevice.getAlias()).thenReturn(TEST_HAP_DEVICE_NAME_1); when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true); mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_4)); @@ -195,6 +203,7 @@ public class MediaOutputPreferenceControllerTest { mPreference = new Preference(mContext); mProfileConnectedDevices = new ArrayList<>(); mHearingAidActiveDevices = new ArrayList<>(2); + mLeAudioActiveDevices = new ArrayList<>(); when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); when(mScreen.getContext()).thenReturn(mContext); @@ -234,7 +243,6 @@ public class MediaOutputPreferenceControllerTest { * Preference summary should be device's name */ @Test - @Ignore public void updateState_withActiveBtDevice_setActivatedDeviceName() { mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP); mAudioManager.setMode(AudioManager.MODE_NORMAL); @@ -254,7 +262,6 @@ public class MediaOutputPreferenceControllerTest { * Preference summary should be device's name */ @Test - @Ignore public void updateState_withActiveHADevice_setActivatedDeviceName() { mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); mAudioManager.setMode(AudioManager.MODE_NORMAL); @@ -269,6 +276,24 @@ public class MediaOutputPreferenceControllerTest { } + @Test + public void updateState_withActiveLeAudioDevice_setActivatedDeviceName() { + mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLE_HEADSET); + mAudioManager.setMode(AudioManager.MODE_NORMAL); + when(mBluetoothDevice.getAlias()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mProfileConnectedDevices.clear(); + mProfileConnectedDevices.add(mBluetoothDevice); + mProfileConnectedDevices.add(mSecondBluetoothDevice); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(mBluetoothDevice); + when(mLeAudioProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mPreference.getSummary()).isNull(); + mController.updateState(mPreference); + assertThat(mPreference.getSummary()).isEqualTo(TEST_LE_AUDIO_DEVICE_NAME_1); + } + @Test public void updateState_noActiveLocalPlayback_noTitle() { mPlaybackState = new PlaybackState.Builder() @@ -350,6 +375,49 @@ public class MediaOutputPreferenceControllerTest { assertThat(mController.findActiveDevice()).isNull(); } + @Test + public void findActiveDevice_allProfilesWithActiveDevice_returnHADevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(mLeftBluetoothHapDevice); + } + + @Test + public void findActiveDevice_a2dpDeviceAndLeAudioDeviceActive_returnLeAudioDevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(btLeDevice); + } + + @Test + public void findActiveDevice_onlyLeAudioDeviceActive_returnLeAudioDevice() { + BluetoothDevice btLeDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_5)); + when(btLeDevice.getName()).thenReturn(TEST_LE_AUDIO_DEVICE_NAME_1); + mLeAudioActiveDevices.clear(); + mLeAudioActiveDevices.add(btLeDevice); + mHearingAidActiveDevices.clear(); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); + when(mA2dpProfile.getActiveDevice()).thenReturn(null); + when(mLeAudioProfile.getActiveDevices()).thenReturn(mLeAudioActiveDevices); + + assertThat(mController.findActiveDevice()).isEqualTo(btLeDevice); + } + private void initPackage() { mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); mAppInfo = new ApplicationInfo();