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

Commit 01dc5ca2 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audioflinger: Fix thread fields locking for dumps

Previously, ThreadBase::mLock was only acquired inside
ThreadBase::dumpBase method. That means, dumping of fields of
descendant classes, tracks, and effect chains was performed
without holding ThreadBase::mLock.

This patch changes the way of how dumping is driven. Now only
ThreadBase has a public 'dump' method which is non-virtual.
This method takes the lock and dumps all the fields, tracks, and
effect chains. It calls virtual methods for dumping the contents
of descendant classes.

Bug: 118842894
Test: compare audioflinger dumps A/B
Change-Id: Iaafc75d13935a6a92ca37f9567b7ac7c31374b3e
parent c70268aa
Loading
Loading
Loading
Loading
+47 −72
Original line number Diff line number Diff line
@@ -786,12 +786,8 @@ String8 channelMaskToString(audio_channel_mask_t mask, bool output) {
    }
}

void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused)
void AudioFlinger::ThreadBase::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input",
            this, mThreadName, getTid(), type(), threadTypeToString(type()));

@@ -800,6 +796,21 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
        dprintf(fd, "  Thread may be deadlocked\n");
    }

    dumpBase_l(fd, args);
    dumpInternals_l(fd, args);
    dumpTracks_l(fd, args);
    dumpEffectChains_l(fd, args);

    if (locked) {
        mLock.unlock();
    }

    dprintf(fd, "  Local log:\n");
    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
}

void AudioFlinger::ThreadBase::dumpBase_l(int fd, const Vector<String16>& args __unused)
{
    dprintf(fd, "  I/O handle: %d\n", mId);
    dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
    dprintf(fd, "  Sample rate: %u Hz\n", mSampleRate);
@@ -814,6 +825,8 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
    dprintf(fd, "  Pending config events:");
    size_t numConfig = mConfigEvents.size();
    if (numConfig) {
        const size_t SIZE = 256;
        char buffer[SIZE];
        for (size_t i = 0; i < numConfig; i++) {
            mConfigEvents[i]->dump(buffer, SIZE);
            dprintf(fd, "\n    %s", buffer);
@@ -858,17 +871,12 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
                isOutput() ? "write" : "read",
                mLatencyMs.toString().c_str());
    }

    if (locked) {
        mLock.unlock();
    }
}

void AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
void AudioFlinger::ThreadBase::dumpEffectChains_l(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    size_t numEffectChains = mEffectChains.size();
    snprintf(buffer, SIZE, "  %zu Effect Chains\n", numEffectChains);
@@ -1819,16 +1827,24 @@ AudioFlinger::PlaybackThread::~PlaybackThread()
    free(mEffectBuffer);
}

void AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
// Thread virtuals

void AudioFlinger::PlaybackThread::onFirstRef()
{
    dumpInternals(fd, args);
    dumpTracks(fd, args);
    dumpEffectChains(fd, args);
    dprintf(fd, "  Local log:\n");
    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
    run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}

void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
// ThreadBase virtuals
void AudioFlinger::PlaybackThread::preExit()
{
    ALOGV("  preExit()");
    // FIXME this is using hard-coded strings but in the future, this functionality will be
    //       converted to use audio HAL extensions required to support tunneling
    status_t result = mOutput->stream->setParameters(String8("exiting=1"));
    ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result);
}

void AudioFlinger::PlaybackThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
{
    String8 result;

@@ -1893,10 +1909,8 @@ void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& ar
    write(fd, result.string(), result.size());
}

void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::PlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
{
    dumpBase(fd, args);

    dprintf(fd, "  Master mute: %s\n", mMasterMute ? "on" : "off");
    if (mHapticChannelMask != AUDIO_CHANNEL_NONE) {
        dprintf(fd, "  Haptic channel mask: %#x (%s)\n", mHapticChannelMask,
@@ -1927,23 +1941,6 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
    }
}

// Thread virtuals

void AudioFlinger::PlaybackThread::onFirstRef()
{
    run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}

// ThreadBase virtuals
void AudioFlinger::PlaybackThread::preExit()
{
    ALOGV("  preExit()");
    // FIXME this is using hard-coded strings but in the future, this functionality will be
    //       converted to use audio HAL extensions required to support tunneling
    status_t result = mOutput->stream->setParameters(String8("exiting=1"));
    ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result);
}

// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
        const sp<AudioFlinger::Client>& client,
@@ -5350,9 +5347,9 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa
}


