Merge "audio policy: fix regression with duplicated output handle"
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index cd2174d..78a184b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -133,6 +133,9 @@
             // Note: called after changeRefCount(-1);
             void stop();
             void close();
+            status_t openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
+                                     const sp<SwAudioOutputDescriptor>& output2,
+                                     audio_io_handle_t *ioHandle);
 
     const sp<IOProfile> mProfile;          // I/O profile this output derives from
     audio_io_handle_t mIoHandle;           // output handle
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 17fc272..caaa0f7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -222,7 +222,7 @@
 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
                                                  AudioPolicyClientInterface *clientInterface)
     : AudioOutputDescriptor(profile, clientInterface),
-    mProfile(profile), mIoHandle(0), mLatency(0),
+    mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
     mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
     mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
@@ -509,6 +509,30 @@
     }
 }
 
+status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
+                                                  const sp<SwAudioOutputDescriptor>& output2,
+                                                  audio_io_handle_t *ioHandle)
+{
+    // open a duplicating output thread for the new output and the primary output
+    // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
+    // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
+    *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
+    if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
+        return INVALID_OPERATION;
+    }
+
+    mId = AudioPort::getNextUniqueId();
+    mIoHandle = *ioHandle;
+    mOutput1 = output1;
+    mOutput2 = output2;
+    mSamplingRate = output2->mSamplingRate;
+    mFormat = output2->mFormat;
+    mChannelMask = output2->mChannelMask;
+    mLatency = output2->mLatency;
+
+    return NO_ERROR;
+}
+
 // HwAudioOutputDescriptor implementation
 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
                                                  AudioPolicyClientInterface *clientInterface)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 40e0199..afd23a6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3959,19 +3959,12 @@
                         //TODO: configure audio effect output stage here
 
                         // open a duplicating output thread for the new output and the primary output
-                        duplicatedOutput =
-                                mpClientInterface->openDuplicateOutput(output,
-                                                                       mPrimaryOutput->mIoHandle);
-                        if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
+                        sp<SwAudioOutputDescriptor> dupOutputDesc =
+                                new SwAudioOutputDescriptor(NULL, mpClientInterface);
+                        status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
+                                                                         &duplicatedOutput);
+                        if (status == NO_ERROR) {
                             // add duplicated output descriptor
-                            sp<SwAudioOutputDescriptor> dupOutputDesc =
-                                    new SwAudioOutputDescriptor(NULL, mpClientInterface);
-                            dupOutputDesc->mOutput1 = mPrimaryOutput;
-                            dupOutputDesc->mOutput2 = desc;
-                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
-                            dupOutputDesc->mFormat = desc->mFormat;
-                            dupOutputDesc->mChannelMask = desc->mChannelMask;
-                            dupOutputDesc->mLatency = desc->mLatency;
                             addOutput(duplicatedOutput, dupOutputDesc);
                             applyStreamVolumes(dupOutputDesc, device, 0, true);
                         } else {