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 | c3e6572e0ff535932b1f6ffb7bcf5acd891675fb (patch) | |
| tree | e4d87846a30c25c0c2c06c2ab314f93bb945b49f /services | |
| parent | ea7c2fea6a031d37270cb5b22b432729626b266d (diff) | |
| parent | b8ba0a979067a4efb0b3819bf17770793e41c15e (diff) | |
| download | frameworks_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.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);  | 
