policy_hal: Move global effects to correct output

-With voice playback concurrency handling in place, offload or direct
outputs are force closed if a voice call is on.
-In such scenario, on closeOutput, global effects are moved to
primary output by audioflinger instead of deep buffer output
(mix output).
- When call ends, and playback resumes, movement of effects
from previous output to new output fails.
- Ensure that when a output is closed, effects if present
are moved to mix output, such that when a new output comes up
the effects can be moved from MIX output to the required output.

CRs-Fixed: 1030710
Change-Id: I127c02adff3f2148e318d9f4945c501f3f20dc55
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index a5e0978..8b12475 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -97,6 +97,37 @@
     return flag;
 }
 #endif /*VOICE_CONCURRENCY*/
+
+void AudioPolicyManagerCustom::moveGlobalEffect()
+{
+    audio_io_handle_t dstOutput = getOutputForEffect();
+    if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
+#ifdef DOLBY_ENABLE
+        status_t status =
+                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
+                                                    mPrimaryOutput->mIoHandle,
+                                                    dstOutput);
+        if (status == NO_ERROR) {
+            for (size_t i = 0; i < mEffects.size(); i++) {
+                 sp<EffectDescriptor> desc = mEffects.valueAt(i);
+                 if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
+                     // update the mIo member of EffectDescriptor
+                     // for the global effect
+                     ALOGV("%s updating mIo", __FUNCTION__);
+                     desc->mIo = dstOutput;
+                 }
+            }
+        } else {
+                ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__,
+                                     mPrimaryOutput->mIoHandle, dstOutput);
+        }
+#else // DOLBY_END
+        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
+                                   mPrimaryOutput->mIoHandle, dstOutput);
+#endif
+    }
+}
+
 // ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
 // ----------------------------------------------------------------------------
@@ -771,6 +802,10 @@
                 }
             }
         }
+        // If effects where present on any of the above closed outputs,
+        // audioflinger moved them to the primary output by default
+        // move them back to the appropriate output.
+        moveGlobalEffect();
     }
 
     if ((AUDIO_MODE_IN_CALL == oldState || AUDIO_MODE_IN_COMMUNICATION == oldState) &&
@@ -839,6 +874,10 @@
                     closeOutput(mOutputs.keyAt(i));
                 }
             }
+            // If effects where present on any of the above closed outputs,
+            // audioflinger moved them to the primary output by default
+            // move them back to the appropriate output.
+            moveGlobalEffect();
         } else if ((oldState == AUDIO_MODE_IN_COMMUNICATION) &&
                     (mEngine->getPhoneState() == AUDIO_MODE_NORMAL)) {
             // call invalidate for music so that music can fallback to compress
@@ -1990,6 +2029,10 @@
                 closeOutput(mOutputs.keyAt(i));
             }
         }
+        // If effects where present on any of the above closed outputs,
+        // audioflinger moved them to the primary output by default
+        // move them back to the appropriate output.
+        moveGlobalEffect();
     }
 #endif
 
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 6f47a54..dfda1c9 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -114,6 +114,7 @@
         static audio_output_flags_t getFallBackPath();
         int mFallBackflag;
 #endif /*VOICE_CONCURRENCY*/
+        void moveGlobalEffect();
 
         // handle special cases for sonification strategy while in call: mute streams or replace by
         // a special tone in the device used for communication