Fix AudioPolicyManager dynamic policy initialization

AudioPolicyManager::getInputForAttr() is initializing the AudioMix
 for the new AudioInputDescriptor.
The audio policy manager refactoring introduced a regression where
 the association of an existing AudioMix (registered when the
 associated AudioPolicy was registered) with the input descriptor
 copied a value of local scope, instead of referencing the
 AudioMix in the list of mixes.

Bug 20081375

Change-Id: Iddd57fed8525880afd1d4a5493f97130aabe4816
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 988aed6..816ec05 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -39,7 +39,7 @@
 
     void clearOutput();
 
-    android::AudioMix &getMix();
+    android::AudioMix *getMix();
 
     void setMix(AudioMix &mix);
 
@@ -75,7 +75,7 @@
                                                   audio_devices_t availableDeviceTypes,
                                                   AudioMix **policyMix);
 
-    status_t getInputMixForAttr(audio_attributes_t attr, AudioMix *&policyMix);
+    status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
 };
 
 }; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 84a53ebd..74aca69 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -46,9 +46,9 @@
     mMix = mix;
 }
 
-android::AudioMix &AudioPolicyMix::getMix()
+android::AudioMix *AudioPolicyMix::getMix()
 {
-    return mMix;
+    return &mMix;
 }
 
 status_t AudioPolicyMixCollection::registerMix(String8 address, AudioMix mix)
@@ -103,36 +103,36 @@
 {
     for (size_t i = 0; i < size(); i++) {
         sp<AudioPolicyMix> policyMix = valueAt(i);
-        AudioMix mix = policyMix->getMix();
+        AudioMix *mix = policyMix->getMix();
 
-        if (mix.mMixType == MIX_TYPE_PLAYERS) {
-            for (size_t j = 0; j < mix.mCriteria.size(); j++) {
-                if ((RULE_MATCH_ATTRIBUTE_USAGE == mix.mCriteria[j].mRule &&
-                     mix.mCriteria[j].mAttr.mUsage == attributes.usage) ||
-                        (RULE_EXCLUDE_ATTRIBUTE_USAGE == mix.mCriteria[j].mRule &&
-                         mix.mCriteria[j].mAttr.mUsage != attributes.usage)) {
+        if (mix->mMixType == MIX_TYPE_PLAYERS) {
+            for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+                if ((RULE_MATCH_ATTRIBUTE_USAGE == mix->mCriteria[j].mRule &&
+                     mix->mCriteria[j].mAttr.mUsage == attributes.usage) ||
+                        (RULE_EXCLUDE_ATTRIBUTE_USAGE == mix->mCriteria[j].mRule &&
+                         mix->mCriteria[j].mAttr.mUsage != attributes.usage)) {
                     desc = policyMix->getOutput();
                     break;
                 }
                 if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                         strncmp(attributes.tags + strlen("addr="),
-                                mix.mRegistrationId.string(),
+                                mix->mRegistrationId.string(),
                                 AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
                     desc = policyMix->getOutput();
                     break;
                 }
             }
-        } else if (mix.mMixType == MIX_TYPE_RECORDERS) {
+        } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
             if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE &&
                     strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                     strncmp(attributes.tags + strlen("addr="),
-                            mix.mRegistrationId.string(),
+                            mix->mRegistrationId.string(),
                             AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
                 desc = policyMix->getOutput();
             }
         }
         if (desc != 0) {
-            desc->mPolicyMix = &mix;
+            desc->mPolicyMix = mix;
             return NO_ERROR;
         }
     }
@@ -144,19 +144,19 @@
                                                                         AudioMix **policyMix)
 {
     for (size_t i = 0; i < size(); i++) {
-        AudioMix mix = valueAt(i)->getMix();
+        AudioMix *mix = valueAt(i)->getMix();
 
-        if (mix.mMixType != MIX_TYPE_RECORDERS) {
+        if (mix->mMixType != MIX_TYPE_RECORDERS) {
             continue;
         }
-        for (size_t j = 0; j < mix.mCriteria.size(); j++) {
-            if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix.mCriteria[j].mRule &&
-                    mix.mCriteria[j].mAttr.mSource == inputSource) ||
-               (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix.mCriteria[j].mRule &&
-                    mix.mCriteria[j].mAttr.mSource != inputSource)) {
+        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+            if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
+                    mix->mCriteria[j].mAttr.mSource == inputSource) ||
+               (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
+                    mix->mCriteria[j].mAttr.mSource != inputSource)) {
                 if (availDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
                     if (policyMix != NULL) {
-                        *policyMix = &mix;
+                        *policyMix = mix;
                     }
                     return AUDIO_DEVICE_IN_REMOTE_SUBMIX;
                 }
@@ -167,7 +167,7 @@
     return AUDIO_DEVICE_NONE;
 }
 
-status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix *&policyMix)
+status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix)
 {
     if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
         return BAD_VALUE;
@@ -180,13 +180,13 @@
         return BAD_VALUE;
     }
     sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
-    AudioMix mix = audioPolicyMix->getMix();
+    AudioMix *mix = audioPolicyMix->getMix();
 
-    if (mix.mMixType != MIX_TYPE_PLAYERS) {
+    if (mix->mMixType != MIX_TYPE_PLAYERS) {
         ALOGW("getInputForAttr() bad policy mix type for address %s", address.string());
         return BAD_VALUE;
     }
-    policyMix = &mix;
+    *policyMix = mix;
     return NO_ERROR;
 }
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 797a2b4..67a5c80 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1189,7 +1189,7 @@
 
     if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
             strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
-        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, policyMix);
+        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
         if (ret != NO_ERROR) {
             return ret;
         }
@@ -1308,7 +1308,7 @@
     inputDesc->mIsSoundTrigger = isSoundTrigger;
     inputDesc->mPolicyMix = policyMix;
 
-    ALOGV("getInputForAttr() returns input type = %d", inputType);
+    ALOGV("getInputForAttr() returns input type = %d", *inputType);
 
     addInput(*input, inputDesc);
     mpClientInterface->onAudioPortListUpdate();
@@ -3032,7 +3032,7 @@
                                   address.string());
                         }
                         policyMix->setOutput(desc);
-                        desc->mPolicyMix = &(policyMix->getMix());
+                        desc->mPolicyMix = policyMix->getMix();
 
                     } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
                         // no duplicated output for direct outputs and