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

Commit 601801db authored by Francois Gaffie's avatar Francois Gaffie Committed by Eric Laurent
Browse files

[BUG] AudioPolicyManager: prevent unecessary force routing on SwOutput



At the begining/end of call, routing for all SwOutput is evaluated.
In case of using bridge, either the output involved in the SwBridge or
the output involved in the HwBridge for volume will be forced to be rerouted
on same device as the routing has already been evaluated for the Swoutput
hosting the call..

This CL implements this optimization.

Bug: 187173302

Test: CSV & VoIP calls

Signed-off-by: default avatarFrancois Gaffie <francois.gaffie@renault.com>
Change-Id: I15102b661a4fc4afdd10888011feadf1fa7084ce
parent b2e5cb5a
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -225,6 +225,9 @@ public:
        mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        mSinkDevice = nullptr;
        mSinkDevice = nullptr;
    }
    }
    bool belongsToOutput(const sp<SwAudioOutputDescriptor> &swOutput) const {
        return swOutput != nullptr && mSwOutput.promote() == swOutput;
    }
    void setUseSwBridge() { mUseSwBridge = true; }
    void setUseSwBridge() { mUseSwBridge = true; }
    bool useSwBridge() const { return mUseSwBridge; }
    bool useSwBridge() const { return mUseSwBridge; }
    bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
    bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