void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::MixerThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
    PlaybackThread::dumpInternals(fd, args);
    PlaybackThread::dumpInternals_l(fd, args);
    dprintf(fd, "  Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs);
    dprintf(fd, "  AudioMixer tracks: %s\n", mAudioMixer->trackNames().c_str());
    dprintf(fd, "  Master mono: %s\n", mMasterMono ? "on" : "off");
@@ -5426,9 +5423,9 @@ AudioFlinger::DirectOutputThread::~DirectOutputThread()
{
}

void AudioFlinger::DirectOutputThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::DirectOutputThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
    PlaybackThread::dumpInternals(fd, args);
    PlaybackThread::dumpInternals_l(fd, args);
    dprintf(fd, "  Master balance: %f  Left: %f  Right: %f\n",
            mMasterBalance.load(), mMasterBalanceLeft, mMasterBalanceRight);
}
@@ -6443,9 +6440,9 @@ void AudioFlinger::DuplicatingThread::threadLoop_standby()
    }
}

void AudioFlinger::DuplicatingThread::dumpInternals(int fd, const Vector<String16>& args __unused)
void AudioFlinger::DuplicatingThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
{
    MixerThread::dumpInternals(fd, args);
    MixerThread::dumpInternals_l(fd, args);

    std::stringstream ss;
    const size_t numTracks = mOutputTracks.size();
@@ -7775,19 +7772,8 @@ void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
    }
}

void AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
{
    dumpInternals(fd, args);
    dumpTracks(fd, args);
    dumpEffectChains(fd, args);
    dprintf(fd, "  Local log:\n");
    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
}

void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::RecordThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
{
    dumpBase(fd, args);

    AudioStreamIn *input = mInput;
    audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE;
    dprintf(fd, "  AudioStreamIn: %p flags %#x (%s)\n",
@@ -7814,7 +7800,7 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
    copy->dump(fd);
}

void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
void AudioFlinger::RecordThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
{
    String8 result;
    size_t numtracks = mTracks.size();
@@ -9079,19 +9065,8 @@ void AudioFlinger::MmapThread::checkInvalidTracks_l()
    }
}

void AudioFlinger::MmapThread::dump(int fd, const Vector<String16>& args)
{
    dumpInternals(fd, args);
    dumpTracks(fd, args);
    dumpEffectChains(fd, args);
    dprintf(fd, "  Local log:\n");
    mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
}

void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::MmapThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
{
    dumpBase(fd, args);

    dprintf(fd, "  Attributes: content type %d usage %d source %d\n",
            mAttr.content_type, mAttr.usage, mAttr.source);
    dprintf(fd, "  Session: %d port Id: %d\n", mSessionId, mPortId);
@@ -9100,7 +9075,7 @@ void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& arg
    }
}

void AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused)
void AudioFlinger::MmapThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
{
    String8 result;
    size_t numtracks = mActiveTracks.size();
@@ -9323,9 +9298,9 @@ void AudioFlinger::MmapPlaybackThread::toAudioPortConfig(struct audio_port_confi
    }
}

void AudioFlinger::MmapPlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
    MmapThread::dumpInternals(fd, args);
    MmapThread::dumpInternals_l(fd, args);

    dprintf(fd, "  Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
            mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
+26 −24
Original line number Diff line number Diff line
@@ -43,9 +43,6 @@ public:

    virtual status_t    readyToRun();

    void dumpBase(int fd, const Vector<String16>& args);
    void dumpEffectChains(int fd, const Vector<String16>& args);

    void clearPowerManager();

    // base for record and playback
@@ -418,7 +415,7 @@ public:

                bool                isMsdDevice() const { return mIsMsdDevice; }

    virtual     void                dump(int fd, const Vector<String16>& args) = 0;
                void                dump(int fd, const Vector<String16>& args);

                // deliver stats to mediametrics.
                void                sendStatistics(bool force);
@@ -470,6 +467,11 @@ protected:
                                return INVALID_OPERATION;
                            }

    virtual     void        dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
                            { }
    virtual     void        dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }


    friend class AudioFlinger;      // for mEffectChains

                const type_t            mType;
@@ -657,6 +659,10 @@ protected:
                };

                SimpleLog mLocalLog;

private:
                void dumpBase_l(int fd, const Vector<String16>& args);
                void dumpEffectChains_l(int fd, const Vector<String16>& args);
};

class VolumeInterface {
@@ -709,8 +715,6 @@ public:
                   audio_io_handle_t id, audio_devices_t device, type_t type, bool systemReady);
    virtual             ~PlaybackThread();

                void        dump(int fd, const Vector<String16>& args) override;

    // Thread virtuals
    virtual     bool        threadLoop();

