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

Commit 3bca9e7c authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: Create Thread callback" into udc-dev-plus-aosp

parents 25143505 b1dac1a3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ int main(int argc __unused, char **argv)
        // attempting to call audio flinger on a null pointer could make the process crash
        // and attract attentions.
        std::vector<AudioMMapPolicyInfo> policyInfos;
        status_t status = af->getMmapPolicyInfos(
        status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos(
                AudioMMapPolicyType::DEFAULT, &policyInfos);
        // Initialize aaudio service when querying mmap policy succeeds and
        // any of the policy supports MMAP.
+2 −2
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) {
}

// getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() {
std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const {
    if (mAudioVibratorInfos.empty()) {
        return {};
    }
@@ -4662,7 +4662,7 @@ Exit:
    return status;
}

bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l()
bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const
NO_THREAD_SAFETY_ANALYSIS  // thread lock for getEffectChain_l.
{
    if (mGlobalEffectEnableTime != 0 &&
+66 −96
Original line number Diff line number Diff line
@@ -122,9 +122,6 @@
#include "Client.h"
#include "ResamplerBufferProvider.h"

// TODO(b/291319167) remove me when AudioFlinger class not directly used by subcomponents
namespace android { class AudioFlinger; }

// include AudioFlinger component interfaces
#include "IAfPatchPanel.h"  // this should be listed before other IAf* interfaces.
#include "IAfEffect.h"
@@ -167,24 +164,17 @@ class AudioFlinger
    , public IAfDeviceEffectManagerCallback
    , public IAfMelReporterCallback
    , public IAfPatchPanelCallback
    , public IAfThreadCallback
{
    friend class sp<AudioFlinger>;
    // TODO(b/291319167) Create interface and remove friends.
    // TODO(b/291012167) replace the Thread friends with an interface.
    friend class DirectOutputThread;
    friend class MixerThread;
    friend class MmapPlaybackThread;
    friend class MmapThread;
    friend class PlaybackThread;
    friend class RecordThread;
    friend class ThreadBase;

public:
    static void instantiate() ANDROID_API;

    static AttributionSourceState checkAttributionSourcePackage(
        const AttributionSourceState& attributionSource);

private:

    // ---- begin IAudioFlinger interface

    status_t dump(int fd, const Vector<String16>& args) final;
@@ -324,7 +314,7 @@ public:

    status_t getMmapPolicyInfos(
            media::audio::common::AudioMMapPolicyType policyType,
            std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) override;
            std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final;

    int32_t getAAudioMixerBurstCount() const final;

@@ -373,6 +363,7 @@ public:

    // ---- begin IAfDeviceEffectManagerCallback interface

    // also used by IAfThreadCallback
    bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); }
    // below also used by IAfMelReporterCallback, IAfPatchPanelCallback
    const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; }
@@ -385,6 +376,7 @@ public:

    // ---- begin IAfMelReporterCallback interface

    // below also used by IAfThreadCallback
    Mutex& mutex() const final { return mLock; }
    sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final REQUIRES(mLock);

