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

Commit 541a2005 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: fix call routing via audio patch

The audio source used to control the call RX path must be tagged as
internal so that the corresponding audio patch is not realized with a
software audio patch because of the lack of gain controller on sink device.

Voice call volume is controlled via setVoiceVolume() HAL API and not
track volume control or device gain control

Bug: 302519079
Test: make
Change-Id: Ie9217f1be1bf127915d6bdf42d5de0834966b9d2
parent ebbf45e2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -285,7 +285,8 @@ public:
    virtual status_t startAudioSource(const struct audio_port_config *source,
                                      const audio_attributes_t *attributes,
                                      audio_port_handle_t *portId,
                                      uid_t uid) = 0;
                                      uid_t uid,
                                      bool internal = false) = 0;
    virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;

    virtual status_t setMasterMono(bool mono) = 0;
+14 −29
Original line number Diff line number Diff line
@@ -222,7 +222,8 @@ public:
                           const struct audio_port_config &config,
                           const sp<DeviceDescriptor>& srcDevice,
                           audio_stream_type_t stream, product_strategy_t strategy,
                           VolumeSource volumeSource);
                           VolumeSource volumeSource,
                           bool isInternal);

    ~SourceClientDescriptor() override = default;

@@ -248,6 +249,7 @@ public:
    void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput, bool closeOutput = false);
    wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
    void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
    bool isInternal() const override { return mIsInternal; }

    using ClientDescriptor::dump;
    void dump(String8 *dst, int spaces) const override;
@@ -268,34 +270,17 @@ public:
     * behavior of AudioDeviceCallback.
     */
    bool mCloseOutput = false;
};

    /**
 * @brief The InternalSourceClientDescriptor class
 * Specialized Client Descriptor for either a raw patch created from @see createAudioPatch API
 * or for internal audio patches managed by APM (e.g. phone call patches).
     * True for specialized Client Descriptor for either a raw patch created from
     * @see createAudioPatch API or for internal audio patches managed by APM
     * (e.g. phone call patches).
     * Whatever the bridge created (software or hardware), we need a client to track the activity
     * and manage volumes.
     * The Audio Patch requested sink is expressed as a preferred device which allows to route
     * the SwOutput. Then APM will performs checks on the UID (against UID of Audioserver) of the
     * requester to prevent rerouting SwOutput involved in raw patches.
     */
class InternalSourceClientDescriptor: public SourceClientDescriptor
{
public:
    InternalSourceClientDescriptor(
            audio_port_handle_t portId, uid_t uid, audio_attributes_t attributes,
            const struct audio_port_config &config, const sp<DeviceDescriptor>& srcDevice,
             const sp<DeviceDescriptor>& sinkDevice,
            product_strategy_t strategy, VolumeSource volumeSource) :
        SourceClientDescriptor(
            portId, uid, attributes, config, srcDevice, AUDIO_STREAM_PATCH, strategy,
            volumeSource)
    {
        setPreferredDeviceId(sinkDevice->getId());
    }
    bool isInternal() const override { return true; }
    ~InternalSourceClientDescriptor() override = default;
    bool mIsInternal = false;
};

class SourceClientCollection :
+2 −2
Original line number Diff line number Diff line
@@ -96,12 +96,12 @@ void RecordClientDescriptor::dump(String8 *dst, int spaces) const
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
         audio_attributes_t attributes, const struct audio_port_config &config,
         const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
         product_strategy_t strategy, VolumeSource volumeSource) :
         product_strategy_t strategy, VolumeSource volumeSource, bool isInternal) :
    TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
        {config.sample_rate, config.channel_mask, config.format}, AUDIO_PORT_HANDLE_NONE,
        stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
        {} /* Sources do not support secondary outputs*/, nullptr),
    mSrcDevice(srcDevice)
    mSrcDevice(srcDevice), mIsInternal(isInternal)
{
}

+18 −22
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
#define LOG_TAG "APM_AudioPolicyManager"