@@ -760,6 +764,9 @@ protected:
                                mActiveTracks.updatePowerState(this, true /* force */);
                            }

                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
                void        dumpTracks_l(int fd, const Vector<String16>& args) override;

public:

    virtual     status_t    initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
@@ -1009,9 +1016,6 @@ private:
    void        updateMetadata_l() final;
    virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata);

    virtual void dumpInternals(int fd, const Vector<String16>& args);
    void        dumpTracks(int fd, const Vector<String16>& args);

    // The Tracks class manages tracks added and removed from the Thread.
    template <typename T>
    class Tracks {
@@ -1166,7 +1170,6 @@ public:

    virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                   status_t& status);
    virtual     void        dumpInternals(int fd, const Vector<String16>& args);

    virtual     bool        isTrackAllowed_l(
                                    audio_channel_mask_t channelMask, audio_format_t format,
@@ -1185,6 +1188,8 @@ protected:
        }
    }

                void        dumpInternals_l(int fd, const Vector<String16>& args) override;

    // threadLoop snippets
    virtual     ssize_t     threadLoop_write();
    virtual     void        threadLoop_standby();
@@ -1266,8 +1271,6 @@ public:
    virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                   status_t& status);

                void        dumpInternals(int fd, const Vector<String16>& args) override;

    virtual     void        flushHw_l();

                void        setMasterBalance(float balance) override;
@@ -1278,6 +1281,8 @@ protected:
    virtual     uint32_t    suspendSleepTimeUs() const;
    virtual     void        cacheParameters_l();

                void        dumpInternals_l(int fd, const Vector<String16>& args) override;

    // threadLoop snippets
    virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
    virtual     void        threadLoop_mix();
@@ -1397,8 +1402,6 @@ public:
    virtual                 ~DuplicatingThread();

    // Thread virtuals
    virtual     void        dumpInternals(int fd, const Vector<String16>& args) override;

                void        addOutputTrack(MixerThread* thread);
                void        removeOutputTrack(MixerThread* thread);
                uint32_t    waitTimeMs() const { return mWaitTimeMs; }
@@ -1407,6 +1410,7 @@ public:
                        const StreamOutHalInterface::SourceMetadata& metadata) override;
protected:
    virtual     uint32_t    activeSleepTimeUs() const;
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;

private:
                bool        outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks);
@@ -1512,9 +1516,6 @@ public:
    void        destroyTrack_l(const sp<RecordTrack>& track);
    void        removeTrack_l(const sp<RecordTrack>& track);

    void        dumpInternals(int fd, const Vector<String16>& args);
    void        dumpTracks(int fd, const Vector<String16>& args);

    // Thread virtuals
    virtual bool        threadLoop();
    virtual void        preExit();
@@ -1551,7 +1552,6 @@ public:
            // return true if the caller should then do it's part of the stopping process
            bool        stop(RecordTrack* recordTrack);

            void        dump(int fd, const Vector<String16>& args) override;
            AudioStreamIn* clearInput();
            virtual sp<StreamHalInterface> stream() const;

@@ -1619,6 +1619,11 @@ public:
                            return audio_is_input_device(
                                    mInDevice & mTimestampCorrectedDevices);
                        }

protected:
            void        dumpInternals_l(int fd, const Vector<String16>& args) override;
            void        dumpTracks_l(int fd, const Vector<String16>& args) override;

private:
            // Enter standby if not already in standby, and set mStandby flag
            void    standbyIfNotAlreadyInStandby();
@@ -1768,11 +1773,9 @@ class MmapThread : public ThreadBase
                // Sets the UID records silence
    virtual     void        setRecordSilenced(uid_t uid __unused, bool silenced __unused) {}

                void        dump(int fd, const Vector<String16>& args) override;
    virtual     void        dumpInternals(int fd, const Vector<String16>& args);
                void        dumpTracks(int fd, const Vector<String16>& args);

 protected:
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
                void        dumpTracks_l(int fd, const Vector<String16>& args) override;

                audio_attributes_t      mAttr;
                audio_session_t         mSessionId;
@@ -1822,8 +1825,6 @@ public:
    virtual     void        checkSilentMode_l();
                void        processVolume_l() override;

    virtual     void        dumpInternals(int fd, const Vector<String16>& args);

    virtual     bool        isOutput() const override { return true; }

                void        updateMetadata_l() override;
@@ -1831,6 +1832,7 @@ public:
    virtual     void        toAudioPortConfig(struct audio_port_config *config);

protected:
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;

                audio_stream_type_t         mStreamType;
                float                       mMasterVolume;