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

Commit 8350d493 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge changes from topics "presubmit-am-87e43861d082492cad38dc75a9f31cdb",...

Merge changes from topics "presubmit-am-87e43861d082492cad38dc75a9f31cdb", "presubmit-am-a8669f4a68d94c8d9b842b36e692e795" into tm-dev

* changes:
  [BUG] AudioPolicyManager: prevent unecessary force routing on SwOutput
  [BUG] AudioPolicyManager: prevent patch leak on SwOutput used for bridges
parents 3c56c244 601801db
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -305,6 +305,7 @@ public:
    {
    {
        return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false;
        return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false;
    }
    }
    bool isRouted() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }


    DeviceVector mDevices; /**< current devices this output is routed to */
    DeviceVector mDevices; /**< current devices this output is routed to */
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
+50 −2
Original line number Original line Diff line number Diff line
@@ -56,7 +56,13 @@ public:


    virtual void dump(String8 *dst, int spaces) const;
    virtual void dump(String8 *dst, int spaces) const;
    virtual std::string toShortString() const;
    virtual std::string toShortString() const;

    /**
     * @brief isInternal
     * @return true if the client corresponds to an audio patch created from createAudioPatch API or
     * for call audio routing, or false if the client corresponds to an AudioTrack, AudioRecord or
     * HW Audio Source.
     */
    virtual bool isInternal() const { return false; }
    audio_port_handle_t portId() const { return mPortId; }
    audio_port_handle_t portId() const { return mPortId; }
    uid_t uid() const { return mUid; }
    uid_t uid() const { return mUid; }
    audio_session_t session() const { return mSessionId; };
    audio_session_t session() const { return mSessionId; };
@@ -69,8 +75,16 @@ public:
    bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
    bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
    virtual void setActive(bool active) { mActive = active; }
    virtual void setActive(bool active) { mActive = active; }
    bool active() const { return mActive; }
    bool active() const { return mActive; }
    /**
     * @brief hasPreferredDevice Note that as internal clients use preferred device for convenience,
     * we do hide this internal behavior to prevent from regression (like invalidating track for
     * clients following same strategies...)
     * @param activeOnly
     * @return
     */
    bool hasPreferredDevice(bool activeOnly = false) const {
    bool hasPreferredDevice(bool activeOnly = false) const {
        return mPreferredDeviceId != AUDIO_PORT_HANDLE_NONE && (!activeOnly || mActive);
        return !isInternal() &&
                mPreferredDeviceId != AUDIO_PORT_HANDLE_NONE && (!activeOnly || mActive);
    }
    }


private:
private:
@@ -211,6 +225,11 @@ 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; }
    bool useSwBridge() const { return mUseSwBridge; }
    bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
    bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
    sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
    sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
@@ -229,6 +248,35 @@ public:
    sp<DeviceDescriptor> mSinkDevice;
    sp<DeviceDescriptor> mSinkDevice;
    wp<SwAudioOutputDescriptor> mSwOutput;
    wp<SwAudioOutputDescriptor> mSwOutput;
    wp<HwAudioOutputDescriptor> mHwOutput;
    wp<HwAudioOutputDescriptor> mHwOutput;
    bool mUseSwBridge = 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).
 * 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;
};
};


class SourceClientCollection :
class SourceClientCollection :
+2 −1
Original line number Original line Diff line number Diff line
@@ -100,7 +100,8 @@ SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t
    TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
    TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
        {config.sample_rate, config.channel_mask, config.format}, AUDIO_PORT_HANDLE_NONE,
        {config.sample_rate, config.channel_mask, config.format}, AUDIO_PORT_HANDLE_NONE,
        stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
        stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
        {} /* Sources do not support secondary outputs*/, nullptr), mSrcDevice(srcDevice)
        {} /* Sources do not support secondary outputs*/, nullptr),
    mSrcDevice(srcDevice)
{
{
}
}


+244 −154

File changed.

Preview size limit exceeded, changes collapsed.

