audio policy: Fix for voice call audio loss

Audio Policy service filters out one of the create patch
commands when it finds two pending commands with the same
patch handles. Due to this routing command is not received
to audio HAL and the voice call set up fails.
Fix this by filtering create patch commands only when
they are issued on the same output.

authored-by: Karthik Reddy Katta <a_katta@codeaurora.org>

Bug: 17787282
Change-Id: If36f0ab71e9b72d6a8eb61d31f762bc5e1683b89
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index 06a7e84..dd4067f 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -839,18 +839,38 @@
         case CREATE_AUDIO_PATCH:
         case RELEASE_AUDIO_PATCH: {
             audio_patch_handle_t handle;
+            struct audio_patch patch;
             if (command->mCommand == CREATE_AUDIO_PATCH) {
                 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
+                patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
             } else {
                 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
             }
             audio_patch_handle_t handle2;
+            struct audio_patch patch2;
             if (command2->mCommand == CREATE_AUDIO_PATCH) {
                 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
+                patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
             } else {
                 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
             }
             if (handle != handle2) break;
+            /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
+               same output. */
+            if( (command->mCommand == CREATE_AUDIO_PATCH) &&
+                (command2->mCommand == CREATE_AUDIO_PATCH) ) {
+                bool isOutputDiff = false;
+                if (patch.num_sources == patch2.num_sources) {
+                    for (unsigned count = 0; count < patch.num_sources; count++) {
+                        if (patch.sources[count].id != patch2.sources[count].id) {
+                            isOutputDiff = true;
+                            break;
+                        }
+                    }
+                    if (isOutputDiff)
+                       break;
+                }
+            }
             ALOGV("Filtering out %s audio patch command for handle %d",
                   (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
             removedCommands.add(command2);