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

Commit 663db425 authored by Francois Gaffie's avatar Francois Gaffie Committed by Automerger Merge Worker
Browse files

AudioPolicy: remove devices while Sw bridge established am: 5bd3d2d1

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1304017

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I88a957946e7305b930c2c1e6290e74b9b6a67079
parents 24131d41 5bd3d2d1
Loading
Loading
Loading
Loading
+30 −4
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
                    if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
                            (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
                                (desc->mDirectOpenCount == 0))) {
                        clearAudioSourcesForOutput(output);
                        closeOutput(output);
                    }
                }
@@ -3944,8 +3945,9 @@ status_t AudioPolicyManager::releaseAudioPatchInternal(audio_patch_handle_t hand
                sp<SwAudioOutputDescriptor> outputDesc =
                        mOutputs.getOutputFromId(patch->sources[1].id);
                if (outputDesc == NULL) {
                    ALOGE("%s output not found for id %d", __func__, patch->sources[0].id);
                    return BAD_VALUE;
                    ALOGW("%s output not found for id %d", __func__, patch->sources[0].id);
                    // releaseOutput has already called closeOuput in case of direct output
                    return NO_ERROR;
                }
                if (patchDesc->getHandle() != outputDesc->getPatchHandle()) {
                    // force SwOutput patch removal as AF counter part patch has already gone.
@@ -4209,12 +4211,13 @@ status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>

    // make sure we only have one patch per source.
    disconnectAudioSource(sourceDesc);
    sourceDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);

    audio_attributes_t attributes = sourceDesc->attributes();
    sp<DeviceDescriptor> srcDevice = sourceDesc->srcDevice();

    DeviceVector sinkDevices =
            mEngine->getOutputDevicesForAttributes(attributes, nullptr, true);
            mEngine->getOutputDevicesForAttributes(attributes, nullptr, false /*fromCache*/);
    ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for attributes");
    sp<DeviceDescriptor> sinkDevice = sinkDevices.itemAt(0);
    ALOG_ASSERT(mAvailableOutputDevices.contains(sinkDevice), "%s: Device %s not available",
@@ -5346,6 +5349,28 @@ bool AudioPolicyManager::followsSameRouting(const audio_attributes_t &lAttr,
            mEngine->getProductStrategyForAttributes(rAttr);
}

void AudioPolicyManager::checkAudioSourceForAttributes(const audio_attributes_t &attr)
{
    for (size_t i = 0; i < mAudioSources.size(); i++)  {
        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
        if (sourceDesc != nullptr && followsSameRouting(attr, sourceDesc->attributes())
                && sourceDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE) {
            connectAudioSource(sourceDesc);
        }
    }
}

void AudioPolicyManager::clearAudioSourcesForOutput(audio_io_handle_t output)
{
    for (size_t i = 0; i < mAudioSources.size(); i++)  {
        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
        if (sourceDesc != nullptr && sourceDesc->swOutput().promote() != nullptr
                && sourceDesc->swOutput().promote()->mIoHandle == output) {
            disconnectAudioSource(sourceDesc);
        }
    }
}

void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
{
    auto psId = mEngine->getProductStrategyForAttributes(attr);
@@ -5441,7 +5466,7 @@ void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr
                                newDevices.types());
            }
            sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
            if (source != 0){
            if (source != nullptr) {
                connectAudioSource(source);
            }
        }
@@ -5464,6 +5489,7 @@ void AudioPolicyManager::checkOutputForAllStrategies()
    for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
        auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
        checkOutputForAttributes(attributes);
        checkAudioSourceForAttributes(attributes);
    }
}

+11 −0
Original line number Diff line number Diff line
@@ -571,6 +571,16 @@ protected:
         */
        void checkOutputForAttributes(const audio_attributes_t &attr);

        /**
         * @brief checkAudioSourceForAttributes checks if any AudioSource following the same routing
         * as the given audio attributes is not routed and try to connect it.
         * It must be called once checkOutputForAttributes has been called for orphans AudioSource,
         * aka AudioSource not attached to any Audio Output (e.g. AudioSource connected to direct
         * Output which has been disconnected (and output closed) due to sink device unavailable).
         * @param attr to be considered
         */
        void checkAudioSourceForAttributes(const audio_attributes_t &attr);

        bool followsSameRouting(const audio_attributes_t &lAttr,
                                const audio_attributes_t &rAttr) const;

@@ -739,6 +749,7 @@ protected:

        sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
                                                                  const audio_attributes_t &attr);
        void clearAudioSourcesForOutput(audio_io_handle_t output);

        void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);