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

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

Merge "AudioFlinger: protect input/output stream access"

parents 6f9ff536 828b9773
Loading
Loading
Loading
Loading
+99 −16
Original line number Original line Diff line number Diff line
@@ -1392,12 +1392,13 @@ status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String
// Thread virtuals
// Thread virtuals
status_t AudioFlinger::PlaybackThread::readyToRun()
status_t AudioFlinger::PlaybackThread::readyToRun()
{
{
    if (mSampleRate == 0) {
    status_t status = initCheck();
    if (status == NO_ERROR) {
        LOGI("AudioFlinger's thread %p ready to run", this);
    } else {
        LOGE("No working audio driver found.");
        LOGE("No working audio driver found.");
        return NO_INIT;
    }
    }
    LOGI("AudioFlinger's thread %p ready to run", this);
    return status;
    return NO_ERROR;
}
}


void AudioFlinger::PlaybackThread::onFirstRef()
void AudioFlinger::PlaybackThread::onFirstRef()
@@ -1491,10 +1492,10 @@ Exit:


uint32_t AudioFlinger::PlaybackThread::latency() const
uint32_t AudioFlinger::PlaybackThread::latency() const
{
{
    if (mOutput) {
    Mutex::Autolock _l(mLock);
    if (initCheck() == NO_ERROR) {
        return mOutput->stream->get_latency(mOutput->stream);
        return mOutput->stream->get_latency(mOutput->stream);
    }
    } else {
    else {
        return 0;
        return 0;
    }
    }
}
}
@@ -1595,16 +1596,21 @@ void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)


String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
{
{
    String8 out_s8;
    String8 out_s8 = String8("");
    char *s;
    char *s;


    Mutex::Autolock _l(mLock);
    if (initCheck() != NO_ERROR) {
        return out_s8;
    }

    s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string());
    s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string());
    out_s8 = String8(s);
    out_s8 = String8(s);
    free(s);
    free(s);
    return out_s8;
    return out_s8;
}
}


// destroyTrack_l() must be called with AudioFlinger::mLock held
// audioConfigChanged_l() must be called with AudioFlinger::mLock held
void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
    AudioSystem::OutputDescriptor desc;
    AudioSystem::OutputDescriptor desc;
    void *param2 = 0;
    void *param2 = 0;
@@ -1663,6 +1669,7 @@ status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, ui
    if (halFrames == 0 || dspFrames == 0) {
    if (halFrames == 0 || dspFrames == 0) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    Mutex::Autolock _l(mLock);
    if (initCheck() != NO_ERROR) {
    if (initCheck() != NO_ERROR) {
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }
@@ -1709,6 +1716,29 @@ uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
}
}




AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput()
{
    Mutex::Autolock _l(mLock);
    return mOutput;
}

AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::clearOutput()
{
    Mutex::Autolock _l(mLock);
    AudioStreamOut *output = mOutput;
    mOutput = NULL;
    return output;
}

// this method must always be called either with ThreadBase mLock held or inside the thread loop
audio_stream_t* AudioFlinger::PlaybackThread::stream()
{
    if (mOutput == NULL) {
        return NULL;
    }
    return &mOutput->stream->common;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
@@ -4083,6 +4113,13 @@ void AudioFlinger::RecordThread::onFirstRef()
    run(mName, PRIORITY_URGENT_AUDIO);
    run(mName, PRIORITY_URGENT_AUDIO);
}
}


status_t AudioFlinger::RecordThread::readyToRun()
{
    status_t status = initCheck();
    LOGW_IF(status != NO_ERROR,"RecordThread %p could not initialize", this);
    return status;
}