// Need to keep the log statements even in production builds
// to enable VERBOSE logging dynamically.
// to enable VERBOSE logging dynamicstartAudioSourceally.
// You can enable VERBOSE logging as follows:
// adb shell setprop log.tag.APM_AudioPolicyManager V
#define LOG_NDEBUG 0
@@ -782,7 +782,11 @@ void AudioPolicyManager::connectTelephonyRxAudioSource()
        .ext.device.type = AUDIO_DEVICE_IN_TELEPHONY_RX, .ext.device.address = ""
    };
    const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
    mCallRxSourceClient = startAudioSourceInternal(&source, &aa, 0/*uid*/);

    audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
    status_t status = startAudioSource(&source, &aa, &portId, 0 /*uid*/, true /*internal*/);
    ALOGE_IF(status != OK, "%s: failed to start audio source (%d)", __func__, status);
    mCallRxSourceClient = mAudioSources.valueFor(portId);
    ALOGE_IF(mCallRxSourceClient == nullptr,
             "%s failed to start Telephony Rx AudioSource", __func__);
}
@@ -815,9 +819,11 @@ void AudioPolicyManager::connectTelephonyTxAudioSource(

    struct audio_port_config source = {};
    srcDevice->toAudioPortConfig(&source);
    mCallTxSourceClient = new InternalSourceClientDescriptor(
                callTxSourceClientPortId, mUidCached, aa, source, srcDevice, sinkDevice,
                mCommunnicationStrategy, toVolumeSource(aa));
    mCallTxSourceClient = new SourceClientDescriptor(
                callTxSourceClientPortId, mUidCached, aa, source, srcDevice, AUDIO_STREAM_PATCH,
                mCommunnicationStrategy, toVolumeSource(aa), true);
    mCallTxSourceClient->setPreferredDeviceId(sinkDevice->getId());

    audio_patch_handle_t patchHandle = AUDIO_PATCH_HANDLE_NONE;
    status_t status = connectAudioSourceToSink(
                mCallTxSourceClient, sinkDevice, patchBuilder.patch(), patchHandle, mUidCached,
@@ -4874,9 +4880,11 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
    audio_attributes_t attributes = attributes_initializer(AUDIO_USAGE_MEDIA);
    const struct audio_port_config *source = &patch->sources[0];
    sp<SourceClientDescriptor> sourceDesc =
            new InternalSourceClientDescriptor(
                portId, uid, attributes, *source, srcDevice, sinkDevice,
                mEngine->getProductStrategyForAttributes(attributes), toVolumeSource(attributes));
            new SourceClientDescriptor(
                portId, uid, attributes, *source, srcDevice, AUDIO_STREAM_PATCH,
                mEngine->getProductStrategyForAttributes(attributes), toVolumeSource(attributes),
                true);
    sourceDesc->setPreferredDeviceId(sinkDevice->getId());

    status_t status =
            connectAudioSourceToSink(sourceDesc, sinkDevice, patch, *handle, uid, 0 /* delayMs */);
@@ -5543,7 +5551,7 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session
status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
                                              const audio_attributes_t *attributes,
                                              audio_port_handle_t *portId,
                                              uid_t uid)
                                              uid_t uid, bool internal)
{
    ALOGV("%s", __FUNCTION__);
    *portId = AUDIO_PORT_HANDLE_NONE;
@@ -5576,7 +5584,7 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
        new SourceClientDescriptor(*portId, uid, *attributes, *source, srcDevice,
                                   mEngine->getStreamTypeForAttributes(*attributes),
                                   mEngine->getProductStrategyForAttributes(*attributes),
                                   toVolumeSource(*attributes));
                                   toVolumeSource(*attributes), internal);

    status_t status = connectAudioSource(sourceDesc);
    if (status == NO_ERROR) {
@@ -5585,18 +5593,6 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
    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)
{
    ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
+2 −4
Original line number Diff line number Diff line
@@ -339,7 +339,8 @@ public:
        virtual status_t startAudioSource(const struct audio_port_config *source,
                                          const audio_attributes_t *attributes,
                                          audio_port_handle_t *portId,
                                          uid_t uid);
                                          uid_t uid,
                                          bool internal = false);
        virtual status_t stopAudioSource(audio_port_handle_t portId);

        virtual status_t setMasterMono(bool mono);
@@ -1055,9 +1056,6 @@ protected:
        bool isMsdPatch(const audio_patch_handle_t &handle) const;

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

        void onNewAudioModulesAvailableInt(DeviceVector *newDevices);