+36 −15
Original line number Original line Diff line number Diff line
@@ -263,10 +263,7 @@ public:
        virtual status_t getAudioPort(struct audio_port_v7 *port);
        virtual status_t getAudioPort(struct audio_port_v7 *port);
        virtual status_t createAudioPatch(const struct audio_patch *patch,
        virtual status_t createAudioPatch(const struct audio_patch *patch,
                                           audio_patch_handle_t *handle,
                                           audio_patch_handle_t *handle,
                                           uid_t uid) {
                                           uid_t uid);
            return createAudioPatchInternal(patch, handle, uid);
        }

        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
                                              uid_t uid);
                                              uid_t uid);
        virtual status_t listAudioPatches(unsigned int *num_patches,
        virtual status_t listAudioPatches(unsigned int *num_patches,
@@ -638,13 +635,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 disconnectTelephonyRxAudioSource();
        void disconnectTelephonyAudioSource(sp<SourceClientDescriptor> &clientDesc);

        void connectTelephonyTxAudioSource(const sp<DeviceDescriptor> &srcdevice,
                                           const sp<DeviceDescriptor> &sinkDevice,
                                           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.
@@ -851,6 +857,12 @@ protected:
        status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
        status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
        status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
        status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);


        status_t connectAudioSourceToSink(const sp<SourceClientDescriptor>& sourceDesc,
                                          const sp<DeviceDescriptor> &sinkDevice,
                                          const struct audio_patch *patch,
                                          audio_patch_handle_t &handle,
                                          uid_t uid, uint32_t delayMs);

        sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
        sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
                                                                  const audio_attributes_t &attr);
                                                                  const audio_attributes_t &attr);
        void clearAudioSourcesForOutput(audio_io_handle_t output);
        void clearAudioSourcesForOutput(audio_io_handle_t output);
@@ -901,8 +913,6 @@ protected:


        SoundTriggerSessionCollection mSoundTriggerSessions;
        SoundTriggerSessionCollection mSoundTriggerSessions;


        sp<AudioPatch> mCallTxPatch;

        HwAudioOutputCollection mHwOutputs;
        HwAudioOutputCollection mHwOutputs;
        SourceClientCollection mAudioSources;
        SourceClientCollection mAudioSources;


@@ -943,7 +953,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;
        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;
@@ -975,7 +986,13 @@ protected:
        // Called by setDeviceConnectionState()
        // Called by setDeviceConnectionState()
        status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
        status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
                                   const char* device_name, media::AudioPort* aidPort);
                                   const char* device_name, media::AudioPort* aidPort);
        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.
@@ -1120,21 +1137,25 @@ private:
         * @param[out] handle patch handle to be provided if patch installed correctly
         * @param[out] handle patch handle to be provided if patch installed correctly
         * @param[in] uid of the client
         * @param[in] uid of the client
         * @param[in] delayMs if required
         * @param[in] delayMs if required
         * @param[in] sourceDesc [optional] in case of external source, source client to be
         * @param[in] sourceDesc source client to be configured when creating the patch, i.e.
         * configured by the patch, i.e. assigning an Output (HW or SW)
         *            assigning an Output (HW or SW) used for volume control.
         * @return NO_ERROR if patch installed correctly, error code otherwise.
         * @return NO_ERROR if patch installed correctly, error code otherwise.
         */
         */
        status_t createAudioPatchInternal(const struct audio_patch *patch,
        status_t createAudioPatchInternal(const struct audio_patch *patch,
                                          audio_patch_handle_t *handle,
                                          audio_patch_handle_t *handle,
                                          uid_t uid, uint32_t delayMs = 0,
                                          uid_t uid, uint32_t delayMs,
                                          const sp<SourceClientDescriptor>& sourceDesc = nullptr);
                                          const sp<SourceClientDescriptor>& sourceDesc);
        /**
        /**
         * @brief releaseAudioPatchInternal internal function to remove an audio patch
         * @brief releaseAudioPatchInternal internal function to remove an audio patch
         * @param[in] handle of the patch to be removed
         * @param[in] handle of the patch to be removed
         * @param[in] delayMs if required
         * @param[in] delayMs if required
         * @param[in] sourceDesc [optional] in case of external source, source client to be
         * unrouted from the patch, i.e. assigning an Output (HW or SW)
         * @return NO_ERROR if patch removed correctly, error code otherwise.
         * @return NO_ERROR if patch removed correctly, error code otherwise.
         */
         */
        status_t releaseAudioPatchInternal(audio_patch_handle_t handle, uint32_t delayMs = 0);
        status_t releaseAudioPatchInternal(audio_patch_handle_t handle,
                                           uint32_t delayMs = 0,
                                           const sp<SourceClientDescriptor>& sourceDesc = nullptr);


        status_t installPatch(const char *caller,
        status_t installPatch(const char *caller,
                audio_patch_handle_t *patchHandle,
                audio_patch_handle_t *patchHandle,