bool AudioFlinger::RecordThread::threadLoop()
bool AudioFlinger::RecordThread::threadLoop()
{
{
    AudioBufferProvider::Buffer buffer;
    AudioBufferProvider::Buffer buffer;
@@ -4573,7 +4610,12 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
{
{
    char *s;
    char *s;
    String8 out_s8;
    String8 out_s8 = String8();

    Mutex::Autolock _l(mLock);
    if (initCheck() != NO_ERROR) {
        return out_s8;
    }


    s = mInput->stream->common.get_parameters(&mInput->stream->common, keys.string());
    s = mInput->stream->common.get_parameters(&mInput->stream->common, keys.string());
    out_s8 = String8(s);
    out_s8 = String8(s);
@@ -4645,6 +4687,11 @@ void AudioFlinger::RecordThread::readInputParameters()


unsigned int AudioFlinger::RecordThread::getInputFramesLost()
unsigned int AudioFlinger::RecordThread::getInputFramesLost()
{
{
    Mutex::Autolock _l(mLock);
    if (initCheck() != NO_ERROR) {
        return 0;
    }

    return mInput->stream->get_input_frames_lost(mInput->stream);
    return mInput->stream->get_input_frames_lost(mInput->stream);
}
}


@@ -4669,6 +4716,30 @@ AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
    return mTrack;
    return mTrack;
}
}


AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::getInput()
{
    Mutex::Autolock _l(mLock);
    return mInput;
}

AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput()
{
    Mutex::Autolock _l(mLock);
    AudioStreamIn *input = mInput;
    mInput = NULL;
    return input;
}

// this method must always be called either with ThreadBase mLock held or inside the thread loop
audio_stream_t* AudioFlinger::RecordThread::stream()
{
    if (mInput == NULL) {
        return NULL;
    }
    return &mInput->stream->common;
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


int AudioFlinger::openOutput(uint32_t *pDevices,
int AudioFlinger::openOutput(uint32_t *pDevices,
@@ -4792,7 +4863,8 @@ status_t AudioFlinger::closeOutput(int output)
    thread->exit();
    thread->exit();


    if (thread->type() != ThreadBase::DUPLICATING) {
    if (thread->type() != ThreadBase::DUPLICATING) {
        AudioStreamOut *out = thread->getOutput();
        AudioStreamOut *out = thread->clearOutput();
        // from now on thread->mOutput is NULL
        out->hwDev->close_output_stream(out->hwDev, out->stream);
        out->hwDev->close_output_stream(out->hwDev, out->stream);
        delete out;
        delete out;
    }
    }
@@ -4932,7 +5004,8 @@ status_t AudioFlinger::closeInput(int input)
    }
    }
    thread->exit();
    thread->exit();


    AudioStreamIn *in = thread->getInput();
    AudioStreamIn *in = thread->clearInput();
    // from now on thread->mInput is NULL
    in->hwDev->close_input_stream(in->hwDev, in->stream);
    in->hwDev->close_input_stream(in->hwDev, in->stream);
    delete in;
    delete in;


@@ -5010,7 +5083,8 @@ AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
{
{
    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
        if (thread->getOutput()->hwDev == mPrimaryHardwareDev) {
        AudioStreamOut *output = thread->getOutput();
        if (output != NULL && output->hwDev == mPrimaryHardwareDev) {
            return thread;
            return thread;
        }
        }
    }
    }
@@ -5789,7 +5863,10 @@ AudioFlinger::EffectModule::~EffectModule()
                (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
                (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
            sp<ThreadBase> thread = mThread.promote();
            sp<ThreadBase> thread = mThread.promote();
            if (thread != 0) {
            if (thread != 0) {
                thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
                audio_stream_t *stream = thread->stream();
                if (stream != NULL) {
                    stream->remove_audio_effect(stream, mEffectInterface);
                }
            }
            }
        }
        }
        // release effect engine
        // release effect engine
@@ -6104,7 +6181,10 @@ status_t AudioFlinger::EffectModule::start_l()
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
        sp<ThreadBase> thread = mThread.promote();
        sp<ThreadBase> thread = mThread.promote();
        if (thread != 0) {
        if (thread != 0) {
            thread->stream()->add_audio_effect(thread->stream(), mEffectInterface);
            audio_stream_t *stream = thread->stream();
            if (stream != NULL) {
                stream->add_audio_effect(stream, mEffectInterface);
            }
        }
        }
    }
    }
    return status;
    return status;
@@ -6137,7 +6217,10 @@ status_t AudioFlinger::EffectModule::stop_l()
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
        sp<ThreadBase> thread = mThread.promote();
        sp<ThreadBase> thread = mThread.promote();
        if (thread != 0) {
        if (thread != 0) {
            thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
            audio_stream_t *stream = thread->stream();
            if (stream != NULL) {
                stream->remove_audio_effect(stream, mEffectInterface);
            }
        }
        }
    }
    }
    return status;
    return status;
+7 −5
Original line number Original line Diff line number Diff line
@@ -724,8 +724,9 @@ private:
                                    int sessionId,
                                    int sessionId,
                                    status_t *status);
                                    status_t *status);


                    AudioStreamOut* getOutput() { return mOutput; }
                    AudioStreamOut* getOutput();
                    virtual audio_stream_t* stream() { return &mOutput->stream->common; }
                    AudioStreamOut* clearOutput();
                    virtual audio_stream_t* stream();


                    void        suspend() { mSuspended++; }
                    void        suspend() { mSuspended++; }
                    void        restore() { if (mSuspended) mSuspended--; }
                    void        restore() { if (mSuspended) mSuspended--; }
@@ -967,7 +968,7 @@ private:
                ~RecordThread();
                ~RecordThread();


        virtual bool        threadLoop();
        virtual bool        threadLoop();
        virtual status_t    readyToRun() { return NO_ERROR; }
        virtual status_t    readyToRun();
        virtual void        onFirstRef();
        virtual void        onFirstRef();


        virtual status_t    initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; }
        virtual status_t    initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; }
@@ -984,8 +985,9 @@ private:
                status_t    start(RecordTrack* recordTrack);
                status_t    start(RecordTrack* recordTrack);
                void        stop(RecordTrack* recordTrack);
                void        stop(RecordTrack* recordTrack);
                status_t    dump(int fd, const Vector<String16>& args);
                status_t    dump(int fd, const Vector<String16>& args);
                AudioStreamIn* getInput() { return mInput; }
                AudioStreamIn* getInput();
                virtual audio_stream_t* stream() { return &mInput->stream->common; }
                AudioStreamIn* clearInput();
                virtual audio_stream_t* stream();


        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer);
        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer);
        virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer);
        virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer);