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

Commit 929e854e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support device role for capture preset." into udc-dev

parents 4c7e265a 14662b57
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -479,6 +479,37 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
    return devices;
}

DeviceVector Engine::getPreferredAvailableDevicesForInputSource(
            const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
    DeviceVector preferredAvailableDevVec = {};
    AudioDeviceTypeAddrVector preferredDevices;
    const status_t status = getDevicesForRoleAndCapturePreset(
            inputSource, DEVICE_ROLE_PREFERRED, preferredDevices);
    if (status == NO_ERROR) {
        // Only use preferred devices when they are all available.
        preferredAvailableDevVec =
                availableInputDevices.getDevicesFromDeviceTypeAddrVec(preferredDevices);
        if (preferredAvailableDevVec.size() == preferredDevices.size()) {
            ALOGVV("%s using pref device %s for source %u",
                   __func__, preferredAvailableDevVec.toString().c_str(), inputSource);
            return preferredAvailableDevVec;
        }
    }
    return preferredAvailableDevVec;
}

DeviceVector Engine::getDisabledDevicesForInputSource(
            const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
    DeviceVector disabledDevices = {};
    AudioDeviceTypeAddrVector disabledDevicesTypeAddr;
    const status_t status = getDevicesForRoleAndCapturePreset(
            inputSource, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr);
    if (status == NO_ERROR) {
        disabledDevices =
                availableInputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr);
    }
    return disabledDevices;
}

sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const
{
@@ -510,6 +541,20 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource)
        }
    }

    // Use the preferred device for the input source if it is available.
    DeviceVector preferredInputDevices = getPreferredAvailableDevicesForInputSource(
            availableDevices, inputSource);
    if (!preferredInputDevices.isEmpty()) {
        // Currently, only support single device for input. The public JAVA API also only
        // support setting single device as preferred device. In that case, returning the
        // first device is OK here.
        return preferredInputDevices[0];
    }
    // Remove the disabled device for the input source from the available input device list.
    DeviceVector disabledInputDevices = getDisabledDevicesForInputSource(
            availableDevices, inputSource);
    availableDevices.remove(disabledInputDevices);

    audio_devices_t commDeviceType =
        getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE);

+4 −0
Original line number Diff line number Diff line
@@ -99,6 +99,10 @@ private:
        const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
    DeviceVector getDisabledDevicesForProductStrategy(
        const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
    DeviceVector getPreferredAvailableDevicesForInputSource(
            const DeviceVector& availableInputDevices, audio_source_t inputSource) const;
    DeviceVector getDisabledDevicesForInputSource(
            const DeviceVector& availableInputDevices, audio_source_t inputSource) const;

    DeviceStrategyMap mDevicesForStrategies;

+102 −0
Original line number Diff line number Diff line
@@ -2833,6 +2833,108 @@ TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCaptureP
              mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
}

TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) {
    const audio_source_t source = AUDIO_SOURCE_MIC;
    const device_role_t role = DEVICE_ROLE_PREFERRED;
    const std::string address = "card=1;device=0";
    const std::string deviceName = "randomName";

    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
            AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
            address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
    auto availableDevices = mManager->getAvailableInputDevices();
    ASSERT_GT(availableDevices.size(), 1);

    audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
    attr.source = source;
    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
    ASSERT_NE(nullptr, selectedDevice);

    sp<DeviceDescriptor> preferredDevice = nullptr;
    for (const auto& device : availableDevices) {
        if (device != selectedDevice) {
            preferredDevice = device;
            break;
        }
    }
    ASSERT_NE(nullptr, preferredDevice);
    // After setting preferred device for capture preset, the selected device for input should be
    // the preferred device.
    ASSERT_EQ(NO_ERROR,
              mManager->setDevicesRoleForCapturePreset(source, role,
                                                       {preferredDevice->getDeviceTypeAddr()}));
    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId));

    // After clearing preferred device for capture preset, the selected device for input should be
    // the same as original one.
    ASSERT_EQ(NO_ERROR,
              mManager->clearDevicesRoleForCapturePreset(source, role));
    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));

    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
            AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
            address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
}

TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) {
    const audio_source_t source = AUDIO_SOURCE_MIC;
    const device_role_t role = DEVICE_ROLE_DISABLED;
    const std::string address = "card=1;device=0";
    const std::string deviceName = "randomName";

    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
            AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
            address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
    auto availableDevices = mManager->getAvailableInputDevices();
    ASSERT_GT(availableDevices.size(), 1);

    audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
    attr.source = source;
    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
    ASSERT_NE(nullptr, selectedDevice);

    // After setting disabled device for capture preset, the disabled device must not be
    // selected for input.
    ASSERT_EQ(NO_ERROR,
              mManager->setDevicesRoleForCapturePreset(source, role,
                                                       {selectedDevice->getDeviceTypeAddr()}));
    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));

    // After clearing disabled device for capture preset, the selected device for input should be
    // the original one.
    ASSERT_EQ(NO_ERROR,
              mManager->clearDevicesRoleForCapturePreset(source, role));
    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
                                            AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
                                            48000));
    ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));

    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
            AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
            address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
}

INSTANTIATE_TEST_CASE_P(
        DevicesRoleForCapturePresetOperation,
        AudioPolicyManagerDevicesRoleForCapturePresetTest,
+3 −1
Original line number Diff line number Diff line
@@ -77,12 +77,14 @@
                </devicePort>
                <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
                </devicePort>
                <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="Speaker"
                       sources="primary output,voip_rx"/>
                <route type="mix" sink="primary input"
                       sources="Built-In Mic,Hdmi-In Mic"/>
                       sources="Built-In Mic,Hdmi-In Mic,USB Device In"/>
                <route type="mix" sink="voip_tx"
                       sources="Built-In Mic"/>
                <route type="mix" sink="Hdmi"