@@ -425,13 +417,62 @@ public:

    // ---- end of IAfPatchPanelCallback interface

    // ----- begin IAfThreadCallback interface

    bool isNonOffloadableGlobalEffectEnabled_l() const final;
    bool btNrecIsOff() const final { return mBtNrecIsOff.load(); }
    float masterVolume_l() const final;
    bool masterMute_l() const final;
    float getMasterBalance_l() const;
    // no range check, AudioFlinger::mLock held
    bool streamMute_l(audio_stream_type_t stream) const final { return mStreamTypes[stream].mute; }
    audio_mode_t getMode() const final { return mMode; }
    bool isLowRamDevice() const final { return mIsLowRamDevice; }

    std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final;
    const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; }
    const sp<MelReporter>& getMelReporter() const final { return mMelReporter; }
    const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final {
        return mEffectsFactoryHal;
    }
    sp<IAudioManager> getOrCreateAudioManager() final;

    // Called when the last effect handle on an effect instance is removed. If this
    // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
    // and removed from mOrphanEffectChains if it does not contain any effect.
    // Return true if the effect was found in mOrphanEffectChains, false otherwise.
    bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final;

    status_t moveEffectChain_l(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final;

    // This is a helper that is called during incoming binder calls.
    // Requests media.log to start merging log buffers
    void requestLogMerge() final;
    sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final;
    void unregisterWriter(const sp<NBLog::Writer>& writer) final;

    sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
            audio_session_t triggerSession,
            audio_session_t listenerSession,
            const audioflinger::SyncEventCallback& callBack,
            const wp<IAfTrackBase>& cookie) final;

    void ioConfigChanged(audio_io_config_event_t event,
            const sp<AudioIoDescriptor>& ioDesc,
            pid_t pid = 0) final;
    void onNonOffloadableGlobalEffectEnable() final;
    void onSupportedLatencyModesChanged(
            audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final;

    // ---- end of IAfThreadCallback interface

    /* List available audio ports and their attributes */
    status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const;

    sp<NBLog::Writer>   newWriter_l(size_t size, const char *name);
    void                unregisterWriter(const sp<NBLog::Writer>& writer);
    sp<EffectsFactoryHalInterface> getEffectsFactory();

public:
    status_t openMmapStream(MmapStreamInterface::stream_direction_t direction,
                            const audio_attributes_t *attr,
                            audio_config_base_t *config,
@@ -446,8 +487,6 @@ public:
        const sp<os::ExternalVibration>& externalVibration);
    static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);

    std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l();

private:
    // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
    static const size_t kLogMemorySize = 400 * 1024;
@@ -457,38 +496,6 @@ private:
    Vector< sp<NBLog::Writer> > mUnregisteredWriters;
    Mutex               mUnregisteredWritersLock;

public:
    // Life cycle of gAudioFlinger and AudioFlinger:
    //
    // AudioFlinger is created once and survives until audioserver crashes
    // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we
    // don't issue a ServiceManager::tryUnregisterService().
    //
    // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef().
    // After this is set, it is safe to obtain a wp<> or sp<> from it as the
    // underlying object does not go away.
    //
    // Note: For most inner classes, it is acceptable to hold a reference to the outer
    // AudioFlinger instance as creation requires AudioFlinger to exist in the first place.
    //
    // An atomic here ensures underlying writes have completed before setting
    // the pointer. Access by memory_order_seq_cst.
    //

    static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;

    sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
                                        audio_session_t triggerSession,
                                        audio_session_t listenerSession,
                                        const audioflinger::SyncEventCallback& callBack,
                                        const wp<IAfTrackBase>& cookie);

    bool        btNrecIsOff() const { return mBtNrecIsOff.load(); }

private:

               audio_mode_t getMode() const { return mMode; }

                            AudioFlinger() ANDROID_API;
    ~AudioFlinger() override;

@@ -507,6 +514,10 @@ private:
    // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS.
    static const bool kEnableExtendedChannels = true;

