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 Diff line number Diff line
@@ -305,6 +305,7 @@ public:
    {
        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 */
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
+50 −2
Original line number Diff line number Diff line
@@ -56,7 +56,13 @@ public:

    virtual void dump(String8 *dst, int spaces) 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; }
    uid_t uid() const { return mUid; }
    audio_session_t session() const { return mSessionId; };
@@ -69,8 +75,16 @@ public:
    bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
    virtual void setActive(bool active) { mActive = active; }
    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 {
        return mPreferredDeviceId != AUDIO_PORT_HANDLE_NONE && (!activeOnly || mActive);
        return !isInternal() &&
                mPreferredDeviceId != AUDIO_PORT_HANDLE_NONE && (!activeOnly || mActive);
    }

private:
@@ -211,6 +225,11 @@ public:
        mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        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; }
    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
    sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
@@ -229,6 +248,35 @@ public:
    sp<DeviceDescriptor> mSinkDevice;
    wp<SwAudioOutputDescriptor> mSwOutput;
    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 :
+2 −1
Original line number 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,
        {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)
        {} /* Sources do not support secondary outputs*/, nullptr),
    mSrcDevice(srcDevice)
{
}