Merge changes from topic "audio-pre-v5"

* changes:
  libaudiohal: EnumConverter renamed to EnumBitfield
  libaudiohal: Factorize with audio HAL utils
  libaudiohal: Factorize more between version
diff --git a/media/codec2/core/include/C2.h b/media/codec2/core/include/C2.h
index 8a55f8d..ef3466d 100644
--- a/media/codec2/core/include/C2.h
+++ b/media/codec2/core/include/C2.h
@@ -289,7 +289,7 @@
      * Convert to a smaller counter type. This is always safe.
      */
     template<typename U, typename E=typename std::enable_if<(sizeof(U) < sizeof(T))>::type>
-    inline operator c2_cntr_t<U>() {
+    inline constexpr operator c2_cntr_t<U>() {
         return c2_cntr_t<U>(mValue);
     }
 
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index df9aea6..8607ee1 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -2452,13 +2452,8 @@
 status_t AudioTrack::selectPresentation(int presentationId, int programId)
 {
     AutoMutex lock(mLock);
-    AudioParameter param = AudioParameter();
-    param.addInt(String8(AudioParameter::keyPresentationId), presentationId);
-    param.addInt(String8(AudioParameter::keyProgramId), programId);
-    ALOGV("%s(%d): PresentationId/ProgramId[%s]",
-            __func__, mId, param.toString().string());
-
-    return mAudioTrack->setParameters(param.toString());
+    ALOGV("%s(%d): PresentationId:%d ProgramId:%d", __func__, mId, presentationId, programId);
+    return mAudioTrack->selectPresentation(presentationId, programId);
 }
 
 VolumeShaper::Status AudioTrack::applyVolumeShaper(
diff --git a/media/libaudioclient/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
index adff057..83a568a 100644
--- a/media/libaudioclient/IAudioTrack.cpp
+++ b/media/libaudioclient/IAudioTrack.cpp
@@ -39,6 +39,7 @@
     PAUSE,
     ATTACH_AUX_EFFECT,
     SET_PARAMETERS,
+    SELECT_PRESENTATION,
     GET_TIMESTAMP,
     SIGNAL,
     APPLY_VOLUME_SHAPER,
@@ -127,6 +128,19 @@
         return status;
     }
 
+    /* Selects the presentation (if available) */
+    virtual status_t selectPresentation(int presentationId, int programId) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+        data.writeInt32(presentationId);
+        data.writeInt32(programId);
+        status_t status = remote()->transact(SELECT_PRESENTATION, data, &reply);
+        if (status == NO_ERROR) {
+            status = reply.readInt32();
+        }
+        return status;
+    }
+
     virtual status_t getTimestamp(AudioTimestamp& timestamp) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
@@ -239,6 +253,11 @@
             reply->writeInt32(setParameters(keyValuePairs));
             return NO_ERROR;
         } break;
+        case SELECT_PRESENTATION: {
+            CHECK_INTERFACE(IAudioTrack, data, reply);
+            reply->writeInt32(selectPresentation(data.readInt32(), data.readInt32()));
+            return NO_ERROR;
+        } break;
         case GET_TIMESTAMP: {
             CHECK_INTERFACE(IAudioTrack, data, reply);
             AudioTimestamp timestamp;
diff --git a/media/libaudioclient/include/media/IAudioTrack.h b/media/libaudioclient/include/media/IAudioTrack.h
index 94afe3c..06e786d 100644
--- a/media/libaudioclient/include/media/IAudioTrack.h
+++ b/media/libaudioclient/include/media/IAudioTrack.h
@@ -70,6 +70,9 @@
     /* Send parameters to the audio hardware */
     virtual status_t    setParameters(const String8& keyValuePairs) = 0;
 
+    /* Selects the presentation (if available) */
+    virtual status_t    selectPresentation(int presentationId, int programId) = 0;
+
     /* Return NO_ERROR if timestamp is valid.  timestamp is undefined otherwise. */
     virtual status_t    getTimestamp(AudioTimestamp& timestamp) = 0;
 
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index f0ca384..c7d9b62 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -19,6 +19,7 @@
 
 #include PATH(android/hardware/audio/FILE_VERSION/IStreamOutCallback.h)
 #include <hwbinder/IPCThreadState.h>
+#include <media/AudioParameter.h>
 #include <mediautils/SchedulingPolicyService.h>
 #include <utils/Log.h>
 
@@ -346,6 +347,24 @@
     return processReturn("setVolume", mStream->setVolume(left, right));
 }
 
