Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ced7367a authored by Wenyu Zhang's avatar Wenyu Zhang
Browse files

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
parent 3f72bb5d
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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
+48 −9
Original line number Diff line number Diff line
@@ -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<AudioDeviceAttributes> audioDeviceAttributesList =
                new ArrayList<AudioDeviceAttributes>();
@@ -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());
        }
    }