diff options
| author | 2024-10-01 19:49:21 +0000 | |
|---|---|---|
| committer | 2024-10-09 18:06:51 +0000 | |
| commit | 1e1c3f52d7940de5bed933ac4a21d245636f170c (patch) | |
| tree | 75ff60670ace40d31dc82d6b6ae191b1afa6cdc9 | |
| parent | dc9afc230b00767a9f75e05f2ab42e5e1c52f2de (diff) | |
audio: Display product name for input device
Bug: b/366358858
Test: atest InputMediaDeviceTest, InputRouteManagerTest, MediaSwitchingControllerTest
Flag: com.android.media.flags.enable_audio_input_device_routing_and_volume_control
Change-Id: I504a0eb39a1156c8079c7592ba73246a1ef4ee84
5 files changed, 152 insertions, 21 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InputMediaDevice.java index 1d17b004fb6a..6335e712f904 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InputMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InputMediaDevice.java @@ -49,19 +49,23 @@ public class InputMediaDevice extends MediaDevice { private final boolean mIsVolumeFixed; + private final String mProductName; + private InputMediaDevice( @NonNull Context context, @NonNull String id, @AudioDeviceType int audioDeviceInfoType, int maxVolume, int currentVolume, - boolean isVolumeFixed) { + boolean isVolumeFixed, + @Nullable String productName) { super(context, /* info= */ null, /* item= */ null); mId = id; mAudioDeviceInfoType = audioDeviceInfoType; mMaxVolume = maxVolume; mCurrentVolume = currentVolume; mIsVolumeFixed = isVolumeFixed; + mProductName = productName; initDeviceRecord(); } @@ -72,13 +76,20 @@ public class InputMediaDevice extends MediaDevice { @AudioDeviceType int audioDeviceInfoType, int maxVolume, int currentVolume, - boolean isVolumeFixed) { + boolean isVolumeFixed, + @Nullable String productName) { if (!isSupportedInputDevice(audioDeviceInfoType)) { return null; } return new InputMediaDevice( - context, id, audioDeviceInfoType, maxVolume, currentVolume, isVolumeFixed); + context, + id, + audioDeviceInfoType, + maxVolume, + currentVolume, + isVolumeFixed, + productName); } public @AudioDeviceType int getAudioDeviceInfoType() { @@ -98,18 +109,25 @@ public class InputMediaDevice extends MediaDevice { }; } + @Nullable + public String getProductName() { + return mProductName; + } + @Override public @NonNull String getName() { - CharSequence name = switch (mAudioDeviceInfoType) { - case TYPE_WIRED_HEADSET -> mContext.getString( - R.string.media_transfer_wired_device_mic_name); - case TYPE_USB_DEVICE, TYPE_USB_HEADSET, TYPE_USB_ACCESSORY -> mContext.getString( - R.string.media_transfer_usb_device_mic_name); - case TYPE_BLUETOOTH_SCO -> mContext.getString( - R.string.media_transfer_bt_device_mic_name); + return switch (mAudioDeviceInfoType) { + case TYPE_WIRED_HEADSET -> + mContext.getString(R.string.media_transfer_wired_device_mic_name); + case TYPE_USB_DEVICE, TYPE_USB_HEADSET, TYPE_USB_ACCESSORY -> + // The product name is assumed to be a well-formed string if it's not null. + mProductName != null + ? mProductName + : mContext.getString(R.string.media_transfer_usb_device_mic_name); + case TYPE_BLUETOOTH_SCO -> + mContext.getString(R.string.media_transfer_bt_device_mic_name); default -> mContext.getString(R.string.media_transfer_this_device_name_desktop); }; - return name.toString(); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java index 9164b64057fd..9ecc2cc6bf7c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java @@ -151,7 +151,8 @@ public final class InputRouteManager { info.getType(), getMaxInputGain(), getCurrentInputGain(), - isInputGainFixed()); + isInputGainFixed(), + getProductNameFromAudioDeviceInfo(info)); if (mediaDevice != null) { if (info.getType() == selectedInputDeviceAttributesType) { mediaDevice.setState(STATE_SELECTED); @@ -169,6 +170,25 @@ public final class InputRouteManager { } } + /** + * Gets the product name for the given {@link AudioDeviceInfo}. + * + * @return The product name for the given {@link AudioDeviceInfo}, or null if a suitable name + * cannot be found. + */ + @Nullable + private String getProductNameFromAudioDeviceInfo(AudioDeviceInfo deviceInfo) { + CharSequence productName = deviceInfo.getProductName(); + if (productName == null) { + return null; + } + String productNameString = productName.toString(); + if (productNameString.isBlank()) { + return null; + } + return productNameString; + } + public void selectDevice(@NonNull MediaDevice device) { if (!(device instanceof InputMediaDevice)) { Slog.w(TAG, "This device is not an InputMediaDevice: " + device.getName()); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputMediaDeviceTest.java index 30e4637f59ff..6c1cb7015225 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputMediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputMediaDeviceTest.java @@ -41,6 +41,9 @@ public class InputMediaDeviceTest { private final int MAX_VOLUME = 1; private final int CURRENT_VOLUME = 0; private final boolean IS_VOLUME_FIXED = true; + private static final String PRODUCT_NAME_BUILTIN_MIC = "Built-in Mic"; + private static final String PRODUCT_NAME_WIRED_HEADSET = "My Wired Headset"; + private static final String PRODUCT_NAME_USB_HEADSET = "My USB Headset"; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -60,7 +63,8 @@ public class InputMediaDeviceTest { AudioDeviceInfo.TYPE_BUILTIN_MIC, MAX_VOLUME, CURRENT_VOLUME, - IS_VOLUME_FIXED); + IS_VOLUME_FIXED, + PRODUCT_NAME_BUILTIN_MIC); assertThat(builtinMediaDevice).isNotNull(); assertThat(builtinMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_microphone); } @@ -74,7 +78,8 @@ public class InputMediaDeviceTest { AudioDeviceInfo.TYPE_BUILTIN_MIC, MAX_VOLUME, CURRENT_VOLUME, - IS_VOLUME_FIXED); + IS_VOLUME_FIXED, + PRODUCT_NAME_BUILTIN_MIC); assertThat(builtinMediaDevice).isNotNull(); assertThat(builtinMediaDevice.getName()) .isEqualTo(mContext.getString(R.string.media_transfer_this_device_name_desktop)); @@ -89,7 +94,8 @@ public class InputMediaDeviceTest { AudioDeviceInfo.TYPE_WIRED_HEADSET, MAX_VOLUME, CURRENT_VOLUME, - IS_VOLUME_FIXED); + IS_VOLUME_FIXED, + PRODUCT_NAME_WIRED_HEADSET); assertThat(wiredMediaDevice).isNotNull(); assertThat(wiredMediaDevice.getName()) .isEqualTo(mContext.getString(R.string.media_transfer_wired_device_mic_name)); @@ -104,7 +110,23 @@ public class InputMediaDeviceTest { AudioDeviceInfo.TYPE_USB_HEADSET, MAX_VOLUME, CURRENT_VOLUME, - IS_VOLUME_FIXED); + IS_VOLUME_FIXED, + PRODUCT_NAME_USB_HEADSET); + assertThat(usbMediaDevice).isNotNull(); + assertThat(usbMediaDevice.getName()).isEqualTo(PRODUCT_NAME_USB_HEADSET); + } + + @Test + public void getName_returnCorrectName_usbHeadset_nullProductName() { + InputMediaDevice usbMediaDevice = + InputMediaDevice.create( + mContext, + String.valueOf(USB_HEADSET_ID), + AudioDeviceInfo.TYPE_USB_HEADSET, + MAX_VOLUME, + CURRENT_VOLUME, + IS_VOLUME_FIXED, + null); assertThat(usbMediaDevice).isNotNull(); assertThat(usbMediaDevice.getName()) .isEqualTo(mContext.getString(R.string.media_transfer_usb_device_mic_name)); @@ -119,7 +141,8 @@ public class InputMediaDeviceTest { AudioDeviceInfo.TYPE_BLUETOOTH_SCO, MAX_VOLUME, CURRENT_VOLUME, - IS_VOLUME_FIXED); + IS_VOLUME_FIXED, + null); assertThat(btMediaDevice).isNotNull(); assertThat(btMediaDevice.getName()) .isEqualTo(mContext.getString(R.string.media_transfer_bt_device_mic_name)); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java index 16c0c1c71d79..f55df661f335 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java @@ -58,6 +58,11 @@ public class InputRouteManagerTest { private static final int MAX_VOLUME = 1; private static final int CURRENT_VOLUME = 0; private static final boolean VOLUME_FIXED_TRUE = true; + private static final String PRODUCT_NAME_BUILTIN_MIC = "Built-in Mic"; + private static final String PRODUCT_NAME_WIRED_HEADSET = "My Wired Headset"; + private static final String PRODUCT_NAME_USB_HEADSET = "My USB Headset"; + private static final String PRODUCT_NAME_USB_DEVICE = "My USB Device"; + private static final String PRODUCT_NAME_USB_ACCESSORY = "My USB Accessory"; private final Context mContext = spy(RuntimeEnvironment.application); private InputRouteManager mInputRouteManager; @@ -75,25 +80,31 @@ public class InputRouteManagerTest { final AudioDeviceInfo info1 = mock(AudioDeviceInfo.class); when(info1.getType()).thenReturn(AudioDeviceInfo.TYPE_BUILTIN_MIC); when(info1.getId()).thenReturn(BUILTIN_MIC_ID); + when(info1.getProductName()).thenReturn(PRODUCT_NAME_BUILTIN_MIC); final AudioDeviceInfo info2 = mock(AudioDeviceInfo.class); when(info2.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); when(info2.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(info2.getProductName()).thenReturn(PRODUCT_NAME_WIRED_HEADSET); final AudioDeviceInfo info3 = mock(AudioDeviceInfo.class); when(info3.getType()).thenReturn(AudioDeviceInfo.TYPE_USB_DEVICE); when(info3.getId()).thenReturn(INPUT_USB_DEVICE_ID); + when(info3.getProductName()).thenReturn(PRODUCT_NAME_USB_DEVICE); final AudioDeviceInfo info4 = mock(AudioDeviceInfo.class); when(info4.getType()).thenReturn(AudioDeviceInfo.TYPE_USB_HEADSET); when(info4.getId()).thenReturn(INPUT_USB_HEADSET_ID); + when(info4.getProductName()).thenReturn(PRODUCT_NAME_USB_HEADSET); final AudioDeviceInfo info5 = mock(AudioDeviceInfo.class); when(info5.getType()).thenReturn(AudioDeviceInfo.TYPE_USB_ACCESSORY); when(info5.getId()).thenReturn(INPUT_USB_ACCESSORY_ID); + when(info5.getProductName()).thenReturn(PRODUCT_NAME_USB_ACCESSORY); final AudioDeviceInfo unsupportedInfo = mock(AudioDeviceInfo.class); when(unsupportedInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_HDMI); + when(unsupportedInfo.getProductName()).thenReturn("HDMI device"); final AudioManager audioManager = mock(AudioManager.class); AudioDeviceInfo[] devices = {info1, info2, info3, info4, info5, unsupportedInfo}; @@ -142,10 +153,12 @@ public class InputRouteManagerTest { final AudioDeviceInfo info1 = mock(AudioDeviceInfo.class); when(info1.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); when(info1.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(info1.getProductName()).thenReturn(PRODUCT_NAME_WIRED_HEADSET); final AudioDeviceInfo info2 = mock(AudioDeviceInfo.class); when(info2.getType()).thenReturn(AudioDeviceInfo.TYPE_BUILTIN_MIC); when(info2.getId()).thenReturn(BUILTIN_MIC_ID); + when(info2.getProductName()).thenReturn(PRODUCT_NAME_BUILTIN_MIC); final AudioManager audioManager = mock(AudioManager.class); AudioDeviceInfo[] devices = {info1, info2}; @@ -171,10 +184,12 @@ public class InputRouteManagerTest { final AudioDeviceInfo info1 = mock(AudioDeviceInfo.class); when(info1.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); when(info1.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(info1.getProductName()).thenReturn(PRODUCT_NAME_WIRED_HEADSET); final AudioDeviceInfo info2 = mock(AudioDeviceInfo.class); when(info2.getType()).thenReturn(AudioDeviceInfo.TYPE_BUILTIN_MIC); when(info2.getId()).thenReturn(BUILTIN_MIC_ID); + when(info2.getProductName()).thenReturn(PRODUCT_NAME_BUILTIN_MIC); final AudioManager audioManager = mock(AudioManager.class); AudioDeviceInfo[] devices = {info1, info2}; @@ -204,10 +219,12 @@ public class InputRouteManagerTest { final AudioDeviceInfo info1 = mock(AudioDeviceInfo.class); when(info1.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); when(info1.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(info1.getProductName()).thenReturn(PRODUCT_NAME_WIRED_HEADSET); final AudioDeviceInfo info2 = mock(AudioDeviceInfo.class); when(info2.getType()).thenReturn(AudioDeviceInfo.TYPE_BUILTIN_MIC); when(info2.getId()).thenReturn(BUILTIN_MIC_ID); + when(info2.getProductName()).thenReturn(PRODUCT_NAME_BUILTIN_MIC); final AudioManager audioManager = mock(AudioManager.class); AudioDeviceInfo[] devices = {info1, info2}; @@ -239,7 +256,8 @@ public class InputRouteManagerTest { AudioDeviceInfo.TYPE_BUILTIN_MIC, MAX_VOLUME, CURRENT_VOLUME, - VOLUME_FIXED_TRUE); + VOLUME_FIXED_TRUE, + PRODUCT_NAME_BUILTIN_MIC); inputRouteManager.selectDevice(inputMediaDevice); AudioDeviceAttributes deviceAttributes = @@ -267,4 +285,51 @@ public class InputRouteManagerTest { public void isInputGainFixed() { assertThat(mInputRouteManager.isInputGainFixed()).isTrue(); } + + @Test + public void onAudioDevicesAdded_shouldSetProductNameCorrectly() { + final AudioDeviceInfo info1 = mock(AudioDeviceInfo.class); + when(info1.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); + when(info1.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + String firstProductName = "My first headset"; + when(info1.getProductName()).thenReturn(firstProductName); + + final AudioDeviceInfo info2 = mock(AudioDeviceInfo.class); + when(info2.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); + when(info2.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + String secondProductName = "My second headset"; + when(info2.getProductName()).thenReturn(secondProductName); + + final AudioDeviceInfo infoWithNullProductName = mock(AudioDeviceInfo.class); + when(infoWithNullProductName.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); + when(infoWithNullProductName.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(infoWithNullProductName.getProductName()).thenReturn(null); + + final AudioDeviceInfo infoWithBlankProductName = mock(AudioDeviceInfo.class); + when(infoWithBlankProductName.getType()).thenReturn(AudioDeviceInfo.TYPE_WIRED_HEADSET); + when(infoWithBlankProductName.getId()).thenReturn(INPUT_WIRED_HEADSET_ID); + when(infoWithBlankProductName.getProductName()).thenReturn(""); + + final AudioManager audioManager = mock(AudioManager.class); + AudioDeviceInfo[] devices = { + info1, info2, infoWithNullProductName, infoWithBlankProductName + }; + when(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(devices); + + InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager); + + assertThat(inputRouteManager.mInputMediaDevices).isEmpty(); + + inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices); + + assertThat(getProductNameAtIndex(inputRouteManager, 1)).isEqualTo(firstProductName); + assertThat(getProductNameAtIndex(inputRouteManager, 2)).isEqualTo(secondProductName); + assertThat(getProductNameAtIndex(inputRouteManager, 3)).isNull(); + assertThat(getProductNameAtIndex(inputRouteManager, 4)).isNull(); + } + + private String getProductNameAtIndex(InputRouteManager inputRouteManager, int index) { + return ((InputMediaDevice) inputRouteManager.mInputMediaDevices.get(index)) + .getProductName(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java index 07e48b9da153..bf4ef509ac80 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java @@ -125,6 +125,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase { private static final boolean VOLUME_FIXED_TRUE = true; private static final int LATCH_COUNT_DOWN_TIME_IN_SECOND = 5; private static final int LATCH_TIME_OUT_TIME_IN_SECOND = 10; + private static final String PRODUCT_NAME_BUILTIN_MIC = "Built-in Mic"; + private static final String PRODUCT_NAME_WIRED_HEADSET = "My Wired Headset"; @Mock private DialogTransitionAnimator mDialogTransitionAnimator; @@ -568,7 +570,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase { AudioDeviceInfo.TYPE_BUILTIN_MIC, MAX_VOLUME, CURRENT_VOLUME, - VOLUME_FIXED_TRUE); + VOLUME_FIXED_TRUE, + PRODUCT_NAME_BUILTIN_MIC); final MediaDevice mediaDevice4 = InputMediaDevice.create( mContext, @@ -576,7 +579,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase { AudioDeviceInfo.TYPE_WIRED_HEADSET, MAX_VOLUME, CURRENT_VOLUME, - VOLUME_FIXED_TRUE); + VOLUME_FIXED_TRUE, + PRODUCT_NAME_WIRED_HEADSET); final List<MediaDevice> inputDevices = new ArrayList<>(); inputDevices.add(mediaDevice3); inputDevices.add(mediaDevice4); @@ -1355,7 +1359,8 @@ public class MediaSwitchingControllerTest extends SysuiTestCase { AudioDeviceInfo.TYPE_BUILTIN_MIC, MAX_VOLUME, CURRENT_VOLUME, - VOLUME_FIXED_TRUE); + VOLUME_FIXED_TRUE, + PRODUCT_NAME_BUILTIN_MIC); mMediaSwitchingController.connectDevice(inputMediaDevice); CountDownLatch latch = new CountDownLatch(LATCH_COUNT_DOWN_TIME_IN_SECOND); |