+#if MAJOR_VERSION == 2
+status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+    if (mStream == 0) return NO_INIT;
+    std::vector<ParameterValue> parameters;
+    String8 halParameters;
+    parameters.push_back({AudioParameter::keyPresentationId, std::to_string(presentationId)});
+    parameters.push_back({AudioParameter::keyProgramId, std::to_string(programId)});
+    parametersToHal(hidl_vec<ParameterValue>(parameters), &halParameters);
+    return setParameters(halParameters);
+}
+#elif MAJOR_VERSION == 4
+status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+    if (mStream == 0) return NO_INIT;
+    return processReturn("selectPresentation",
+            mStream->selectPresentation(presentationId, programId));
+}
+#endif
+
 status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
     if (mStream == 0) return NO_INIT;
     *written = 0;
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index c7bfc45..f7b507e 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -128,6 +128,9 @@
     // Use this method in situations where audio mixing is done in the hardware.
     virtual status_t setVolume(float left, float right);
 
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId);
+
     // Write audio buffer to driver.
     virtual status_t write(const void *buffer, size_t bytes, size_t *written);
 
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
index b134f57..0aba7c1 100644
--- a/media/libaudiohal/impl/StreamHalLocal.cpp
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include <hardware/audio.h>
+#include <media/AudioParameter.h>
 #include <utils/Log.h>
 
 #include "DeviceHalLocal.h"
@@ -138,6 +139,13 @@
     return mStream->set_volume(mStream, left, right);
 }
 
