OSDN Git Service

audio policy: fix effect handle leak
authorEric Laurent <elaurent@google.com>
Tue, 21 Oct 2014 16:07:11 +0000 (09:07 -0700)
committerEric Laurent <elaurent@google.com>
Tue, 21 Oct 2014 16:56:18 +0000 (09:56 -0700)
Fix ref counting error in AudioPolicyEffect::addInputEffects()
and addOutputSessionEffects()

Bug: 17675112.
Change-Id: I5267d1024a585919f66ead83662e57b78ba53540

services/audiopolicy/AudioPolicyEffects.cpp

index 3c1c042..e7e1b36 100644 (file)
@@ -105,26 +105,28 @@ status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
     inputDesc->mRefCount++;
 
     ALOGV("addInputEffects(): input: %d, refCount: %d", input, inputDesc->mRefCount);
-
-    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
-    for (size_t i = 0; i < effects.size(); i++) {
-        EffectDesc *effect = effects[i];
-        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
-        status_t status = fx->initCheck();
-        if (status != NO_ERROR && status != ALREADY_EXISTS) {
-            ALOGW("addInputEffects(): failed to create Fx %s on source %d",
+    if (inputDesc->mRefCount == 1) {
+        Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
+        for (size_t i = 0; i < effects.size(); i++) {
+            EffectDesc *effect = effects[i];
+            sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0,
+                                                 audioSession, input);
+            status_t status = fx->initCheck();
+            if (status != NO_ERROR && status != ALREADY_EXISTS) {
+                ALOGW("addInputEffects(): failed to create Fx %s on source %d",
+                      effect->mName, (int32_t)aliasSource);
+                // fx goes out of scope and strong ref on AudioEffect is released
+                continue;
+            }
+            for (size_t j = 0; j < effect->mParams.size(); j++) {
+                fx->setParameter(effect->mParams[j]);
+            }
+            ALOGV("addInputEffects(): added Fx %s on source: %d",
                   effect->mName, (int32_t)aliasSource);
-            // fx goes out of scope and strong ref on AudioEffect is released
-            continue;
-        }
-        for (size_t j = 0; j < effect->mParams.size(); j++) {
-            fx->setParameter(effect->mParams[j]);
+            inputDesc->mEffects.add(fx);
         }
-        ALOGV("addInputEffects(): added Fx %s on source: %d", effect->mName, (int32_t)aliasSource);
-        inputDesc->mEffects.add(fx);
+        inputDesc->setProcessorEnabled(true);
     }
-    inputDesc->setProcessorEnabled(true);
-
     return status;
 }
 
@@ -241,26 +243,28 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
     }
     procDesc->mRefCount++;
 
-    ALOGV("addOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount);
-
-    Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
-    for (size_t i = 0; i < effects.size(); i++) {
-        EffectDesc *effect = effects[i];
-        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0, audioSession, output);
-        status_t status = fx->initCheck();
-        if (status != NO_ERROR && status != ALREADY_EXISTS) {
-            ALOGE("addOutputSessionEffects(): failed to create Fx  %s on session %d",
-                  effect->mName, audioSession);
-            // fx goes out of scope and strong ref on AudioEffect is released
-            continue;
+    ALOGV("addOutputSessionEffects(): session: %d, refCount: %d",
+          audioSession, procDesc->mRefCount);
+    if (procDesc->mRefCount == 1) {
+        Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
+        for (size_t i = 0; i < effects.size(); i++) {
+            EffectDesc *effect = effects[i];
+            sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0,
+                                                 audioSession, output);
+            status_t status = fx->initCheck();
+            if (status != NO_ERROR && status != ALREADY_EXISTS) {
+                ALOGE("addOutputSessionEffects(): failed to create Fx  %s on session %d",
+                      effect->mName, audioSession);
+                // fx goes out of scope and strong ref on AudioEffect is released
+                continue;
+            }
+            ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
+                  effect->mName, audioSession, (int32_t)stream);
+            procDesc->mEffects.add(fx);
         }
-        ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
-              effect->mName, audioSession, (int32_t)stream);
-        procDesc->mEffects.add(fx);
-    }
-
-    procDesc->setProcessorEnabled(true);
 
+        procDesc->setProcessorEnabled(true);
+    }
     return status;
 }
 
@@ -281,7 +285,8 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu
 
     EffectVector *procDesc = mOutputSessions.valueAt(index);
     procDesc->mRefCount--;
-    ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount);
+    ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
+          audioSession, procDesc->mRefCount);
     if (procDesc->mRefCount == 0) {
         procDesc->setProcessorEnabled(false);
         procDesc->mEffects.clear();