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

Commit 484e927c authored by Eric Laurent's avatar Eric Laurent
Browse files

audiopolicy: fix VoIP and system sound routing concurrency

On platforms with dedicated output profiles for VoIP, activity on
all output streams should be considered when use case priority is
evaluated while selecting current device on a given output stream.

For now, implement a simple rule taking only into account output streams
attached to the same audio HAL module and limited to voice call use
case.
This should be extended to all use cases with a refined rule
considering mutually exclusive devices (using same backend) as opposed
to all streams on the same audio HAL module.

Bug: 109640706
Test: repro steps in b/109640706
Change-Id: I2cea35911a6121980f128a3a3d694699364854eb
parent bebb9d11
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -4872,11 +4872,15 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescr
    //      use device for strategy DTMF
    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
    //      use device for strategy t-t-s

    // FIXME: extend use of isStrategyActiveOnSameModule() to all strategies
    // with a refined rule considering mutually exclusive devices (using same backend)
    // as opposed to all streams on the same audio HAL module.
    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
    } else if (isInCall() ||
                    isStrategyActive(outputDesc, STRATEGY_PHONE)) {
               isStrategyActiveOnSameModule(outputDesc, STRATEGY_PHONE)) {
        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
@@ -5884,6 +5888,20 @@ bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outpu
    return false;
}

bool AudioPolicyManager::isStrategyActiveOnSameModule(const sp<AudioOutputDescriptor>& outputDesc,
                                          routing_strategy strategy, uint32_t inPastMs,
                                          nsecs_t sysTime) const
{
    for (size_t i = 0; i < mOutputs.size(); i++) {
        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
        if (outputDesc->sharesHwModuleWith(desc)
            && isStrategyActive(desc, strategy, inPastMs, sysTime)) {
            return true;
        }
    }
    return false;
}

audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
{
    return mEngine->getForceUse(usage);
+4 −0
Original line number Diff line number Diff line
@@ -321,6 +321,10 @@ protected:
        bool isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc, routing_strategy strategy,
                              uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;

        bool isStrategyActiveOnSameModule(const sp<AudioOutputDescriptor>& outputDesc,
                                                  routing_strategy strategy, uint32_t inPastMs = 0,
                                                  nsecs_t sysTime = 0) const;

        // change the route of the specified output. Returns the number of ms we have slept to
        // allow new routing to take effect in certain cases.
        virtual uint32_t setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,