From ced7367a35f7451881455e78c13be53ec6ff732e Mon Sep 17 00:00:00 2001 From: Wenyu Zhang Date: Tue, 5 Nov 2024 15:38:19 +0000 Subject: Activate hot plugged device Activate hot plugged audio input device, to match the output device behavior. This is a reland of http://ag/29970464 with slight modification that the applyDefaultSelectedTypeToAllPresets is being called at the beginning of onAudioDevicesAdded to make sure the device list is fully available when mAudioManager.getDevices API is called. Change-Id: I92196d6bb66424cd86e2dd705ad06a0f97d061bd Bug: b/355684672, b/374174565 Test: InputRouteManagerTest Flag: com.android.media.flags.enable_audio_input_device_routing_and_volume_control --- .../settingslib/media/InputRouteManager.java | 18 +++++++ .../settingslib/media/InputRouteManagerTest.java | 57 ++++++++++++++++++---- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java index 4f315a2a2486..76aa5bf3334c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java @@ -75,6 +75,24 @@ public final class InputRouteManager { @Override public void onAudioDevicesAdded(@NonNull AudioDeviceInfo[] addedDevices) { applyDefaultSelectedTypeToAllPresets(); + + // Activate the last hot plugged valid input device, to match the output device + // behavior. + @AudioDeviceType int deviceTypeToActivate = mSelectedInputDeviceType; + for (AudioDeviceInfo info : addedDevices) { + if (InputMediaDevice.isSupportedInputDevice(info.getType())) { + deviceTypeToActivate = info.getType(); + } + } + + // Only activate if we find a different valid input device. e.g. if none of the + // addedDevices is supported input device, we don't need to activate anything. + if (mSelectedInputDeviceType != deviceTypeToActivate) { + mSelectedInputDeviceType = deviceTypeToActivate; + AudioDeviceAttributes deviceAttributes = + createInputDeviceAttributes(mSelectedInputDeviceType); + setPreferredDeviceForAllPresets(deviceAttributes); + } } @Override 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 782cee23fb42..d808a25ebc04 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 @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -138,6 +139,18 @@ public class InputRouteManagerTest { /* address= */ ""); } + private AudioDeviceAttributes getUsbHeadsetDeviceAttributes() { + return new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_INPUT, + AudioDeviceInfo.TYPE_USB_HEADSET, + /* address= */ ""); + } + + private AudioDeviceAttributes getHdmiDeviceAttributes() { + return new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_INPUT, AudioDeviceInfo.TYPE_HDMI, /* address= */ ""); + } + private void onPreferredDevicesForCapturePresetChanged(InputRouteManager inputRouteManager) { final List audioDeviceAttributesList = new ArrayList(); @@ -303,21 +316,47 @@ public class InputRouteManagerTest { } @Test - public void onAudioDevicesAdded_shouldApplyDefaultSelectedDeviceToAllPresets() { + public void onAudioDevicesAdded_shouldActivateAddedDevice() { final AudioManager audioManager = mock(AudioManager.class); - AudioDeviceAttributes wiredHeadsetDeviceAttributes = getWiredHeadsetDeviceAttributes(); - when(audioManager.getDevicesForAttributes(INPUT_ATTRIBUTES)) - .thenReturn(Collections.singletonList(wiredHeadsetDeviceAttributes)); - InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager); AudioDeviceInfo[] devices = {mockWiredHeadsetInfo()}; inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices); - // Called twice, one after initiation, the other after onAudioDevicesAdded call. - verify(audioManager, atLeast(2)).getDevicesForAttributes(INPUT_ATTRIBUTES); + // The only added wired headset will be activated. for (@MediaRecorder.Source int preset : PRESETS) { - verify(audioManager, atLeast(2)) - .setPreferredDeviceForCapturePreset(preset, wiredHeadsetDeviceAttributes); + verify(audioManager, atLeast(1)) + .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes()); + } + } + + @Test + public void onAudioDevicesAdded_shouldActivateLastAddedDevice() { + final AudioManager audioManager = mock(AudioManager.class); + InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager); + AudioDeviceInfo[] devices = {mockWiredHeadsetInfo(), mockUsbHeadsetInfo()}; + inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices); + + // When adding multiple valid input devices, the last added device (usb headset in this + // case) will be activated. + for (@MediaRecorder.Source int preset : PRESETS) { + verify(audioManager, never()) + .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes()); + verify(audioManager, atLeast(1)) + .setPreferredDeviceForCapturePreset(preset, getUsbHeadsetDeviceAttributes()); + } + } + + @Test + public void onAudioDevicesAdded_doNotActivateInvalidAddedDevice() { + final AudioManager audioManager = mock(AudioManager.class); + InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager); + AudioDeviceInfo[] devices = {mockHdmiInfo()}; + inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices); + + // Do not activate since HDMI is not a valid input device. + for (@MediaRecorder.Source int preset : PRESETS) { + verify(audioManager, never()) + .setPreferredDeviceForCapturePreset(preset, getHdmiDeviceAttributes()); } } -- cgit v1.2.3-59-g8ed1b