Merge "Snap for 5674421 from fa4a379ff8e06a8d0d9a9c9e57c3b3cdb6027db1 to pi-platform-release am: a22302ec9a" into pie-cuttlefish-testing
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index ebe08c6..5d479b3 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -129,6 +129,7 @@
 
     shared_libs: [
         "libstagefright_enc_common",
+        "liblog",
     ],
 
     cflags: ["-Werror"],
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
index 81b3f69..79b37ff 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
@@ -14,6 +14,7 @@
 
     shared_libs: [
         "libdl",
+        "liblog",
     ],
 
     static_libs: [
diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
index 8cebb09..f2e28c4 100644
--- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
@@ -47,6 +47,10 @@
 
 #include "q_pulse.h"
 
+#undef LOG_TAG
+#define LOG_TAG "amrwbenc"
+#include "log/log.h"
+
 static Word16 tipos[36] = {
     0, 1, 2, 3,                            /* starting point &ipos[0], 1st iter */
     1, 2, 3, 0,                            /* starting point &ipos[4], 2nd iter */
@@ -745,11 +749,16 @@
 
         i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
 
-        while (ind[i] >= 0)
+        while (i < NPMAXPT * NB_TRACK && ind[i] >= 0)
         {
             i += 1;
         }
-        ind[i] = index;
+        if (i < NPMAXPT * NB_TRACK) {
+            ind[i] = index;
+        } else {
+            ALOGE("b/132647222, OOB access in ind array track=%d i=%d", track, i);
+            android_errorWriteLog(0x534e4554, "132647222");
+        }
     }
 
     k = 0;
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 72604e3..6c34963 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -157,6 +157,12 @@
                  buffer->size() + bufferRemaining);
 
             sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
+            if (copy->data() == NULL) {
+                android_errorWriteLog(0x534e4554, "68399439");
+                ALOGE("not enough memory to download: requesting %zu + %zu",
+                        buffer->size(), bufferRemaining);
+                return NO_MEMORY;
+            }
             memcpy(copy->data(), buffer->data(), buffer->size());
             copy->setRange(0, buffer->size());
 
diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp
index 088eaae..0dc7722 100644
--- a/media/libstagefright/timedtext/TextDescriptions.cpp
+++ b/media/libstagefright/timedtext/TextDescriptions.cpp
@@ -383,7 +383,7 @@
         tmpData += 8;
         size_t remaining = size - 8;
 
