summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-08-08 09:31:42 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-08-08 09:31:42 -0700
commitc3e6572e0ff535932b1f6ffb7bcf5acd891675fb (patch)
treee4d87846a30c25c0c2c06c2ab314f93bb945b49f /services
parentea7c2fea6a031d37270cb5b22b432729626b266d (diff)
parentb8ba0a979067a4efb0b3819bf17770793e41c15e (diff)
downloadframeworks_av-c3e6572e0ff535932b1f6ffb7bcf5acd891675fb.zip
frameworks_av-c3e6572e0ff535932b1f6ffb7bcf5acd891675fb.tar.gz
frameworks_av-c3e6572e0ff535932b1f6ffb7bcf5acd891675fb.tar.bz2
Merge "AudioFlinger: protect input/output stream access"
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp115
-rw-r--r--services/audioflinger/AudioFlinger.h12
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);