public:
    // Remove this when Oboeservice is updated to obtain handle directly.
    static inline std::atomic<AudioFlinger*> gAudioFlinger = nullptr;

    // Returns true if channel mask is permitted for the PCM sink in the MixerThread
    static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
        switch (audio_channel_mask_get_representation(channelMask)) {
@@ -565,7 +576,7 @@ private:

    // Internal dump utilities.
    static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
public:

    // TODO(b/291319167) extract to afutils
    static bool dumpTryLock(Mutex& mutex);
private:
@@ -631,10 +642,6 @@ private:

    const sp<MediaLogNotifier> mMediaLogNotifier;

    // This is a helper that is called during incoming binder calls.
    // Requests media.log to start merging log buffers
    void requestLogMerge();

    // Find io handle by session id.
    // Preference is given to an io handle with a matching effect chain to session id.
    // If none found, AUDIO_IO_HANDLE_NONE is returned.
@@ -665,15 +672,6 @@ private:
    void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
    void closeInputFinish(const sp<IAfRecordThread>& thread);

              // no range check, AudioFlinger::mLock held
              bool streamMute_l(audio_stream_type_t stream) const
                                { return mStreamTypes[stream].mute; }
              void ioConfigChanged(audio_io_config_event_t event,
                                   const sp<AudioIoDescriptor>& ioDesc,
                                   pid_t pid = 0);
              void onSupportedLatencyModesChanged(
                    audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes);

              // Allocate an audio_unique_id_t.
              // Specific types are audio_io_handle_t, audio_session_t, effect ID (int),
              // audio_module_handle_t, and audio_patch_handle_t.
@@ -685,12 +683,9 @@ private:
              //       Thus it may fail by returning an ID of the wrong sign,
              //       or by returning a non-unique ID.
              // This is the internal API.  For the binder API see newAudioUniqueId().
    // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback
    // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback, IAfThreadCallback
    audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;

              status_t moveEffectChain_l(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread);

              // return thread associated with primary hardware device, or NULL
              DeviceTypeSet primaryOutputDevice_l() const;

@@ -706,11 +701,6 @@ private:
                      IAfPlaybackThread* thread,
                      const std::vector<audio_io_handle_t>& secondaryOutputs) const;

public:
    // TODO(b/291319167) cluster together
                bool isNonOffloadableGlobalEffectEnabled_l();
private:
                void onNonOffloadableGlobalEffectEnable();
                bool isSessionAcquired_l(audio_session_t audioSession);

                // Store an effect chain to mOrphanEffectChains keyed vector.
@@ -724,14 +714,7 @@ private:
                // Get an effect chain for the specified session in mOrphanEffectChains and remove
                // it if found. Returns 0 if not found (this is the most common case).
                sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session);
                // Called when the last effect handle on an effect instance is removed. If this
                // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
                // and removed from mOrphanEffectChains if it does not contain any effect.
                // Return true if the effect was found in mOrphanEffectChains, false otherwise.
public:
// TODO(b/291319167) suggest better grouping
                bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect);
private:

                std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();

                void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
@@ -749,14 +732,11 @@ private:
        int         mCnt;
    };

public:
    // TODO(b/291319167) access by getter,
    mutable     Mutex                               mLock;
                // protects mClients and mNotificationClients.
                // must be locked after mLock and ThreadBase::mLock if both must be locked
                // avoids acquiring AudioFlinger::mLock from inside thread loop.

private:
    mutable Mutex mClientLock;

                // protected by mClientLock
@@ -828,9 +808,6 @@ private:
                // protected by mLock
                Vector<AudioSessionRef*> mAudioSessionRefs;

                float       masterVolume_l() const;
                float       getMasterBalance_l() const;
                bool        masterMute_l() const;
                AudioHwDevice* loadHwModule_l(const char *name);

                // sync events awaiting for a session to be created.
@@ -847,7 +824,6 @@ private:
                // Audio data transfer is directly handled by the client creating the MMAP stream
    DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads;

private:
    sp<Client>  registerPid(pid_t pid);    // always returns non-0

    // for use from destructor
@@ -862,15 +838,10 @@ private:
                                      size_t rejectedKVPSize, const String8& rejectedKVPs,
                                      uid_t callingUid);

public:
    sp<IAudioManager> getOrCreateAudioManager();

    // These methods read variables atomically without mLock,
    // though the variables are updated with mLock.
    bool    isLowRamDevice() const { return mIsLowRamDevice; }
    size_t getClientSharedHeapSize() const;

private:
    std::atomic<bool> mIsLowRamDevice;
    bool    mIsDeviceTypeKnown;
    int64_t mTotalMemory;
@@ -881,10 +852,7 @@ private:

    /* const */ sp<IAfPatchPanel> mPatchPanel;

public:
    // TODO(b/291319167) access by getter.
    sp<EffectsFactoryHalInterface> mEffectsFactoryHal;
private:

    const sp<PatchCommandThread> mPatchCommandThread;
    /* const */ sp<DeviceEffectManager> mDeviceEffectManager;  // set onFirstRef