+44 −20
Original line number Original line Diff line number Diff line
@@ -664,8 +664,8 @@ status_t AudioPolicyManager::updateCallRoutingInternal(
    ALOGV("%s device rxDevice %s txDevice %s", __func__,
    ALOGV("%s device rxDevice %s txDevice %s", __func__,
          rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());
          rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());


    disconnectTelephonyAudioSource(mCallRxSourceClientPort);
    disconnectTelephonyAudioSource(mCallRxSourceClient);
    disconnectTelephonyAudioSource(mCallTxSourceClientPort);
    disconnectTelephonyAudioSource(mCallTxSourceClient);


    auto telephonyRxModule =
    auto telephonyRxModule =
        mHwModules.getModuleForDeviceType(AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_FORMAT_DEFAULT);
        mHwModules.getModuleForDeviceType(AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_FORMAT_DEFAULT);
@@ -745,27 +745,32 @@ bool AudioPolicyManager::isDeviceOfModule(


void AudioPolicyManager::connectTelephonyRxAudioSource()
void AudioPolicyManager::connectTelephonyRxAudioSource()
{
{
    disconnectTelephonyAudioSource(mCallRxSourceClientPort);
    disconnectTelephonyAudioSource(mCallRxSourceClient);
    const struct audio_port_config source = {
    const struct audio_port_config source = {
        .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE,
        .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE,
        .ext.device.type = AUDIO_DEVICE_IN_TELEPHONY_RX, .ext.device.address = ""
        .ext.device.type = AUDIO_DEVICE_IN_TELEPHONY_RX, .ext.device.address = ""
    };
    };
    const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
    const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
    status_t status = startAudioSource(&source, &aa, &mCallRxSourceClientPort, 0/*uid*/);
    mCallRxSourceClient = startAudioSourceInternal(&source, &aa, 0/*uid*/);
    ALOGE_IF(status != NO_ERROR, "%s failed to start Telephony Rx AudioSource", __func__);
    ALOGE_IF(mCallRxSourceClient == nullptr,
             "%s failed to start Telephony Rx AudioSource", __func__);
}
}


void AudioPolicyManager::disconnectTelephonyAudioSource(audio_port_handle_t &portHandle)
void AudioPolicyManager::disconnectTelephonyAudioSource(sp<SourceClientDescriptor> &clientDesc)
{
{
    stopAudioSource(portHandle);
    if (clientDesc == nullptr) {
    portHandle = AUDIO_PORT_HANDLE_NONE;
        return;
    }
    ALOGW_IF(stopAudioSource(clientDesc->portId()) != NO_ERROR,
            "%s error stopping audio source", __func__);
    clientDesc.clear();
}
}


void AudioPolicyManager::connectTelephonyTxAudioSource(
void AudioPolicyManager::connectTelephonyTxAudioSource(
        const sp<DeviceDescriptor> &srcDevice, const sp<DeviceDescriptor> &sinkDevice,
        const sp<DeviceDescriptor> &srcDevice, const sp<DeviceDescriptor> &sinkDevice,
        uint32_t delayMs)
        uint32_t delayMs)
{
{
    disconnectTelephonyAudioSource(mCallTxSourceClientPort);
    disconnectTelephonyAudioSource(mCallTxSourceClient);
    if (srcDevice == nullptr || sinkDevice == nullptr) {
    if (srcDevice == nullptr || sinkDevice == nullptr) {
        ALOGW("%s could not create patch, invalid sink and/or source device(s)", __func__);
        ALOGW("%s could not create patch, invalid sink and/or source device(s)", __func__);
        return;
        return;
@@ -774,19 +779,20 @@ void AudioPolicyManager::connectTelephonyTxAudioSource(
    patchBuilder.addSource(srcDevice).addSink(sinkDevice);
    patchBuilder.addSource(srcDevice).addSink(sinkDevice);
    ALOGV("%s between source %s and sink %s", __func__,
    ALOGV("%s between source %s and sink %s", __func__,
            srcDevice->toString().c_str(), sinkDevice->toString().c_str());
            srcDevice->toString().c_str(), sinkDevice->toString().c_str());
    mCallTxSourceClientPort = PolicyAudioPort::getNextUniqueId();
    auto callTxSourceClientPortId = PolicyAudioPort::getNextUniqueId();
    const audio_attributes_t aa = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
    const audio_attributes_t aa = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
    struct audio_port_config source = {};
    struct audio_port_config source = {};
    srcDevice->toAudioPortConfig(&source);
    srcDevice->toAudioPortConfig(&source);
    sp<SourceClientDescriptor> sourceDesc = new InternalSourceClientDescriptor(
    mCallTxSourceClient = new InternalSourceClientDescriptor(
                mCallTxSourceClientPort, mUidCached, aa, source, srcDevice, sinkDevice,
                callTxSourceClientPortId, mUidCached, aa, source, srcDevice, sinkDevice,
                mCommunnicationStrategy, toVolumeSource(aa));
                mCommunnicationStrategy, toVolumeSource(aa));
    audio_patch_handle_t patchHandle = AUDIO_PATCH_HANDLE_NONE;
    audio_patch_handle_t patchHandle = AUDIO_PATCH_HANDLE_NONE;
    status_t status = connectAudioSourceToSink(
    status_t status = connectAudioSourceToSink(
                sourceDesc, sinkDevice, patchBuilder.patch(), patchHandle, mUidCached, delayMs);
                mCallTxSourceClient, sinkDevice, patchBuilder.patch(), patchHandle, mUidCached,
                delayMs);
    ALOGE_IF(status != NO_ERROR, "%s() error %d creating TX audio patch", __func__, status);
    ALOGE_IF(status != NO_ERROR, "%s() error %d creating TX audio patch", __func__, status);
    if (status == NO_ERROR) {
    if (status == NO_ERROR) {
        mAudioSources.add(mCallTxSourceClientPort, sourceDesc);
        mAudioSources.add(callTxSourceClientPortId, mCallTxSourceClient);
    }
    }
}
}


@@ -855,8 +861,8 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
                rxDevices = mPrimaryOutput->devices();
                rxDevices = mPrimaryOutput->devices();
            }
            }
            if (oldState == AUDIO_MODE_IN_CALL) {
            if (oldState == AUDIO_MODE_IN_CALL) {
                disconnectTelephonyAudioSource(mCallRxSourceClientPort);
                disconnectTelephonyAudioSource(mCallRxSourceClient);
                disconnectTelephonyAudioSource(mCallTxSourceClientPort);
                disconnectTelephonyAudioSource(mCallTxSourceClient);
            }
            }
            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
        }
        }
@@ -866,8 +872,10 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
    for (size_t i = 0; i < mOutputs.size(); i++) {
    for (size_t i = 0; i < mOutputs.size(); i++) {
        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
        DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
        DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
        if (state != AUDIO_MODE_IN_CALL || desc != mPrimaryOutput) {
        if (state != AUDIO_MODE_IN_CALL || (desc != mPrimaryOutput && !isTelephonyRxOrTx(desc))) {
            setOutputDevices(desc, newDevices, !newDevices.isEmpty(), 0 /*delayMs*/);
            bool forceRouting = !newDevices.isEmpty();
            setOutputDevices(desc, newDevices, forceRouting, 0 /*delayMs*/, nullptr,
                             true /*requiresMuteCheck*/, !forceRouting /*requiresVolumeCheck*/);
        }
        }
    }
    }


@@ -3523,11 +3531,15 @@ void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint
    for (size_t i = 0; i < mOutputs.size(); i++) {
    for (size_t i = 0; i < mOutputs.size(); i++) {
        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) ||
                (outputDesc != mPrimaryOutput && !isTelephonyRxOrTx(outputDesc))) {
            // As done in setDeviceConnectionState, we could also fix default device issue by
            // As done in setDeviceConnectionState, we could also fix default device issue by
            // preventing the force re-routing in case of default dev that distinguishes on address.
            // preventing the force re-routing in case of default dev that distinguishes on address.
            // Let's give back to engine full device choice decision however.
            // Let's give back to engine full device choice decision however.
            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs);
            bool forceRouting = !newDevices.isEmpty();
            waitMs = setOutputDevices(outputDesc, newDevices, forceRouting, delayMs, nullptr,
                                      true /*requiresMuteCheck*/,
                                      !forceRouting /*requiresVolumeCheck*/);
            // Only apply special touch sound delay once
            // Only apply special touch sound delay once
            delayMs = 0;
            delayMs = 0;
        }
        }
