AudioPolicy: managerdefault: fix onAudioDeviceUpdate callback

Scenario: startAudioSource (SW bridge) started, then stopped.
AF patch is released, so PlaybackThread has empty patch.

Next playback using the same sink will not recreate any patch
on AF as same device (and output desc has still valid patch handle)

Hence, ioconfichanged will get PORT NONE as sink device, no
onAudioDeviceUpdate cb can be fired.

This CL fixes this issue by reset of patch handle on the output

Test: startAudioSource / stopAudioSource then playback on the same
sink. Ensure onAudioDeviceUpdate is fired

Signed-off-by: Francois Gaffie <francois.gaffie@renault.com>
Change-Id: Ia9c2570f687166f38335ed7efae28920f7acc474
Merged-In: Ia9c2570f687166f38335ed7efae28920f7acc474
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a72da83..f30b6f1 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3708,6 +3708,22 @@
             removeAudioPatch(patchDesc->getHandle());
             nextAudioPortGeneration();
             mpClientInterface->onAudioPatchListUpdate();
+            // SW Bridge
+            if (patch->num_sources > 1 && patch->sources[1].type == AUDIO_PORT_TYPE_MIX) {
+                sp<SwAudioOutputDescriptor> outputDesc =
+                        mOutputs.getOutputFromId(patch->sources[1].id);
+                if (outputDesc == NULL) {
+                    ALOGE("%s output not found for id %d", __func__, patch->sources[0].id);
+                    return BAD_VALUE;
+                }
+                // Reset handle so that setOutputDevice will force new AF patch to reach the sink
+                outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
+                setOutputDevices(outputDesc,
+                                 getNewOutputDevices(outputDesc, true /*fromCache*/),
+                                 true, /*force*/
+                                 0,
+                                 NULL);
+            }
         } else {
             return BAD_VALUE;
         }