-        if (size < chunkSize) {
+        if (chunkSize <= 8 || size < chunkSize) {
             return OK;
         }
         switch(chunkType) {
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index b25d6d4..df1cf26 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -27,7 +27,7 @@
 namespace android {
 
 class IOProfile;
-class AudioMix;
+class AudioPolicyMix;
 
 // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
 // and keep track of the usage of this input.
@@ -44,7 +44,7 @@
 
     audio_io_handle_t             mIoHandle;       // input handle
     audio_devices_t               mDevice;         // current device this input is routed to
-    AudioMix                      *mPolicyMix;     // non NULL when used by a dynamic policy
+    wp<AudioPolicyMix>            mPolicyMix;      // non NULL when used by a dynamic policy
     const sp<IOProfile>           mProfile;        // I/O profile this output derives from
 
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 5e5d38b..247f20f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -29,7 +29,7 @@
 namespace android {
 
 class IOProfile;
-class AudioMix;
+class AudioPolicyMix;
 class AudioPolicyClientInterface;
 class DeviceDescriptor;
 
@@ -141,7 +141,7 @@
     audio_io_handle_t mIoHandle;           // output handle
     uint32_t mLatency;                  //
     audio_output_flags_t mFlags;   //
-    AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
+    wp<AudioPolicyMix> mPolicyMix;           // non NULL when used by a dynamic policy
     sp<SwAudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
     sp<SwAudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
     uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 8fc6fe9..3345579 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -29,9 +29,11 @@
 /**
  * custom mix entry in mPolicyMixes
  */
-class AudioPolicyMix : public RefBase {
+class AudioPolicyMix : public AudioMix, public RefBase {
 public:
-    AudioPolicyMix() {}
+    AudioPolicyMix(const AudioMix &mix);
+    AudioPolicyMix(const AudioPolicyMix&) = delete;
+    AudioPolicyMix& operator=(const AudioPolicyMix&) = delete;
 
     const sp<SwAudioOutputDescriptor> &getOutput() const;
 
@@ -39,14 +41,9 @@
 
     void clearOutput();
 
-    android::AudioMix *getMix();
-
-    void setMix(AudioMix &mix);
-
     status_t dump(int fd, int spaces, int index) const;
 
 private:
-    AudioMix    mMix;                   // Audio policy mix descriptor
     sp<SwAudioOutputDescriptor> mOutput;  // Corresponding output stream
 };
 
@@ -76,9 +73,9 @@
 
     audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
                                                   audio_devices_t availableDeviceTypes,
-                                                  AudioMix **policyMix);
+                                                  sp<AudioPolicyMix> *policyMix);
 
-    status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
+    status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix);
 
     status_t dump(int fd) const;
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index dd5247d..f7d8bf3 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -28,6 +28,7 @@
 namespace android {
 
 class AudioPolicyClientInterface;
+class AudioPolicyMix;
 
 class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
 {
@@ -40,7 +41,7 @@
                  audio_input_flags_t flags,
                  uid_t uid,
                  bool isSoundTrigger,
-                 AudioMix* policyMix,
+                 const sp<AudioPolicyMix> &policyMix,
                  AudioPolicyClientInterface *clientInterface);
 
     status_t dump(int fd, int spaces, int index) const;
@@ -75,7 +76,7 @@
     bool mSilenced;
     uint32_t  mOpenCount;
     uint32_t  mActiveCount;
-    AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
+    wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
     AudioPolicyClientInterface* mClientInterface;
     const AudioSessionInfoProvider* mInfoProvider;
 };
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 92332fb..27bc4c6 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -21,6 +21,7 @@
 #include "AudioInputDescriptor.h"
 #include "IOProfile.h"
 #include "AudioGain.h"
+#include "AudioPolicyMix.h"
 #include "HwModule.h"
 #include <media/AudioPolicy.h>
 #include <policy.h>
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 294a2a6..d15ba4b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -19,6 +19,7 @@
 
 #include <AudioPolicyInterface.h>
 #include "AudioOutputDescriptor.h"
+#include "AudioPolicyMix.h"
 #include "IOProfile.h"
 #include "AudioGain.h"
 #include "Volume.h"
@@ -307,17 +308,18 @@
     } else {
         mGlobalRefCount += delta;
     }
+    sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
     if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
-        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
         {
-            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
                     MIX_STATE_MIXING);
         }
 
     } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
-        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
         {
-            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
                     MIX_STATE_IDLE);
         }
     }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 08930f1..327dc4d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -27,6 +27,10 @@
 
 namespace android {
 
+AudioPolicyMix::AudioPolicyMix(const AudioMix &mix) : AudioMix(mix)
+{
+}
+
 void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
 {
     mOutput = output;
@@ -42,16 +46,6 @@
     mOutput.clear();
 }
 
-void AudioPolicyMix::setMix(AudioMix &mix)
-{
-    mMix = mix;
-}
-
-android::AudioMix *AudioPolicyMix::getMix()
-{
-    return &mMix;
-}
-
 status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
 {
     const size_t SIZE = 256;
@@ -61,25 +55,25 @@
     snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
     result.append(buffer);
     std::string mixTypeLiteral;
-    if (!MixTypeConverter::toString(mMix.mMixType, mixTypeLiteral)) {
-        ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMix.mMixType);
+    if (!MixTypeConverter::toString(mMixType, mixTypeLiteral)) {
+        ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMixType);
         return BAD_VALUE;
     }
     snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
     result.append(buffer);
     std::string routeFlagLiteral;
-    RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
+    RouteFlagTypeConverter::maskToString(mRouteFlags, routeFlagLiteral);
     snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
     result.append(buffer);
     std::string deviceLiteral;
-    deviceToString(mMix.mDeviceType, deviceLiteral);
+    deviceToString(mDeviceType, deviceLiteral);
     snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
     result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
+    snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
     result.append(buffer);
 
     int indexCriterion = 0;
-    for (const auto &criterion : mMix.mCriteria) {
+    for (const auto &criterion : mCriteria) {
         snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
         result.append(buffer);
         std::string usageLiteral;
@@ -89,7 +83,7 @@
         }
         snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
         result.append(buffer);
-        if (mMix.mMixType == MIX_TYPE_RECORDERS) {
+        if (mMixType == MIX_TYPE_RECORDERS) {
             std::string sourceLiteral;
             if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
                 ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
@@ -120,12 +114,11 @@
         ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string());
         return BAD_VALUE;
     }
-    sp<AudioPolicyMix> policyMix = new AudioPolicyMix();
-    policyMix->setMix(mix);
+    sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
     add(address, policyMix);
 
     if (desc != 0) {
-        desc->mPolicyMix = policyMix->getMix();
+        desc->mPolicyMix = policyMix;
         policyMix->setOutput(desc);
     }
     return NO_ERROR;
@@ -171,8 +164,7 @@
     ALOGV("getOutputForAttr() querying %zu mixes:", size());
     desc = 0;
     for (size_t i = 0; i < size(); i++) {
-        sp<AudioPolicyMix> policyMix = valueAt(i);
-        AudioMix *mix = policyMix->getMix();
+        sp<AudioPolicyMix> mix = valueAt(i);
 
         if (mix->mMixType == MIX_TYPE_PLAYERS) {
             // TODO if adding more player rules (currently only 2), make rule handling "generic"
@@ -269,7 +261,7 @@
                       (hasUidExcludeRules && uidExclusionFound) ||
                       (hasUidMatchRules && !uidMatchFound))) {
                 ALOGV("\tgetOutputForAttr will use mix %zu", i);
-                desc = policyMix->getOutput();
+                desc = mix->getOutput();
             }
 
         } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
@@ -278,7 +270,7 @@
                     strncmp(attributes.tags + strlen("addr="),
                             mix->mDeviceAddress.string(),
                             AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
-                desc = policyMix->getOutput();
+                desc = mix->getOutput();
             }
         }
         if (desc != 0) {
@@ -289,12 +281,13 @@
     return BAD_VALUE;
 }
 
-audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                                        audio_devices_t availDevices,
-                                                                        AudioMix **policyMix)
+audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(
+        audio_source_t inputSource,
+        audio_devices_t availDevices,
+        sp<AudioPolicyMix> *policyMix)
 {
     for (size_t i = 0; i < size(); i++) {
-        AudioMix *mix = valueAt(i)->getMix();
+        AudioPolicyMix *mix = valueAt(i).get();
 
         if (mix->mMixType != MIX_TYPE_RECORDERS) {
             continue;
@@ -317,7 +310,8 @@
     return AUDIO_DEVICE_NONE;
 }
 
-status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix)
+status_t AudioPolicyMixCollection::getInputMixForAttr(
+        audio_attributes_t attr, sp<AudioPolicyMix> *policyMix)
 {
     if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
         return BAD_VALUE;
@@ -327,8 +321,7 @@
 #ifdef LOG_NDEBUG
     ALOGV("getInputMixForAttr looking for address %s\n  mixes available:", address.string());
     for (size_t i = 0; i < size(); i++) {
-            sp<AudioPolicyMix> policyMix = valueAt(i);
-            AudioMix *mix = policyMix->getMix();
+            sp<AudioPolicyMix> mix = valueAt(i);
             ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string());
     }
 #endif
@@ -339,13 +332,14 @@
         return BAD_VALUE;
     }
     sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
-    AudioMix *mix = audioPolicyMix->getMix();
 
-    if (mix->mMixType != MIX_TYPE_PLAYERS) {
+    if (audioPolicyMix->mMixType != MIX_TYPE_PLAYERS) {
         ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string());
         return BAD_VALUE;
     }
-    *policyMix = mix;
+    if (policyMix != nullptr) {
+        *policyMix = audioPolicyMix;
+    }
     return NO_ERROR;
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 7cda46b..694c3f2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -19,6 +19,7 @@
 
 #include <AudioPolicyInterface.h>
 #include "policy.h"
+#include "AudioPolicyMix.h"
 #include "AudioSession.h"
 #include "AudioGain.h"
 #include "TypeConverter.h"
@@ -36,7 +37,7 @@
                            audio_input_flags_t flags,
                            uid_t uid,
                            bool isSoundTrigger,
-                           AudioMix* policyMix,
+                           const sp<AudioPolicyMix> &policyMix,
                            AudioPolicyClientInterface *clientInterface) :
     mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
     mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
