summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-07-27 09:48:47 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-27 09:48:47 -0700
commita7280a59259018d997896c043fd2db95f631f12e (patch)
tree516378da6bd410e4fd2fe8cc4927be61b450b684 /services
parent99b25ba8da5fdb7a524b53c5db290f7a64f1259c (diff)
parentec437d8d3db79459d7b19e1734e6fe309bd621e8 (diff)
downloadframeworks_av-a7280a59259018d997896c043fd2db95f631f12e.zip
frameworks_av-a7280a59259018d997896c043fd2db95f631f12e.tar.gz
frameworks_av-a7280a59259018d997896c043fd2db95f631f12e.tar.bz2
Merge "AudioFlinger: fix crash when deleting pre process."
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp38
-rw-r--r--services/audioflinger/AudioFlinger.h4
2 files changed, 27 insertions, 15 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 95b9918..4e068b2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3993,8 +3993,6 @@ bool AudioFlinger::RecordThread::threadLoop()
for (size_t i = 0; i < effectChains.size(); i ++) {
effectChains[i]->process_l();
}
- // enable changes in effect chain
- unlockEffectChains(effectChains);
buffer.frameCount = mFrameCount;
if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
@@ -4094,9 +4092,9 @@ bool AudioFlinger::RecordThread::threadLoop()
// clear the overflow.
usleep(kRecordThreadSleepUs);
}
- } else {
- unlockEffectChains(effectChains);
}
+ // enable changes in effect chain
+ unlockEffectChains(effectChains);
effectChains.clear();
}
@@ -5669,13 +5667,11 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
}
}
- // Release effect engine here so that it is done immediately. Otherwise it will be released
- // by the destructor when the last strong reference on the this object is released which can
- // happen after next process is called on this effect.
- if (size == 0 && mEffectInterface != NULL) {
- // release effect engine
- EffectRelease(mEffectInterface);
- mEffectInterface = NULL;
+ // Prevent calls to process() and other functions on effect interface from now on.
+ // The effect engine will be released by the destructor when the last strong reference on
+ // this object is released which can happen after next process is called.
+ if (size == 0) {
+ mState = DESTROYED;
}
return size;
@@ -5725,7 +5721,7 @@ void AudioFlinger::EffectModule::updateState() {
mState = IDLE;
}
break;
- default: //IDLE , ACTIVE
+ default: //IDLE , ACTIVE, DESTROYED
break;
}
}
@@ -5734,7 +5730,7 @@ void AudioFlinger::EffectModule::process()
{
Mutex::Autolock _l(mLock);
- if (mEffectInterface == NULL ||
+ if (mState == DESTROYED || mEffectInterface == NULL ||
mConfig.inputCfg.buffer.raw == NULL ||
mConfig.outputCfg.buffer.raw == NULL) {
return;
@@ -5910,6 +5906,12 @@ status_t AudioFlinger::EffectModule::start_l()
return status;
}
+status_t AudioFlinger::EffectModule::stop()
+{
+ Mutex::Autolock _l(mLock);
+ return stop_l();
+}
+
status_t AudioFlinger::EffectModule::stop_l()
{
if (mEffectInterface == NULL) {
@@ -5946,7 +5948,7 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
Mutex::Autolock _l(mLock);
// LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
- if (mEffectInterface == NULL) {
+ if (mState == DESTROYED || mEffectInterface == NULL) {
return NO_INIT;
}
status_t status = (*mEffectInterface)->command(mEffectInterface,
@@ -5995,6 +5997,8 @@ status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
case ACTIVE:
mState = STOPPING;
break;
+ case DESTROYED:
+ return NO_ERROR; // simply ignore as we are being destroyed
}
for (size_t i = 1; i < mHandles.size(); i++) {
sp<EffectHandle> h = mHandles[i].promote();
@@ -6016,6 +6020,7 @@ bool AudioFlinger::EffectModule::isEnabled()
case IDLE:
case STOPPING:
case STOPPED:
+ case DESTROYED:
default:
return false;
}
@@ -6031,6 +6036,7 @@ bool AudioFlinger::EffectModule::isProcessEnabled()
return true;
case IDLE:
case STARTING:
+ case DESTROYED:
default:
return false;
}
@@ -6632,6 +6638,10 @@ size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
for (i = 0; i < size; i++) {
if (effect == mEffects[i]) {
+ // calling stop here will remove pre-processing effect from the audio HAL.
+ // This is safe as we hold the EffectChain mutex which guarantees that we are not in
+ // the middle of a read from audio HAL
+ mEffects[i]->stop();
if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
delete[] effect->inBuffer();
} else {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index edd3e2a..7b6215f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1024,7 +1024,8 @@ private:
STARTING,
ACTIVE,
STOPPING,
- STOPPED
+ STOPPED,
+ DESTROYED
};
int id() { return mId; }
@@ -1069,6 +1070,7 @@ private:
status_t setDevice(uint32_t device);
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(uint32_t mode);
+ status_t stop();
status_t dump(int fd, const Vector<String16>& args);