audio policy: fix effect handle leak

Fix ref counting error in AudioPolicyEffect::addInputEffects()
and addOutputSessionEffects()

Bug: 17675112.
Change-Id: I5267d1024a585919f66ead83662e57b78ba53540
diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/AudioPolicyEffects.cpp
index 3c1c042..e7e1b36 100644
--- a/services/audiopolicy/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/AudioPolicyEffects.cpp
@@ -105,26 +105,28 @@
     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;
+            inputDesc->mEffects.add(fx);
         }
-        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);
-        inputDesc->mEffects.add(fx);
+        inputDesc->setProcessorEnabled(true);
     }
-    inputDesc->setProcessorEnabled(true);
-
     return status;
 }
 
@@ -241,26 +243,28 @@
     }
     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 @@
 
     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();