diff options
author | Eric Laurent <elaurent@google.com> | 2011-08-08 09:31:42 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-08-08 09:31:42 -0700 |
commit | c993acbce63b60385b01cf1b95a4799ec308339b (patch) | |
tree | 91c5994bc4faa34a22d7cfb495e78de248f2fc63 /services/audioflinger | |
parent | 6f9ff5368c79f8d8d74ee5fa0cdc5410c57cf671 (diff) | |
parent | 828b9773cc765f45b4f61af70f2184ca85fa82f9 (diff) | |
download | frameworks_base-c993acbce63b60385b01cf1b95a4799ec308339b.zip frameworks_base-c993acbce63b60385b01cf1b95a4799ec308339b.tar.gz frameworks_base-c993acbce63b60385b01cf1b95a4799ec308339b.tar.bz2 |
Merge "AudioFlinger: protect input/output stream access"
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 115 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 12 |
2 files changed, 106 insertions, 21 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 2355d5c..e201b17 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1392,12 +1392,13 @@ status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String // Thread virtuals 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."); - return NO_INIT; } - LOGI("AudioFlinger's thread %p ready to run", this); - return NO_ERROR; + return status; } void AudioFlinger::PlaybackThread::onFirstRef() @@ -1491,10 +1492,10 @@ Exit: uint32_t AudioFlinger::PlaybackThread::latency() const { - if (mOutput) { + Mutex::Autolock _l(mLock); + if (initCheck() == NO_ERROR) { return mOutput->stream->get_latency(mOutput->stream); - } - else { + } else { return 0; } } @@ -1595,16 +1596,21 @@ void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track) String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) { - String8 out_s8; + String8 out_s8 = String8(""); char *s; + Mutex::Autolock _l(mLock); + if (initCheck() != NO_ERROR) { + return out_s8; + } + s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string()); out_s8 = String8(s); free(s); 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) { AudioSystem::OutputDescriptor desc; void *param2 = 0; @@ -1663,6 +1669,7 @@ status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, ui if (halFrames == 0 || dspFrames == 0) { return BAD_VALUE; } + Mutex::Autolock _l(mLock); if (initCheck() != NO_ERROR) { 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) @@ -4083,6 +4113,13 @@ void AudioFlinger::RecordThread::onFirstRef() 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() { AudioBufferProvider::Buffer buffer; @@ -4573,7 +4610,12 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() String8 AudioFlinger::RecordThread::getParameters(const String8& keys) { 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()); out_s8 = String8(s); @@ -4645,6 +4687,11 @@ void AudioFlinger::RecordThread::readInputParameters() unsigned int AudioFlinger::RecordThread::getInputFramesLost() { + Mutex::Autolock _l(mLock); + if (initCheck() != NO_ERROR) { + return 0; + } + return mInput->stream->get_input_frames_lost(mInput->stream); } @@ -4669,6 +4716,30 @@ AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track() 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, @@ -4792,7 +4863,8 @@ status_t AudioFlinger::closeOutput(int output) thread->exit(); 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); delete out; } @@ -4932,7 +5004,8 @@ status_t AudioFlinger::closeInput(int input) } 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); delete in; @@ -5010,7 +5083,8 @@ AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() { for (size_t i = 0; i < mPlaybackThreads.size(); i++) { PlaybackThread *thread = mPlaybackThreads.valueAt(i).get(); - if (thread->getOutput()->hwDev == mPrimaryHardwareDev) { + AudioStreamOut *output = thread->getOutput(); + if (output != NULL && output->hwDev == mPrimaryHardwareDev) { return thread; } } @@ -5789,7 +5863,10 @@ AudioFlinger::EffectModule::~EffectModule() (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { sp<ThreadBase> thread = mThread.promote(); 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 @@ -6104,7 +6181,10 @@ status_t AudioFlinger::EffectModule::start_l() (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) { sp<ThreadBase> thread = mThread.promote(); 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; @@ -6137,7 +6217,10 @@ status_t AudioFlinger::EffectModule::stop_l() (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) { sp<ThreadBase> thread = mThread.promote(); 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; diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 791341a..4fa70a2 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -724,8 +724,9 @@ private: int sessionId, status_t *status); - AudioStreamOut* getOutput() { return mOutput; } - virtual audio_stream_t* stream() { return &mOutput->stream->common; } + AudioStreamOut* getOutput(); + AudioStreamOut* clearOutput(); + virtual audio_stream_t* stream(); void suspend() { mSuspended++; } void restore() { if (mSuspended) mSuspended--; } @@ -967,7 +968,7 @@ private: ~RecordThread(); virtual bool threadLoop(); - virtual status_t readyToRun() { return NO_ERROR; } + virtual status_t readyToRun(); virtual void onFirstRef(); virtual status_t initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; } @@ -984,8 +985,9 @@ private: status_t start(RecordTrack* recordTrack); void stop(RecordTrack* recordTrack); status_t dump(int fd, const Vector<String16>& args); - AudioStreamIn* getInput() { return mInput; } - virtual audio_stream_t* stream() { return &mInput->stream->common; } + AudioStreamIn* getInput(); + AudioStreamIn* clearInput(); + virtual audio_stream_t* stream(); virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer); virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); |