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

Commit ef505b0e authored by Andy Hung's avatar Andy Hung Committed by Gerrit Code Review
Browse files

Merge "Add AudioFlinger to Thread thread safety annotations" into main

parents 39e51be3 f79092de
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -1102,8 +1102,9 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
            // move effect chain to this output thread if an effect on same session was waiting
            // for a track to be created
            if (effectThread != nullptr) {
                audio_utils::lock_guard _sl(effectThread->mutex());
                if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
                // No thread safety analysis: double lock on a thread capability.
                audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex());
                if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) {
                    effectThreadId = thread->id();
                    effectIds = thread->getEffectIds_l(sessionId);
                }
@@ -3034,7 +3035,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
                    audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex());
                    Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
                    for (size_t i = 0; i < effectChains.size(); i ++) {
                        moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
                        moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(),
                                dstThread);
                    }
                }
@@ -4298,7 +4299,7 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t
    }

    audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex());
    return moveEffectChain_l(sessionId, srcThread, dstThread);
    return moveEffectChain_ll(sessionId, srcThread, dstThread);
}


@@ -4318,25 +4319,26 @@ void AudioFlinger::setEffectSuspended(int effectId,
}


// moveEffectChain_l must be called with both srcThread and dstThread mutex()s held
status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
// moveEffectChain_ll must be called with the AudioFlinger::mutex()
// and both srcThread and dstThread mutex()s held
status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId,
        IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
{
    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
            sessionId, srcThread, dstThread);
    ALOGV("%s: session %d from thread %p to thread %p",
            __func__, sessionId, srcThread, dstThread);

    sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId);
    if (chain == 0) {
        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
                sessionId, srcThread);
        ALOGW("%s: effect chain for session %d not on source thread %p",
                __func__, sessionId, srcThread);
        return INVALID_OPERATION;
    }

    // Check whether the destination thread and all effects in the chain are compatible
    if (!chain->isCompatibleWithThread_l(dstThread)) {
        ALOGW("moveEffectChain_l() effect chain failed because"
        ALOGW("%s: effect chain failed because"
                " destination thread %p is not compatible with effects in the chain",
                dstThread);
                __func__, dstThread);
        return INVALID_OPERATION;
    }

@@ -4358,7 +4360,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
            effect = chain->getEffectFromId_l(0)) {
        srcThread->removeEffect_l(effect);
        removed.add(effect);
        status = dstThread->addEffect_l(effect);
        status = dstThread->addEffect_ll(effect);
        if (status != NO_ERROR) {
            errorString = StringPrintf(
                    "cannot add effect %p to destination thread", effect.get());
@@ -4384,7 +4386,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
        for (const auto& effect : removed) {
            dstThread->removeEffect_l(effect); // Note: Depending on error location, the last
                                               // effect may not have been placed on dstThread.
            if (srcThread->addEffect_l(effect) == NO_ERROR) {
            if (srcThread->addEffect_ll(effect) == NO_ERROR) {
                ++restored;
                if (dstChain == nullptr) {
                    dstChain = effect->getCallback()->chain().promote();
@@ -4449,16 +4451,16 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
            return INVALID_OPERATION;
        }
        thread->removeEffect_l(effect);
        status = dstThread->addEffect_l(effect);
        status = dstThread->addEffect_ll(effect);
        if (status != NO_ERROR) {
            thread->addEffect_l(effect);
            thread->addEffect_ll(effect);
            status = INVALID_OPERATION;
            goto Exit;
        }

        dstChain = effect->getCallback()->chain().promote();
        if (dstChain == 0) {
            thread->addEffect_l(effect);
            thread->addEffect_ll(effect);
            status = INVALID_OPERATION;
        }

+3 −2
Original line number Diff line number Diff line
@@ -367,8 +367,9 @@ private:
    bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final
            EXCLUDES_AudioFlinger_Mutex;

    status_t moveEffectChain_l(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final REQUIRES(mutex());
    status_t moveEffectChain_ll(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final
            REQUIRES(mutex(), audio_utils::ThreadBase_Mutex);

    // This is a helper that is called during incoming binder calls.
    // Requests media.log to start merging log buffers
+4 −1
Original line number Diff line number Diff line
@@ -3338,7 +3338,10 @@ status_t DeviceEffectProxy::onCreatePatch(
}

status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
        const struct audio_port_config *port, sp<IAfEffectHandle> *handle) {
        const struct audio_port_config *port, sp<IAfEffectHandle> *handle)
NO_THREAD_SAFETY_ANALYSIS
// calling function 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
{

    ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d",
            __func__, port->type, port->ext.device.type,
+41 −22
Original line number Diff line number Diff line
@@ -67,44 +67,56 @@ struct stream_type_t {
// and hence may be used by the Effect / Track framework.
class IAfThreadCallback : public virtual RefBase {
public:
    virtual audio_utils::mutex& mutex() const = 0;
    virtual bool isNonOffloadableGlobalEffectEnabled_l() const = 0;  // Tracks
    virtual audio_utils::mutex& mutex() const
            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
    virtual bool isNonOffloadableGlobalEffectEnabled_l() const
            REQUIRES(mutex()) = 0;  // Tracks
    virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
    virtual bool btNrecIsOff() const = 0;
    virtual float masterVolume_l() const = 0;
    virtual bool masterMute_l() const = 0;
    virtual float getMasterBalance_l() const = 0;
    virtual bool streamMute_l(audio_stream_type_t stream) const = 0;
    virtual float masterVolume_l() const
            REQUIRES(mutex()) = 0;
    virtual bool masterMute_l() const
            REQUIRES(mutex()) = 0;
    virtual float getMasterBalance_l() const
            REQUIRES(mutex()) = 0;
    virtual bool streamMute_l(audio_stream_type_t stream) const
            REQUIRES(mutex()) = 0;
    virtual audio_mode_t getMode() const = 0;
    virtual bool isLowRamDevice() const = 0;
    virtual bool isAudioPolicyReady() const = 0;  // Effects
    virtual uint32_t getScreenState() const = 0;
    virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const = 0;
    virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const
            REQUIRES(mutex()) = 0;
    virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0;
    virtual const sp<MelReporter>& getMelReporter() const = 0;
    virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0;
    virtual sp<IAudioManager> getOrCreateAudioManager() = 0;  // Tracks

    virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) = 0;
    virtual status_t moveEffectChain_l(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) = 0;
    virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
            EXCLUDES_AudioFlinger_Mutex = 0;
    virtual status_t moveEffectChain_ll(audio_session_t sessionId,
            IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
            REQUIRES(mutex(), audio_utils::ThreadBase_Mutex) = 0;

    virtual void requestLogMerge() = 0;
    virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) = 0;
    virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name)
            REQUIRES(mutex()) = 0;
    virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0;

    virtual 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) = 0;
            const wp<IAfTrackBase>& cookie)
            EXCLUDES_AudioFlinger_Mutex = 0;

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

class IAfThreadBase : public virtual RefBase {
@@ -213,7 +225,8 @@ public:
            status_t* status /*non-NULL*/,
            bool pinned,
            bool probe,
            bool notifyFramesProcessed) = 0;
            bool notifyFramesProcessed)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    // return values for hasAudioSession (bit field)
    enum effect_state {
@@ -255,7 +268,8 @@ public:
    // add and effect module. Also creates the effect chain is none exists for
    // the effects audio session. Only called in a context of moving an effect
    // from one thread to another
    virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0;
    virtual status_t addEffect_ll(const sp<IAfEffectModule>& effect)
            REQUIRES(audio_utils::AudioFlinger_Mutex, mutex()) = 0;
    // remove and effect module. Also removes the effect chain is this was the last
    // effect
    virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0;
@@ -310,7 +324,8 @@ public:
    // deliver stats to mediametrics.
    virtual void sendStatistics(bool force) = 0;

    virtual audio_utils::mutex& mutex() const = 0;
    virtual audio_utils::mutex& mutex() const
            RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0;

    virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0;
    virtual void onEffectDisable() = 0;
@@ -321,8 +336,10 @@ public:
    virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0;

    virtual bool isStreamInitialized() const = 0;
    virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0;
    virtual void stopMelComputation_l() = 0;
    virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
    virtual void stopMelComputation_l()
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0;

@@ -398,7 +415,8 @@ public:
            audio_port_handle_t portId,
            const sp<media::IAudioTrackCallback>& callback,
            bool isSpatialized,
            bool isBitPerfect) = 0;
            bool isBitPerfect)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0;
    virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0;
@@ -502,7 +520,8 @@ public:
            pid_t tid,
            status_t* status /*non-NULL*/,
            audio_port_handle_t portId,
            int32_t maxSharedAudioHistoryMs) = 0;
            int32_t maxSharedAudioHistoryMs)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
    virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0;
    virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0;

+119 −114
Original line number Diff line number Diff line
@@ -1794,9 +1794,9 @@ std::vector<int> ThreadBase::getEffectIds_l(audio_session_t sessionId) const
    return chain != nullptr ? chain->getEffectIds() : std::vector<int>{};
}

// PlaybackThread::addEffect_l() must be called with AudioFlinger::mutex() and
// PlaybackThread::mutex() held
status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
// PlaybackThread::addEffect_ll() must be called with AudioFlinger::mutex() and
// ThreadBase::mutex() held
status_t ThreadBase::addEffect_ll(const sp<IAfEffectModule>& effect)
{
    // check for existing effect chain with the requested audio session
    audio_session_t sessionId = effect->sessionId();
@@ -1804,22 +1804,22 @@ status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
    bool chainCreated = false;

    ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(),
             "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x",
                    this, effect->desc().name, effect->desc().flags);
             "%s: on offloaded thread %p: effect %s does not support offload flags %#x",
             __func__, this, effect->desc().name, effect->desc().flags);

    if (chain == 0) {
        // create a new chain for this session
        ALOGV("addEffect_l() new effect chain for session %d", sessionId);
        ALOGV("%s: new effect chain for session %d", __func__, sessionId);
        chain = IAfEffectChain::create(this, sessionId);
        addEffectChain_l(chain);
        chain->setStrategy(getStrategyForSession_l(sessionId));
        chainCreated = true;
    }
    ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
    ALOGV("%s: %p chain %p effect %p", __func__, this, chain.get(), effect.get());

    if (chain->getEffectFromId_l(effect->id()) != 0) {
        ALOGW("addEffect_l() %p effect %s already present in chain %p",
                this, effect->desc().name, chain.get());
        ALOGW("%s: %p effect %s already present in chain %p",
                __func__, this, effect->desc().name, chain.get());
        return BAD_VALUE;
    }

@@ -3122,6 +3122,8 @@ void PlaybackThread::resetDraining(uint32_t sequence)
}

void PlaybackThread::readOutputParameters_l()
NO_THREAD_SAFETY_ANALYSIS
// 'moveEffectChain_ll' requires holding mutex 'AudioFlinger_Mutex' exclusively
{
    // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL
    const audio_config_base_t audioConfig = mOutput->getAudioProperties();
@@ -3289,10 +3291,11 @@ void PlaybackThread::readOutputParameters_l()
    // Note that mutex() is not held when readOutputParameters_l() is called from the constructor
    // but in this case nothing is done below as no audio sessions have effect yet so it doesn't
    // matter.
    // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
    // create a copy of mEffectChains as calling moveEffectChain_ll()
    // can reorder some effect chains
    Vector<sp<IAfEffectChain>> effectChains = mEffectChains;
    for (size_t i = 0; i < effectChains.size(); i ++) {
        mAfThreadCallback->moveEffectChain_l(effectChains[i]->sessionId(),
        mAfThreadCallback->moveEffectChain_ll(effectChains[i]->sessionId(),
            this/* srcThread */, this/* dstThread */);
    }

@@ -7838,6 +7841,8 @@ status_t SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) {
}

void SpatializerThread::checkOutputStageEffects()
NO_THREAD_SAFETY_ANALYSIS
//  'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
{
    bool hasVirtualizer = false;
    bool hasDownMixer = false;
Loading