+status_t StreamOutHalLocal::selectPresentation(int presentationId, int programId) {
+    AudioParameter param;
+    param.addInt(String8(AudioParameter::keyPresentationId), presentationId);
+    param.addInt(String8(AudioParameter::keyProgramId), programId);
+    return setParameters(param.toString());
+}
+
 status_t StreamOutHalLocal::write(const void *buffer, size_t bytes, size_t *written) {
     ssize_t writeResult = mStream->write(mStream, buffer, bytes);
     if (writeResult > 0) {
diff --git a/media/libaudiohal/impl/StreamHalLocal.h b/media/libaudiohal/impl/StreamHalLocal.h
index cea4229..4fd1960 100644
--- a/media/libaudiohal/impl/StreamHalLocal.h
+++ b/media/libaudiohal/impl/StreamHalLocal.h
@@ -103,6 +103,9 @@
     // Use this method in situations where audio mixing is done in the hardware.
     virtual status_t setVolume(float left, float right);
 
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId);
+
     // Write audio buffer to driver.
     virtual status_t write(const void *buffer, size_t bytes, size_t *written);
 
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index c969e28..bd71dc0 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -109,6 +109,9 @@
     // Use this method in situations where audio mixing is done in the hardware.
     virtual status_t setVolume(float left, float right) = 0;
 
+    // Selects the audio presentation (if available).
+    virtual status_t selectPresentation(int presentationId, int programId) = 0;
+
     // Write audio buffer to driver.
     virtual status_t write(const void *buffer, size_t bytes, size_t *written) = 0;
 
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
index 1860b0c..f01361b 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
@@ -322,7 +322,7 @@
 
     if (mLooper == NULL) {
         mLooper = new ALooper;
-        mLooper->setName("generic");
+        mLooper->setName("generic2");
         mLooper->start(false, /* runOnCallingThread */
                        true,  /* canCallJava */
                        PRIORITY_DEFAULT);
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
index 175be53..2ea55f6 100644
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
@@ -103,7 +103,7 @@
 void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
     if (mLiveLooper == NULL) {
         mLiveLooper = new ALooper;
-        mLiveLooper->setName("http live");
+        mLiveLooper->setName("http live2");
         mLiveLooper->start(false, /* runOnCallingThread */
                            true /* canCallJava */);
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index 5ea600f..6c4f0db 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -825,20 +825,31 @@
 
         case kWhatGetSelectedTrack:
         {
+            int32_t type32;
+            CHECK(msg->findInt32("type", (int32_t*)&type32));
+            media_track_type type = (media_track_type)type32;
+
+            size_t inbandTracks = 0;
             status_t err = INVALID_OPERATION;
+            ssize_t selectedTrack = -1;
             if (mCurrentSourceInfo.mSource != NULL) {
                 err = OK;
-
-                int32_t type32;
-                CHECK(msg->findInt32("type", (int32_t*)&type32));
-                media_track_type type = (media_track_type)type32;
-                ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
-
-                PlayerMessage* reply;
-                CHECK(msg->findPointer("reply", (void**)&reply));
-                reply->add_values()->set_int32_value(selectedTrack);
+                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
+                selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
             }
 
+            if (selectedTrack == -1 && mCCDecoder != NULL) {
+                err = OK;
+                selectedTrack = mCCDecoder->getSelectedTrack(type);
+                if (selectedTrack != -1) {
+                    selectedTrack += inbandTracks;
+                }
+            }
+
+            PlayerMessage* reply;
+            CHECK(msg->findPointer("reply", (void**)&reply));
+            reply->add_values()->set_int32_value(selectedTrack);
+
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
 
@@ -1719,7 +1730,7 @@
     notify->setInt32("generation", mRendererGeneration);
     mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
     mRendererLooper = new ALooper;
-    mRendererLooper->setName("NuPlayerRenderer");
+    mRendererLooper->setName("NuPlayer2Renderer");
     mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
     mRendererLooper->registerHandler(mRenderer);
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
index e215965..a9f2104 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
@@ -199,6 +199,18 @@
     return OK;
 }
 
+ssize_t NuPlayer2::CCDecoder::getSelectedTrack(media_track_type type) const {
+    if (mSelectedTrack != -1) {
+        CCTrack track = mTracks[mSelectedTrack];
+        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
+            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
+        }
+        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
+    }
+
+    return -1;
+}
+
 bool NuPlayer2::CCDecoder::isSelected() const {
     return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
 }
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
index 57d5ea2..97834d1 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
@@ -38,6 +38,7 @@
     size_t getTrackCount() const;
     sp<AMessage> getTrackInfo(size_t index) const;
     status_t selectTrack(size_t index, bool select);
+    ssize_t getSelectedTrack(media_track_type type) const;
     bool isSelected() const;
     void decode(const sp<ABuffer> &accessUnit);
     void display(int64_t timeUs);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
index 9c1988f..1f1b69e 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
@@ -38,7 +38,7 @@
     // Every decoder has its own looper because MediaCodec operations
     // are blocking, but NuPlayer2 needs asynchronous operations.
     mDecoderLooper = new ALooper;
-    mDecoderLooper->setName("NPDecoder");
+    mDecoderLooper->setName("NP2Decoder");
     mDecoderLooper->start(false, /* runOnCallingThread */
                           true,  /* canCallJava */
                           ANDROID_PRIORITY_AUDIO);
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
index 53c66c0..aed925b 100644
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
@@ -105,7 +105,7 @@
 
     if (mLooper == NULL) {
         mLooper = new ALooper;
-        mLooper->setName("rtsp");
+        mLooper->setName("rtsp2");
         mLooper->start();
 
         mLooper->registerHandler(this);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 0784939..3922767 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -659,20 +659,31 @@
 
         case kWhatGetSelectedTrack:
         {
+            int32_t type32;
+            CHECK(msg->findInt32("type", (int32_t*)&type32));
+            media_track_type type = (media_track_type)type32;
+
+            size_t inbandTracks = 0;
             status_t err = INVALID_OPERATION;
+            ssize_t selectedTrack = -1;
             if (mSource != NULL) {
                 err = OK;
-
-                int32_t type32;
-                CHECK(msg->findInt32("type", (int32_t*)&type32));
-                media_track_type type = (media_track_type)type32;
-                ssize_t selectedTrack = mSource->getSelectedTrack(type);
-
-                Parcel* reply;
-                CHECK(msg->findPointer("reply", (void**)&reply));
-                reply->writeInt32(selectedTrack);
+                inbandTracks = mSource->getTrackCount();
+                selectedTrack = mSource->getSelectedTrack(type);
             }
 
+            if (selectedTrack == -1 && mCCDecoder != NULL) {
+                err = OK;
+                selectedTrack = mCCDecoder->getSelectedTrack(type);
+                if (selectedTrack != -1) {
+                    selectedTrack += inbandTracks;
+                }
+            }
+
+            Parcel* reply;
+            CHECK(msg->findPointer("reply", (void**)&reply));
+            reply->writeInt32(selectedTrack);
+
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
index fb12360..ec30d0c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
@@ -200,6 +200,18 @@
     return OK;
 }
 
+ssize_t NuPlayer::CCDecoder::getSelectedTrack(media_track_type type) const {
+    if (mSelectedTrack != -1) {
+        CCTrack track = mTracks[mSelectedTrack];
+        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
+            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
+        }
+        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
+    }
+
+    return -1;
+}
+
 bool NuPlayer::CCDecoder::isSelected() const {
     return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
index f310f37..37b8230 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h
@@ -38,6 +38,7 @@
     size_t getTrackCount() const;
     sp<AMessage> getTrackInfo(size_t index) const;
     status_t selectTrack(size_t index, bool select);
+    ssize_t getSelectedTrack(media_track_type type) const;
     bool isSelected() const;
     void decode(const sp<ABuffer> &accessUnit);
     void display(int64_t timeUs);
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 610b961..17187a8 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -41,7 +41,7 @@
         ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
         ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
         ".avi", ".mpeg", ".mpg", ".awb", ".mpga", ".mov",
-        ".m4v", ".oga"
+        ".m4v", ".oga", ".m4r"
     };
     static const size_t kNumValidExtensions =
         sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
index 1f29185..a8e77c7 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
@@ -199,9 +199,8 @@
             }
 
             case KeyEvent.ACTION_UP: {
-                //TODO(b/119790339): Resolve hidden API usage. AudioManager.FLAG_FROM_KEY
-                final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE;
-                        //| AudioManager.FLAG_FROM_KEY;
+                final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
+                        | AudioManager.FLAG_FROM_KEY;
                 try {
                     mSessionBinder.adjustVolume("mContext.getOpPackageName()", mCbStub, true, 0,
                             flags);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index b6b3815..1b20693 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -553,6 +553,7 @@
         virtual void        pause();
         virtual status_t    attachAuxEffect(int effectId);
         virtual status_t    setParameters(const String8& keyValuePairs);
+        virtual status_t    selectPresentation(int presentationId, int programId);
         virtual media::VolumeShaper::Status applyVolumeShaper(
                 const sp<media::VolumeShaper::Configuration>& configuration,
                 const sp<media::VolumeShaper::Operation>& operation) override;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 53ea9a4..971f6a5 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -67,6 +67,7 @@
             bool        isStatic() const { return  mSharedBuffer.get() != nullptr; }
 
             status_t    setParameters(const String8& keyValuePairs);
+            status_t    selectPresentation(int presentationId, int programId);
             status_t    attachAuxEffect(int EffectId);
             void        setAuxBuffer(int EffectId, int32_t *buffer);
             int32_t     *auxBuffer() const { return mAuxBuffer; }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f833cf7..cec0819 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2413,6 +2413,14 @@
     return String8();
 }
 
+status_t AudioFlinger::DirectOutputThread::selectPresentation(int presentationId, int programId) {
+    Mutex::Autolock _l(mLock);
+    if (mOutput == nullptr || mOutput->stream == nullptr) {
+        return NO_INIT;
+    }
+    return mOutput->stream->selectPresentation(presentationId, programId);
+}
+
 void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 49fc234..7f3ea0f 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1199,6 +1199,8 @@
                        audio_io_handle_t id, audio_devices_t device, bool systemReady);
     virtual                 ~DirectOutputThread();
 
+                status_t    selectPresentation(int presentationId, int programId);
+
     // Thread virtuals
 
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index f2617ae..91a3286 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -326,6 +326,10 @@
     return mTrack->setParameters(keyValuePairs);
 }
 
