summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/Threads.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2016-12-01 15:28:29 -0800
committerSean McCreary <mccreary@mcwest.org>2017-03-22 12:36:15 -0600
commitdac1444e4926f94d8d9ac6b6a098ac101ce4a7be (patch)
treef5ce31efebcd13cd9e32dced444b7d2b63d3e727 /services/audioflinger/Threads.cpp
parent0574c56e88e96d33c923a8f54364ac0bf3dc5a91 (diff)
downloadframeworks_av-dac1444e4926f94d8d9ac6b6a098ac101ce4a7be.zip
frameworks_av-dac1444e4926f94d8d9ac6b6a098ac101ce4a7be.tar.gz
frameworks_av-dac1444e4926f94d8d9ac6b6a098ac101ce4a7be.tar.bz2
DO NOT MERGE - improve audio effect framwework thread safety
- Reorganize handle effect creation code to make sure the effect engine is created with both thread and effect chain mutex held. - Reorganize handle disconnect code to make sure the effect engine is released with both thread and effect chain mutex held. - Protect IEffect interface methods in EffectHande with a Mutex. - Only pin effect if the session was acquired first. - Do not use strong pointer to EffectModule in EffectHandles: only the EffectChain has a single strong reference to the EffectModule. Bug: 32707507 CVE-2017-0479 CVE-2017-0480 CVE-2017-0499 Change-Id: Ia1098cba2cd32cc2d1c9dfdff4adc2388dfed80e (cherry picked from commit b378b73dd7480b584340b8028802c9ca2d625123) (cherry picked from commit 22e26d8ee73488c58ba3e7928e5da155151abfd0 with backport by <sultanxda@gmail.com>)
Diffstat (limited to 'services/audioflinger/Threads.cpp')
-rw-r--r--services/audioflinger/Threads.cpp51
1 files changed, 33 insertions, 18 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e5e8bdb..d7c9c47 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1159,7 +1159,8 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
int sessionId,
effect_descriptor_t *desc,
int *enabled,
- status_t *status)
+ status_t *status,
+ bool pinned)
{
sp<EffectModule> effect;
sp<EffectHandle> handle;
@@ -1253,20 +1254,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
}
effectRegistered = true;
// create a new effect module if none present in the chain
- effect = new EffectModule(this, chain, desc, id, sessionId);
- lStatus = effect->status();
- if (lStatus != NO_ERROR) {
- goto Exit;
- }
-
- bool setVal = false;
- if (mType == OFFLOAD || (mType == DIRECT && mIsDirectPcm)) {
- setVal = true;
- }
-
- effect->setOffloaded(setVal, mId);
-
- lStatus = chain->addEffect_l(effect);
+ lStatus = chain->createEffect_l(effect, this, desc, id, (audio_session_t)sessionId, pinned);
if (lStatus != NO_ERROR) {
goto Exit;
}
@@ -1307,6 +1295,33 @@ Exit:
return handle;
}
+void AudioFlinger::ThreadBase::disconnectEffectHandle(EffectHandle *handle,
+ bool unpinIfLast)
+{
+ bool remove = false;
+ sp<EffectModule> effect;
+ {
+ Mutex::Autolock _l(mLock);
+
+ effect = handle->effect().promote();
+ if (effect == 0) {
+ return;
+ }
+ // restore suspended effects if the disconnected handle was enabled and the last one.
+ remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
+ if (remove) {
+ removeEffect_l(effect, true);
+ }
+ }
+ if (remove) {
+ mAudioFlinger->updateOrphanEffectChains(effect);
+ AudioSystem::unregisterEffect(effect->id());
+ if (handle->enabled()) {
+ checkSuspendOnEffectEnabled(effect, false, effect->sessionId());
+ }
+ }
+}
+
sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
{
Mutex::Autolock _l(mLock);
@@ -1371,9 +1386,9 @@ status_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
return NO_ERROR;
}
-void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
+void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect, bool release) {
- ALOGV("removeEffect_l() %p effect %p", this, effect.get());
+ ALOGV("%s %p effect %p", __FUNCTION__, this, effect.get());
effect_descriptor_t desc = effect->desc();
if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
detachAuxEffect_l(effect->id());
@@ -1382,7 +1397,7 @@ void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
sp<EffectChain> chain = effect->chain().promote();
if (chain != 0) {
// remove effect chain if removing last effect
- if (chain->removeEffect_l(effect) == 0) {
+ if (chain->removeEffect_l(effect, release) == 0) {
removeEffectChain_l(chain);
}
} else {