@@ -4799,6 +4811,18 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
    return status;
    return status;
}
}


sp<SourceClientDescriptor> AudioPolicyManager::startAudioSourceInternal(
        const struct audio_port_config *source, const audio_attributes_t *attributes, uid_t uid)
{
    ALOGV("%s", __FUNCTION__);
    audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;

    status_t status = startAudioSource(source, attributes, &portId, uid);
    ALOGE_IF(status != OK, "%s: failed to start audio source (%d)", __func__, status);
    return mAudioSources.valueFor(portId);
}


status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
{
{
    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
+13 −5
Original line number Original line Diff line number Diff line
@@ -638,18 +638,22 @@ protected:
        void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);
        void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);


        bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
        bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
            return mCallRxSourceClientPort != AUDIO_PORT_HANDLE_NONE
            return mCallRxSourceClient != nullptr && source == mCallRxSourceClient;
                && source == mAudioSources.valueFor(mCallRxSourceClientPort);
        }
        }


        void connectTelephonyRxAudioSource();
        void connectTelephonyRxAudioSource();


        void disconnectTelephonyAudioSource(audio_port_handle_t &portHandle);
        void disconnectTelephonyAudioSource(sp<SourceClientDescriptor> &clientDesc);


        void connectTelephonyTxAudioSource(const sp<DeviceDescriptor> &srcdevice,
        void connectTelephonyTxAudioSource(const sp<DeviceDescriptor> &srcdevice,
                                           const sp<DeviceDescriptor> &sinkDevice,
                                           const sp<DeviceDescriptor> &sinkDevice,
                                           uint32_t delayMs);
                                           uint32_t delayMs);


        bool isTelephonyRxOrTx(const sp<SwAudioOutputDescriptor>& desc) const {
            return (mCallRxSourceClient != nullptr && mCallRxSourceClient->belongsToOutput(desc))
                    || (mCallTxSourceClient != nullptr
                    &&  mCallTxSourceClient->belongsToOutput(desc));
        }


        /**
        /**
         * @brief updates routing for all inputs.
         * @brief updates routing for all inputs.
@@ -952,8 +956,8 @@ protected:


        // The port handle of the hardware audio source created internally for the Call RX audio
        // The port handle of the hardware audio source created internally for the Call RX audio
        // end point.
        // end point.
        audio_port_handle_t mCallRxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
        sp<SourceClientDescriptor> mCallRxSourceClient;
        audio_port_handle_t mCallTxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
        sp<SourceClientDescriptor> mCallTxSourceClient;


        // Support for Multi-Stream Decoder (MSD) module
        // Support for Multi-Stream Decoder (MSD) module
        sp<DeviceDescriptor> getMsdAudioInDevice() const;
        sp<DeviceDescriptor> getMsdAudioInDevice() const;
@@ -988,6 +992,10 @@ protected:
        bool isMsdPatch(const audio_patch_handle_t &handle) const;
        bool isMsdPatch(const audio_patch_handle_t &handle) const;


private:
private:
        sp<SourceClientDescriptor> startAudioSourceInternal(
                const struct audio_port_config *source, const audio_attributes_t *attributes,
                uid_t uid);

        void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
        void onNewAudioModulesAvailableInt(DeviceVector *newDevices);


        // Add or remove AC3 DTS encodings based on user preferences.
        // Add or remove AC3 DTS encodings based on user preferences.