+status_t AudioFlinger::TrackHandle::selectPresentation(int presentationId, int programId) {
+    return mTrack->selectPresentation(presentationId, programId);
+}
+
 VolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
         const sp<VolumeShaper::Configuration>& configuration,
         const sp<VolumeShaper::Operation>& operation) {
@@ -976,6 +980,19 @@
     }
 }
 
+status_t AudioFlinger::PlaybackThread::Track::selectPresentation(int presentationId,
+        int programId) {
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread == 0) {
+        ALOGE("thread is dead");
+        return FAILED_TRANSACTION;
+    } else if ((thread->type() == ThreadBase::DIRECT) || (thread->type() == ThreadBase::OFFLOAD)) {
+        DirectOutputThread *directOutputThread = static_cast<DirectOutputThread*>(thread.get());
+        return directOutputThread->selectPresentation(presentationId, programId);
+    }
+    return INVALID_OPERATION;
+}
+
 VolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
         const sp<VolumeShaper::Configuration>& configuration,
         const sp<VolumeShaper::Operation>& operation)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3909202..68858226 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -845,8 +845,9 @@
     // chosen by the engine if not.
     // FIXME: provide a more generic approach which is not device specific and move this back
     // to getOutputForDevice.
+    // TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
     if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
-        *stream == AUDIO_STREAM_MUSIC &&
+        (*stream == AUDIO_STREAM_MUSIC || attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
         audio_is_linear_pcm(config->format) &&
         isInCall()) {
         if (requestedDeviceId != AUDIO_PORT_HANDLE_NONE) {
@@ -935,7 +936,8 @@
     if (stream == AUDIO_STREAM_TTS) {
         *flags = AUDIO_OUTPUT_FLAG_TTS;
     } else if (stream == AUDIO_STREAM_VOICE_CALL &&
-               audio_is_linear_pcm(config->format)) {
+               audio_is_linear_pcm(config->format) &&
+               (*flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) == 0) {
         *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
                                        AUDIO_OUTPUT_FLAG_DIRECT);
         ALOGV("Set VoIP and Direct output flags for PCM format");
@@ -5897,18 +5899,8 @@
             // Add reported surround sound formats to enabled surround formats.
             for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
                 audio_format_t format = formats[formatIndex];
-                switch(format) {
-                    case AUDIO_FORMAT_AC3:
-                    case AUDIO_FORMAT_E_AC3:
-                    case AUDIO_FORMAT_DTS:
-                    case AUDIO_FORMAT_DTS_HD:
-                    case AUDIO_FORMAT_AAC_LC:
-                    case AUDIO_FORMAT_DOLBY_TRUEHD:
-                    case AUDIO_FORMAT_E_AC3_JOC:
-                        mSurroundFormats.insert(format);
-                        break;
-                    default:
-                        break;
+                if (mConfig.getSurroundFormats().count(format) != 0) {
+                    mSurroundFormats.insert(format);
                 }
             }
         }