@@ -79,9 +80,10 @@
     if (event != RECORD_CONFIG_EVENT_NONE) {
         // Dynamic policy callback:
         // if input maps to a dynamic policy with an activity listener, notify of state change
-        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+        sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
+        if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
         {
-            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+            mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
                     (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
         }
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 9d618b0..2736fd4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1155,10 +1155,9 @@
     mOutputRoutes.incRouteActivity(session);
 
     audio_devices_t newDevice;
-    AudioMix *policyMix = NULL;
+    sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
     const char *address = NULL;
-    if (outputDesc->mPolicyMix != NULL) {
-        policyMix = outputDesc->mPolicyMix;
+    if (policyMix != NULL) {
         address = policyMix->mDeviceAddress.string();
         if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
             newDevice = policyMix->mDeviceType;
@@ -1353,12 +1352,13 @@
     if (outputDesc->mRefCount[stream] == 1) {
         // Automatically disable the remote submix input when output is stopped on a
         // re routing mix of type MIX_TYPE_RECORDERS
+        sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
         if (audio_is_remote_submix_device(outputDesc->mDevice) &&
-                outputDesc->mPolicyMix != NULL &&
-                outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
+                policyMix != NULL &&
+                policyMix->mMixType == MIX_TYPE_RECORDERS) {
             setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
                     AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                    outputDesc->mPolicyMix->mDeviceAddress,
+                    policyMix->mDeviceAddress,
                     "remote-submix");
         }
     }
@@ -1498,7 +1498,7 @@
     String8 address = String8("");
     audio_source_t halInputSource;
     audio_source_t inputSource = attr->source;
-    AudioMix *policyMix = NULL;
+    sp<AudioPolicyMix> policyMix;
     DeviceVector inputDevices;
 
     if (inputSource == AUDIO_SOURCE_DEFAULT) {
@@ -1639,7 +1639,7 @@
                                                         audio_source_t inputSource,
                                                         const audio_config_base_t *config,
                                                         audio_input_flags_t flags,
-                                                        AudioMix *policyMix)
+                                                        const sp<AudioPolicyMix> &policyMix)
 {
     audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
     audio_source_t halInputSource = inputSource;
@@ -2051,10 +2051,11 @@
         }
 
         if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
+            sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
             // if input maps to a dynamic policy with an activity listener, notify of state change
-            if ((inputDesc->mPolicyMix != NULL)
-                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
-                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
+            if ((policyMix != NULL)
+                    && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+                mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
                         MIX_STATE_MIXING);
             }
 
@@ -2069,10 +2070,10 @@
             // For remote submix (a virtual device), we open only one input per capture request.
             if (audio_is_remote_submix_device(inputDesc->mDevice)) {
                 String8 address = String8("");
-                if (inputDesc->mPolicyMix == NULL) {
+                if (policyMix == NULL) {
                     address = String8("0");
-                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
-                    address = inputDesc->mPolicyMix->mDeviceAddress;
+                } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
+                    address = policyMix->mDeviceAddress;
                 }
                 if (address != "") {
                     setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@@ -2120,10 +2121,11 @@
         if (inputDesc->isActive()) {
             setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
         } else {
+            sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
             // if input maps to a dynamic policy with an activity listener, notify of state change
-            if ((inputDesc->mPolicyMix != NULL)
-                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
-                mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
+            if ((policyMix != NULL)
+                    && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+                mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
                         MIX_STATE_IDLE);
             }
 
@@ -2131,10 +2133,10 @@
             // used by a policy mix of type MIX_TYPE_RECORDERS
             if (audio_is_remote_submix_device(inputDesc->mDevice)) {
                 String8 address = String8("");
-                if (inputDesc->mPolicyMix == NULL) {
+                if (policyMix == NULL) {
                     address = String8("0");
-                } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
-                    address = inputDesc->mPolicyMix->mDeviceAddress;
+                } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
+                    address = policyMix->mDeviceAddress;
                 }
                 if (address != "") {
                     setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@@ -4351,7 +4353,7 @@
                                   address.string());
                         }
                         policyMix->setOutput(desc);
-                        desc->mPolicyMix = policyMix->getMix();
+                        desc->mPolicyMix = policyMix;
 
                     } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
                                     hasPrimaryOutput()) {
@@ -5492,7 +5494,7 @@
 
 
 audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                                  AudioMix **policyMix)
+                                                                  sp<AudioPolicyMix> *policyMix)
 {
     audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
     audio_devices_t selectedDeviceFromMix =
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 48e0472..45dca2e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -658,7 +658,7 @@
                 audio_source_t inputSource,
                 const audio_config_base_t *config,
                 audio_input_flags_t flags,
-                AudioMix *policyMix);
+                const sp<AudioPolicyMix> &policyMix);
 
         // internal function to derive a stream type value from audio attributes
         audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
@@ -672,7 +672,7 @@
         // select input device corresponding to requested audio source and return associated policy
         // mix if any. Calls getDeviceForInputSource().
         audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                        AudioMix **policyMix = NULL);
+                                                      sp<AudioPolicyMix> *policyMix = NULL);
 
         // Called by setDeviceConnectionState().
         status_t setDeviceConnectionStateInt(audio_devices_t device,