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

Commit b567ba06 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audiopolicy: Refactor AudioPolicyManager::updateCallRouting

The code of the function had almost identical paths for
Rx and Tx patches creation. Factored them out, now it's much
easier to see what is common, and what differs.

Test: audio in still present incoming and outgoing telephony calls
Change-Id: Ia02179513d76809e33c65b2dad465358acdbfc63
parent 1b2a794a
Loading
Loading
Loading
Loading
+58 −83
Original line number Original line Diff line number Diff line
@@ -386,9 +386,6 @@ status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
{
{
    bool createTxPatch = false;
    bool createTxPatch = false;
    status_t status;
    audio_patch_handle_t afPatchHandle;
    DeviceVector deviceList;
    uint32_t muteWaitMs = 0;
    uint32_t muteWaitMs = 0;


    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
@@ -420,80 +417,48 @@ uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_
            createTxPatch = true;
            createTxPatch = true;
        }
        }
    } else { // create RX path audio patch
    } else { // create RX path audio patch
        struct audio_patch patch;
        mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevice, delayMs);

        patch.num_sources = 1;
        patch.num_sinks = 1;
        deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
        ALOG_ASSERT(!deviceList.isEmpty(),
                    "updateCallRouting() selected device not in output device list");
        sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
        deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
        ALOG_ASSERT(!deviceList.isEmpty(),
                    "updateCallRouting() no telephony RX device");
        sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);

        rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
        rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);

        // request to reuse existing output stream if one is already opened to reach the RX device
        SortedVector<audio_io_handle_t> outputs =
                                getOutputsForDevice(rxDevice, mOutputs);
        audio_io_handle_t output = selectOutput(outputs,
                                                AUDIO_OUTPUT_FLAG_NONE,
                                                AUDIO_FORMAT_INVALID);
        if (output != AUDIO_IO_HANDLE_NONE) {
            sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
            ALOG_ASSERT(!outputDesc->isDuplicated(),
                        "updateCallRouting() RX device output is duplicated");
            outputDesc->toAudioPortConfig(&patch.sources[1]);
            patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
            patch.num_sources = 2;
        }

        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
        ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
                                               status);
        if (status == NO_ERROR) {
            mCallRxPatch = new AudioPatch(&patch, mUidCached);
            mCallRxPatch->mAfPatchHandle = afPatchHandle;
            mCallRxPatch->mUid = mUidCached;
        }
        createTxPatch = true;
        createTxPatch = true;
    }
    }
    if (createTxPatch) { // create TX path audio patch
    if (createTxPatch) { // create TX path audio patch
        struct audio_patch patch;
        mCallTxPatch = createTelephonyPatch(false /*isRx*/, txDevice, delayMs);
    }

    return muteWaitMs;
}


sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
        bool isRx, audio_devices_t device, uint32_t delayMs) {
    struct audio_patch patch;
    patch.num_sources = 1;
    patch.num_sources = 1;
    patch.num_sinks = 1;
    patch.num_sinks = 1;
        deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
        ALOG_ASSERT(!deviceList.isEmpty(),
                    "updateCallRouting() selected device not in input device list");
        sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
        txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
        deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
        ALOG_ASSERT(!deviceList.isEmpty(),
                    "updateCallRouting() no telephony TX device");
        sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
        txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);


        SortedVector<audio_io_handle_t> outputs =
    sp<DeviceDescriptor> txSourceDeviceDesc;
                                getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
    if (isRx) {
        audio_io_handle_t output = selectOutput(outputs,
        fillAudioPortConfigForDevice(mAvailableOutputDevices, device, &patch.sinks[0]);
                                                AUDIO_OUTPUT_FLAG_NONE,
        fillAudioPortConfigForDevice(
                                                AUDIO_FORMAT_INVALID);
                mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX, &patch.sources[0]);
        // request to reuse existing output stream if one is already opened to reach the TX
    } else {
        // path output device
        txSourceDeviceDesc = fillAudioPortConfigForDevice(
                mAvailableInputDevices, device, &patch.sources[0]);
        fillAudioPortConfigForDevice(
                mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX, &patch.sinks[0]);
    }

    audio_devices_t outputDevice = isRx ? device : AUDIO_DEVICE_OUT_TELEPHONY_TX;
    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(outputDevice, mOutputs);
    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
    // request to reuse existing output stream if one is already opened to reach the target device
    if (output != AUDIO_IO_HANDLE_NONE) {
    if (output != AUDIO_IO_HANDLE_NONE) {
        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
        ALOG_ASSERT(!outputDesc->isDuplicated(),
        ALOG_ASSERT(!outputDesc->isDuplicated(),
                        "updateCallRouting() RX device output is duplicated");
                "%s() %#x device output %d is duplicated", __func__, outputDevice, output);
        outputDesc->toAudioPortConfig(&patch.sources[1]);
        outputDesc->toAudioPortConfig(&patch.sources[1]);
        patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
        patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
        patch.num_sources = 2;
        patch.num_sources = 2;
    }
    }


    if (!isRx) {
        // terminate active capture if on the same HW module as the call TX source device
        // terminate active capture if on the same HW module as the call TX source device
        // FIXME: would be better to refine to only inputs whose profile connects to the
        // FIXME: would be better to refine to only inputs whose profile connects to the
        // call TX device but this information is not in the audio patch and logic here must be
        // call TX device but this information is not in the audio patch and logic here must be
@@ -509,19 +474,29 @@ uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_
                }
                }
            }
            }
        }
        }
    }


        afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
    status_t status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
        ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
    ALOGW_IF(status != NO_ERROR,
                                               status);
            "%s() error %d creating %s audio patch", __func__, status, isRx ? "RX" : "TX");
    sp<AudioPatch> audioPatch;
    if (status == NO_ERROR) {
    if (status == NO_ERROR) {
            mCallTxPatch = new AudioPatch(&patch, mUidCached);
        audioPatch = new AudioPatch(&patch, mUidCached);
            mCallTxPatch->mAfPatchHandle = afPatchHandle;
        audioPatch->mAfPatchHandle = afPatchHandle;
            mCallTxPatch->mUid = mUidCached;
        audioPatch->mUid = mUidCached;
    }
    }
    return audioPatch;
}
}


    return muteWaitMs;
sp<DeviceDescriptor> AudioPolicyManager::fillAudioPortConfigForDevice(
        const DeviceVector& devices, audio_devices_t device, audio_port_config *config) {
    DeviceVector deviceList = devices.getDevicesFromType(device);
    ALOG_ASSERT(!deviceList.isEmpty(),
            "%s() selected device type %#x is not in devices list", __func__, device);
    sp<DeviceDescriptor> deviceDesc = deviceList.itemAt(0);
    deviceDesc->toAudioPortConfig(config);
    return deviceDesc;
}
}


void AudioPolicyManager::setPhoneState(audio_mode_t state)
void AudioPolicyManager::setPhoneState(audio_mode_t state)
+3 −0
Original line number Original line Diff line number Diff line
@@ -470,6 +470,9 @@ protected:
        }
        }


        uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
        uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
        sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
        sp<DeviceDescriptor> fillAudioPortConfigForDevice(
                const DeviceVector& devices, audio_devices_t device, audio_port_config *config);


        // if argument "device" is different from AUDIO_DEVICE_NONE,  startSource() will force
        // if argument "device" is different from AUDIO_DEVICE_NONE,  startSource() will force
        // the re-evaluation of the output device.
        // the re-evaluation of the output device.