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

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

audio policy: audio source automatic re-connection am: d2c073b0

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ib1b7ad79b27d06c76cb46292ee5d21879d790821
parents 663db425 d2c073b0
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -195,10 +195,18 @@ public:

    ~SourceClientDescriptor() override = default;

    void connect(audio_patch_handle_t patchHandle, const sp<DeviceDescriptor>& sinkDevice) {
        mPatchHandle = patchHandle;
        mSinkDevice = sinkDevice;
    }
    void disconnect() {
        mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        mSinkDevice = nullptr;
    }
    bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
    void setPatchHandle(audio_patch_handle_t patchHandle) { mPatchHandle = patchHandle; }

    sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
    sp<DeviceDescriptor> sinkDevice() const { return mSinkDevice; }
    wp<SwAudioOutputDescriptor> swOutput() const { return mSwOutput; }
    void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput);
    wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
@@ -210,6 +218,7 @@ public:
 private:
    audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    const sp<DeviceDescriptor> mSrcDevice;
    sp<DeviceDescriptor> mSinkDevice;
    wp<SwAudioOutputDescriptor> mSwOutput;
    wp<HwAudioOutputDescriptor> mHwOutput;
};
+30 −13
Original line number Diff line number Diff line
@@ -358,7 +358,11 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
            updateCallRouting(newDevices);
        }

        // Reconnect Audio Source
        for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
            auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
            checkAudioSourceForAttributes(attributes);
        }
        if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
            cleanUpForDevice(device);
        }
@@ -4211,18 +4215,21 @@ 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();

    // May the device (dynamic) have been disconnected/reconnected, id has changed.
    sp<DeviceDescriptor> srcDevice = mAvailableInputDevices.getDevice(
                sourceDesc->srcDevice()->type(),
                String8(sourceDesc->srcDevice()->address().c_str()),
                AUDIO_FORMAT_DEFAULT);
    DeviceVector sinkDevices =
            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",
                __FUNCTION__, sinkDevice->toString().c_str());

    if (!mAvailableOutputDevices.contains(sinkDevice)) {
        ALOGE("%s Device %s not available", __func__, sinkDevice->toString().c_str());
        return INVALID_OPERATION;
    }
    PatchBuilder patchBuilder;
    patchBuilder.addSink(sinkDevice).addSource(srcDevice);
    audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
@@ -4232,7 +4239,7 @@ status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>
        ALOGW("%s patch panel could not connect device patch, error %d", __func__, status);
        return INVALID_OPERATION;
    }
    sourceDesc->setPatchHandle(handle);
    sourceDesc->connect(handle, sinkDevice);
    // SW Bridge? (@todo: HW bridge, keep track of HwOutput for device selection "reconsideration")
    sp<SwAudioOutputDescriptor> swOutput = sourceDesc->swOutput().promote();
    if (swOutput != 0) {
@@ -4515,6 +4522,10 @@ bool AudioPolicyManager::isCallScreenModeSupported()
status_t AudioPolicyManager::disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
{
    ALOGV("%s port Id %d", __FUNCTION__, sourceDesc->portId());
    if (!sourceDesc->isConnected()) {
        ALOGV("%s port Id %d already disconnected", __FUNCTION__, sourceDesc->portId());
        return NO_ERROR;
    }
    sp<SwAudioOutputDescriptor> swOutput = sourceDesc->swOutput().promote();
    if (swOutput != 0) {
        status_t status = stopSource(swOutput, sourceDesc);
@@ -4530,7 +4541,9 @@ status_t AudioPolicyManager::disconnectAudioSource(const sp<SourceClientDescript
            ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
        }
    }
    return releaseAudioPatchInternal(sourceDesc->getPatchHandle());
    status_t status = releaseAudioPatchInternal(sourceDesc->getPatchHandle());
    sourceDesc->disconnect();
    return status;
}

sp<SourceClientDescriptor> AudioPolicyManager::getSourceForAttributesOnOutput(
@@ -6462,9 +6475,9 @@ void AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc
{
    for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--)  {
        sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
        if (sourceDesc->srcDevice()->equals(deviceDesc)) {
            ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->portId());
            stopAudioSource(sourceDesc->portId());
        if (sourceDesc->isConnected() && (sourceDesc->srcDevice()->equals(deviceDesc) ||
                                          sourceDesc->sinkDevice()->equals(deviceDesc))) {
            disconnectAudioSource(sourceDesc);
        }
    }

@@ -6478,10 +6491,14 @@ void AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc
                release = true;
            }
        }
        const char *address = deviceDesc->address().c_str();
        for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++)  {
            const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
            if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
                    sink->ext.device.type == deviceDesc->type()) {
                    sink->ext.device.type == deviceDesc->type() &&
                    (strnlen(address, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0
                     || strncmp(sink->ext.device.address, address,
                                 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
                release = true;
            }
        }