@@ -903,8 +871,10 @@ private:

    static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER;

public:
    // Keep in sync with java definition in media/java/android/media/AudioRecord.java
    static constexpr int32_t kMaxSharedAudioHistoryMs = 5000;
private:

    std::map<media::audio::common::AudioMMapPolicyType,
             std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
+8 −16
Original line number Diff line number Diff line
@@ -2116,30 +2116,22 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock

/* static */
sp<IAfEffectChain> IAfEffectChain::create(
        const wp<IAfThreadBase>& wThread,
        const sp<IAfThreadBase>& thread,
        audio_session_t sessionId)
{
    return sp<EffectChain>::make(wThread, sessionId);
    return sp<EffectChain>::make(thread, sessionId);
}

EffectChain::EffectChain(const wp<IAfThreadBase>& thread,
EffectChain::EffectChain(const sp<IAfThreadBase>& thread,
                                       audio_session_t sessionId)
    : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
      mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
      mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
{
    const sp<IAfThreadBase> p = thread.promote();
    if (p == nullptr) {
        return;
    }
    mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC);
    mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) /
                                    p->frameCount();
}

EffectChain::~EffectChain()
{
    mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
                                    thread->frameCount();
}

// getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held
@@ -2988,12 +2980,12 @@ status_t EffectChain::EffectCallback::createEffectHal(
bool EffectChain::EffectCallback::updateOrphanEffectChains(
        const sp<IAfEffectBase>& effect) {
    // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
    return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
    return mAfThreadCallback->updateOrphanEffectChains(effect->asEffectModule());
}

status_t EffectChain::EffectCallback::allocateHalBuffer(
        size_t size, sp<EffectBufferHalInterface>* buffer) {
    return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
    return mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(size, buffer);
}

status_t EffectChain::EffectCallback::addEffectToHal(
+8 −13
Original line number Diff line number Diff line
@@ -382,8 +382,7 @@ private:
// it also provide it's own input buffer used by the track as accumulation buffer.
class EffectChain : public IAfEffectChain {
public:
    EffectChain(const wp<IAfThreadBase>& wThread, audio_session_t sessionId);
    ~EffectChain() override;
    EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId);

    void process_l() final;

@@ -516,16 +515,11 @@ private:
        // Note: ctors taking a weak pointer to their owner must not promote it
        // during construction (but may keep a reference for later promotion).
        EffectCallback(const wp<EffectChain>& owner,
                const wp<IAfThreadBase>& thread)
                const sp<IAfThreadBase>& thread)  // we take a sp<> but store a wp<>.
            : mChain(owner)
            , mThread(thread)
            , mAudioFlinger(*AudioFlinger::gAudioFlinger) {
            const sp<IAfThreadBase> base = thread.promote();
            if (base != nullptr) {
                mThreadType = base->type();
            } else {
                mThreadType = IAfThreadBase::MIXER;  // assure a consistent value.
            }
            , mThread(thread) {
            mThreadType = thread->type();
            mAfThreadCallback = thread->afThreadCallback();
        }

        status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -566,7 +560,7 @@ private:
        wp<IAfEffectChain> chain() const final { return mChain; }

        bool isAudioPolicyReady() const final {
            return mAudioFlinger.isAudioPolicyReady();
            return mAfThreadCallback->isAudioPolicyReady();
        }

        wp<IAfThreadBase> thread() const { return mThread.load(); }
@@ -574,12 +568,13 @@ private:
        void setThread(const sp<IAfThreadBase>& thread) {
            mThread = thread;
            mThreadType = thread->type();
            mAfThreadCallback = thread->afThreadCallback();
        }

    private:
        const wp<IAfEffectChain> mChain;
        mediautils::atomic_wp<IAfThreadBase> mThread;
        AudioFlinger &mAudioFlinger;  // implementation detail: outer instance always exists.
        sp<IAfThreadCallback> mAfThreadCallback;
        IAfThreadBase::type_t mThreadType;
    };

Loading