Merge "audio policy: receive assistant and a11y service UIDs"
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp
index 38ff37f..d713d2d 100644
--- a/camera/VendorTagDescriptor.cpp
+++ b/camera/VendorTagDescriptor.cpp
@@ -411,6 +411,11 @@
     return res;
 }
 
+const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> &
+            VendorTagDescriptorCache::getVendorIdsAndTagDescriptors() {
+    return mVendorMap;
+}
+
 int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
     int ret = 0;
     auto desc = mVendorMap.find(id);
diff --git a/camera/include/camera/VendorTagDescriptor.h b/camera/include/camera/VendorTagDescriptor.h
index c718c93..6f55890 100644
--- a/camera/include/camera/VendorTagDescriptor.h
+++ b/camera/include/camera/VendorTagDescriptor.h
@@ -211,6 +211,9 @@
      */
     void dump(int fd, int verbosity, int indentation) const;
 
+    const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> &
+            getVendorIdsAndTagDescriptors();
+
   protected:
     std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> mVendorMap;
     struct vendor_tag_cache_ops mVendorCacheOps;
diff --git a/include/media/AudioPresentationInfo.h b/include/media/AudioPresentationInfo.h
deleted file mode 100644
index e91a992..0000000
--- a/include/media/AudioPresentationInfo.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AUDIO_PRESENTATION_INFO_H_
-#define AUDIO_PRESENTATION_INFO_H_
-
-#include <sstream>
-#include <stdint.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-enum mastering_indication {
-    MASTERING_NOT_INDICATED,
-    MASTERED_FOR_STEREO,
-    MASTERED_FOR_SURROUND,
-    MASTERED_FOR_3D,
-    MASTERED_FOR_HEADPHONE,
-};
-
-struct AudioPresentation : public RefBase {
-    int32_t mPresentationId;
-    int32_t mProgramId;
-    KeyedVector<String8, String8> mLabels;
-    String8 mLanguage;
-    int32_t mMasteringIndication;
-    bool mAudioDescriptionAvailable;
-    bool mSpokenSubtitlesAvailable;
-    bool mDialogueEnhancementAvailable;
-
-    AudioPresentation() {
-        mPresentationId = -1;
-        mProgramId = -1;
-        mLanguage = "";
-        mMasteringIndication = MASTERING_NOT_INDICATED;
-        mAudioDescriptionAvailable = false;
-        mSpokenSubtitlesAvailable = false;
-        mDialogueEnhancementAvailable = false;
-    }
-};
-
-typedef Vector<sp<AudioPresentation>> AudioPresentations;
-
-class AudioPresentationInfo : public RefBase {
- public:
-    AudioPresentationInfo();
-
-    ~AudioPresentationInfo();
-
-    void addPresentation(sp<AudioPresentation> presentation);
-
-    size_t countPresentations() const;
-
-    const sp<AudioPresentation> getPresentation(size_t index) const;
-
- private:
-    AudioPresentations mPresentations;
-};
-
-}  // namespace android
-
-#endif  // AUDIO_PRESENTATION_INFO_H_
diff --git a/media/codec2/Android.bp b/media/codec2/core/Android.bp
similarity index 71%
rename from media/codec2/Android.bp
rename to media/codec2/core/Android.bp
index 576677a..b723755 100644
--- a/media/codec2/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -1,3 +1,9 @@
+cc_library_headers {
+    name: "libcodec2_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+}
+
 cc_library_shared {
     name: "libcodec2",
     vendor_available: true,
@@ -9,22 +15,18 @@
         "-Werror",
     ],
 
-    include_dirs: [
-        "frameworks/native/include/media/hardware",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
     header_libs: [
+        "libcodec2_headers",
         "libhardware_headers",
         "libutils_headers",
+        "media_plugin_headers",
     ],
 
     export_header_lib_headers: [
+        "libcodec2_headers",
         "libhardware_headers",
         "libutils_headers",
+        "media_plugin_headers",
     ],
 
     sanitize: {
@@ -40,3 +42,4 @@
 
     ldflags: ["-Wl,-Bsymbolic"],
 }
+
diff --git a/media/codec2/C2.cpp b/media/codec2/core/C2.cpp
similarity index 100%
rename from media/codec2/C2.cpp
rename to media/codec2/core/C2.cpp
diff --git a/media/codec2/include/C2.h b/media/codec2/core/include/C2.h
similarity index 100%
rename from media/codec2/include/C2.h
rename to media/codec2/core/include/C2.h
diff --git a/media/codec2/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
similarity index 100%
rename from media/codec2/include/C2Buffer.h
rename to media/codec2/core/include/C2Buffer.h
diff --git a/media/codec2/include/C2BufferBase.h b/media/codec2/core/include/C2BufferBase.h
similarity index 100%
rename from media/codec2/include/C2BufferBase.h
rename to media/codec2/core/include/C2BufferBase.h
diff --git a/media/codec2/include/C2Component.h b/media/codec2/core/include/C2Component.h
similarity index 100%
rename from media/codec2/include/C2Component.h
rename to media/codec2/core/include/C2Component.h
diff --git a/media/codec2/include/C2Config.h b/media/codec2/core/include/C2Config.h
similarity index 100%
rename from media/codec2/include/C2Config.h
rename to media/codec2/core/include/C2Config.h
diff --git a/media/codec2/include/C2Enum.h b/media/codec2/core/include/C2Enum.h
similarity index 100%
rename from media/codec2/include/C2Enum.h
rename to media/codec2/core/include/C2Enum.h
diff --git a/media/codec2/include/C2Param.h b/media/codec2/core/include/C2Param.h
similarity index 100%
rename from media/codec2/include/C2Param.h
rename to media/codec2/core/include/C2Param.h
diff --git a/media/codec2/include/C2ParamDef.h b/media/codec2/core/include/C2ParamDef.h
similarity index 100%
rename from media/codec2/include/C2ParamDef.h
rename to media/codec2/core/include/C2ParamDef.h
diff --git a/media/codec2/include/C2Work.h b/media/codec2/core/include/C2Work.h
similarity index 100%
rename from media/codec2/include/C2Work.h
rename to media/codec2/core/include/C2Work.h
diff --git a/media/codec2/include/_C2MacroUtils.h b/media/codec2/core/include/_C2MacroUtils.h
similarity index 100%
rename from media/codec2/include/_C2MacroUtils.h
rename to media/codec2/core/include/_C2MacroUtils.h
diff --git a/media/codec2/include/android-C2Buffer.h b/media/codec2/core/include/android-C2Buffer.h
similarity index 100%
rename from media/codec2/include/android-C2Buffer.h
rename to media/codec2/core/include/android-C2Buffer.h
diff --git a/media/codec2/include/media/stagefright/codec2/1.0/InputSurface.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
similarity index 100%
rename from media/codec2/include/media/stagefright/codec2/1.0/InputSurface.h
rename to media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
diff --git a/media/codec2/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
similarity index 100%
rename from media/codec2/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
rename to media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
diff --git a/media/codec2/tests/Android.bp b/media/codec2/tests/Android.bp
index 5540f7b..fce6e21 100644
--- a/media/codec2/tests/Android.bp
+++ b/media/codec2/tests/Android.bp
@@ -6,10 +6,13 @@
     ],
 
     include_dirs: [
-        "frameworks/av/media/codec2/include",
         "frameworks/av/media/codec2/vndk/include",
     ],
 
+    header_libs: [
+        "libcodec2_headers",
+    ],
+
     // param tests must not depend on any codec2 libraries as all params should be templated
     shared_libs: [
     ],
@@ -57,8 +60,8 @@
         "C2ComponentInterface_test.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/native/include/media/openmax",
+    header_libs: [
+        "media_plugin_headers",
     ],
 
     shared_libs: [
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 5a7c98c..0eb90be 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -42,9 +42,9 @@
         "internal",
     ],
 
-    include_dirs: [
-        "frameworks/native/include/media/hardware",
-        "frameworks/av/media/codec2/include",
+    header_libs: [
+        "media_plugin_headers",
+        "libcodec2_headers",
     ],
 
     shared_libs: [
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index c3bdc92..337ff2a 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -38,6 +38,7 @@
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 #include <media/stagefright/foundation/ColorUtils.h>
@@ -2753,6 +2754,75 @@
     AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AC4);
     AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
     AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
+
+    AudioPresentationCollection presentations;
+    // translate the AC4 presentation information to audio presentations for this track
+    AC4DSIParser::AC4Presentations ac4Presentations = parser.getPresentations();
+    if (!ac4Presentations.empty()) {
+        for (const auto& ac4Presentation : ac4Presentations) {
+            auto& presentation = ac4Presentation.second;
+            if (!presentation.mEnabled) {
+                continue;
+            }
+            AudioPresentationV1 ap;
+            ap.mPresentationId = presentation.mGroupIndex;
+            ap.mProgramId = presentation.mProgramID;
+            ap.mLanguage = presentation.mLanguage;
+            if (presentation.mPreVirtualized) {
+                ap.mMasteringIndication = MASTERED_FOR_HEADPHONE;
+            } else {
+                switch (presentation.mChannelMode) {
+                    case AC4Parser::AC4Presentation::kChannelMode_Mono:
+                    case AC4Parser::AC4Presentation::kChannelMode_Stereo:
+                        ap.mMasteringIndication = MASTERED_FOR_STEREO;
+                        break;
+                    case AC4Parser::AC4Presentation::kChannelMode_3_0:
+                    case AC4Parser::AC4Presentation::kChannelMode_5_0:
+                    case AC4Parser::AC4Presentation::kChannelMode_5_1:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_34:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_34:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_52:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_52:
+                        ap.mMasteringIndication = MASTERED_FOR_SURROUND;
+                        break;
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_322:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_322:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_0_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_7_1_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_9_0_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_9_1_4:
+                    case AC4Parser::AC4Presentation::kChannelMode_22_2:
+                        ap.mMasteringIndication = MASTERED_FOR_3D;
+                        break;
+                    default:
+                        ALOGE("Invalid channel mode in AC4 presentation");
+                        return ERROR_MALFORMED;
+                }
+            }
+
+            ap.mAudioDescriptionAvailable = (presentation.mContentClassifier ==
+                    AC4Parser::AC4Presentation::kVisuallyImpaired);
+            ap.mSpokenSubtitlesAvailable = (presentation.mContentClassifier ==
+                    AC4Parser::AC4Presentation::kVoiceOver);
+            ap.mDialogueEnhancementAvailable = presentation.mHasDialogEnhancements;
+            if (!ap.mLanguage.empty()) {
+                ap.mLabels.emplace(ap.mLanguage, presentation.mDescription);
+            }
+            presentations.push_back(std::move(ap));
+        }
+    }
+
+    if (presentations.empty()) {
+        // Clear audio presentation info in metadata.
+        AMediaFormat_setBuffer(
+                mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, nullptr, 0);
+    } else {
+        std::ostringstream outStream(std::ios::out);
+        serializeAudioPresentations(presentations, &outStream);
+        AMediaFormat_setBuffer(
+                mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+                outStream.str().data(), outStream.str().size());
+    }
     return OK;
 }
 
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index a74ddaa..605b13a 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -272,9 +272,6 @@
 
     off64_t size;
     if (mDataSource->getSize(&size) == OK && (haveAudio || haveVideo)) {
-        sp<AnotherPacketSource> impl = haveVideo
-                ? mParser->getSource(ATSParser::VIDEO)
-                : mParser->getSource(ATSParser::AUDIO);
         size_t prevSyncSize = 1;
         int64_t durationUs = -1;
         List<int64_t> durations;
@@ -308,17 +305,32 @@
                 }
             }
         }
-        status_t err;
-        int64_t bufferedDurationUs;
-        bufferedDurationUs = impl->getBufferedDurationUs(&err);
-        if (err == ERROR_END_OF_STREAM) {
-            durationUs = bufferedDurationUs;
+
+        bool found = false;
+        for (int i = 0; i < ATSParser::NUM_SOURCE_TYPES; ++i) {
+            ATSParser::SourceType type = static_cast<ATSParser::SourceType>(i);
+            sp<AnotherPacketSource> impl = mParser->getSource(type);
+            if (impl == NULL) {
+                continue;
+            }
+
+            int64_t trackDurationUs = durationUs;
+
+            status_t err;
+            int64_t bufferedDurationUs = impl->getBufferedDurationUs(&err);
+            if (err == ERROR_END_OF_STREAM) {
+                trackDurationUs = bufferedDurationUs;
+            }
+            if (trackDurationUs > 0) {
+                ALOGV("[SourceType%d] durationUs=%" PRId64 "", type, trackDurationUs);
+                const sp<MetaData> meta = impl->getFormat();
+                meta->setInt64(kKeyDuration, trackDurationUs);
+                impl->setFormat(meta);
+
+                found = true;
+            }
         }
-        if (durationUs > 0) {
-            const sp<MetaData> meta = impl->getFormat();
-            meta->setInt64(kKeyDuration, durationUs);
-            impl->setFormat(meta);
-        } else {
+        if (!found) {
             estimateDurationsFromTimesUsAtEnd();
         }
     }
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 96fccae..df9aea6 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -811,12 +811,9 @@
         if (!isOffloaded_l()) {
             t->pause();
         } else if (mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK) {
-            const sp<AudioTrackThread> t = mAudioTrackThread;
-            if (t != 0) {
-                // causes wake up of the playback thread, that will callback the client for
-                // EVENT_STREAM_END in processAudioBuffer()
-                t->wake();
-            }
+            // causes wake up of the playback thread, that will callback the client for
+            // EVENT_STREAM_END in processAudioBuffer()
+            t->wake();
         }
     } else {
         setpriority(PRIO_PROCESS, 0, mPreviousPriority);
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
index 72efcdf..9f2deda 100644
--- a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
@@ -225,6 +225,9 @@
 
     // Key for ALAC Magic Cookie
     kKeyAlacMagicCookie  = 'almc', // raw data
+
+    // AC-4 AudioPresentationInfo
+    kKeyAudioPresentationInfo = 'audP',  // raw data
 };
 
 enum {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index d96d358..cc5b7da 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -96,7 +96,6 @@
         "AHierarchicalStateMachine.cpp",
         "AMRWriter.cpp",
         "AudioPlayer.cpp",
-        "AudioPresentationInfo.cpp",
         "AudioSource.cpp",
         "BufferImpl.cpp",
         "CallbackDataSource.cpp",
@@ -207,6 +206,12 @@
         "include",
     ],
 
+    // This is needed to make sure libcodec2 exists in all devices.
+    // TODO: Remove this once the public CCodec is enabled.
+    required: [
+        "libcodec2",
+    ],
+
     cflags: [
         "-Wno-multichar",
         "-Werror",
diff --git a/media/libstagefright/AudioPresentationInfo.cpp b/media/libstagefright/AudioPresentationInfo.cpp
deleted file mode 100644
index 86e1859..0000000
--- a/media/libstagefright/AudioPresentationInfo.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "AudioPresentationInfo"
-
-#include <media/AudioPresentationInfo.h>
-
-namespace android {
-
-AudioPresentationInfo::AudioPresentationInfo() {
-}
-
-AudioPresentationInfo::~AudioPresentationInfo() {
-    mPresentations.clear();
-}
-
-void AudioPresentationInfo::addPresentation(sp<AudioPresentation> presentation) {
-    mPresentations.push(presentation);
-}
-
-size_t AudioPresentationInfo::countPresentations() const {
-    return mPresentations.size();
-}
-
-// Returns an AudioPresentation for the given valid index
-// index must be >=0 and < countPresentations()
-const sp<AudioPresentation> AudioPresentationInfo::getPresentation(size_t index) const {
-    return mPresentations[index];
-}
-
-}  // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 8f1dd36..318c1eb 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -18,6 +18,8 @@
 #define LOG_TAG "MediaExtractorFactory"
 #include <utils/Log.h>
 
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
 #include <binder/IServiceManager.h>
 #include <media/DataSource.h>
 #include <media/MediaAnalyticsItem.h>
@@ -353,18 +355,29 @@
 status_t MediaExtractorFactory::dump(int fd, const Vector<String16>&) {
     Mutex::Autolock autoLock(gPluginMutex);
     String8 out;
-    out.append("Available extractors:\n");
-    if (gPluginsRegistered) {
-        for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
-            out.appendFormat("  %25s: plugin_version(%d), uuid(%s), version(%u), path(%s)\n",
-                    (*it)->def.extractor_name,
-                    (*it)->def.def_version,
-                    (*it)->uuidString.c_str(),
-                    (*it)->def.extractor_version,
-                    (*it)->libPath.c_str());
-        }
+
+    const IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
+        // dumpExtractors() will append the following string.
+        // out.appendFormat("Permission Denial: "
+        //        "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid);
+        ALOGE("Permission Denial: can't dump MediaExtractor from pid=%d, uid=%d", pid, uid);
     } else {
-        out.append("  (no plugins registered)\n");
+        out.append("Available extractors:\n");
+        if (gPluginsRegistered) {
+            for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
+                out.appendFormat("  %25s: plugin_version(%d), uuid(%s), version(%u), path(%s)\n",
+                        (*it)->def.extractor_name,
+                    (*it)->def.def_version,
+                        (*it)->uuidString.c_str(),
+                        (*it)->def.extractor_version,
+                        (*it)->libPath.c_str());
+            }
+        } else {
+            out.append("  (no plugins registered)\n");
+        }
     }
     write(fd, out.string(), out.size());
     return OK;
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index f94648c..f5178dd 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -794,4 +794,32 @@
     return false;
 }
 
+// Return OK if we have received an audio presentation info.
+// Return ERROR_UNSUPPORTED if the track has no audio presentation.
+// Return INVALID_OPERATION if audio presentation metadata version does not match.
+status_t NuMediaExtractor::getAudioPresentations(
+        size_t trackIndex, AudioPresentationCollection *presentations) const {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mImpl == NULL) {
+        return -EINVAL;
+    }
+
+    if (trackIndex >= mImpl->countTracks()) {
+        return -ERANGE;
+    }
+
+    sp<MetaData> meta = mImpl->getTrackMetaData(trackIndex);
+
+    uint32_t type;
+    const void *data;
+    size_t size;
+    if (meta != NULL && meta->findData(kKeyAudioPresentationInfo, &type, &data, &size)) {
+        std::istringstream inStream(std::string(static_cast<const char*>(data), size));
+        return deserializeAudioPresentations(&inStream, presentations);
+    }
+    ALOGE("Source does not contain any audio presentation");
+    return ERROR_UNSUPPORTED;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 4aee9d5..53c32b2 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -615,6 +615,7 @@
 static std::vector<std::pair<const char *, uint32_t>> bufferMappings {
     {
         { "albumart", kKeyAlbumArt },
+        { "audio-presentation-info", kKeyAudioPresentationInfo },
         { "pssh", kKeyPssh },
         { "crypto-iv", kKeyCryptoIV },
         { "crypto-key", kKeyCryptoKey },
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
index a75483a..3d10086 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
@@ -617,6 +617,7 @@
     return;
 }
 
+__attribute__((no_sanitize("signed-integer-overflow")))
 void idctrow_intra(
     int16 *blk, PIXEL *comp, int width
 )
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 5b7961d..861528e 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -61,6 +61,7 @@
         "AMessage.cpp",
         "AString.cpp",
         "AStringUtils.cpp",
+        "AudioPresentationInfo.cpp",
         "ByteUtils.cpp",
         "ColorUtils.cpp",
         "MediaDefs.cpp",
diff --git a/media/libstagefright/foundation/AudioPresentationInfo.cpp b/media/libstagefright/foundation/AudioPresentationInfo.cpp
new file mode 100644
index 0000000..4b8e969
--- /dev/null
+++ b/media/libstagefright/foundation/AudioPresentationInfo.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "AudioPresentationInfo"
+
+#include <vector>
+
+#include "AudioPresentationInfo.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+void serializeAudioPresentations(const AudioPresentationCollection& presentations,
+        std::ostream* serializedOutput) {
+    uint32_t numPresentations = presentations.size();
+    serializedOutput->write(reinterpret_cast<char*>(&numPresentations), sizeof(numPresentations));
+    for (const auto& ap : presentations) {
+        if (ap.mVersion == PRESENTATION_VERSION_1) {
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mVersion)),
+                    sizeof(ap.mVersion));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mPresentationId)),
+                    sizeof(ap.mPresentationId));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mProgramId)),
+                    sizeof(ap.mProgramId));
+
+            uint32_t numLabels = ap.mLabels.size();
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&numLabels)),
+                    sizeof(numLabels));
+            for (const auto& label : ap.mLabels) {
+                uint32_t labelKeySize = label.first.size();
+                serializedOutput->write(
+                        const_cast<char*>(reinterpret_cast<const char*>(&labelKeySize)),
+                        sizeof(labelKeySize));
+                serializedOutput->write(label.first.c_str(), labelKeySize);
+
+                uint32_t labelValSize = label.second.size();
+                serializedOutput->write(
+                        const_cast<char*>(reinterpret_cast<const char*>(&labelValSize)),
+                        sizeof(labelValSize));
+                serializedOutput->write(label.second.c_str(), labelValSize);
+            }
+
+            uint32_t langSize = ap.mLanguage.size();
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&langSize)),
+                    sizeof(langSize));
+            serializedOutput->write(ap.mLanguage.c_str(), langSize);
+
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mMasteringIndication)),
+                    sizeof(ap.mMasteringIndication));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mAudioDescriptionAvailable)),
+                    sizeof(ap.mAudioDescriptionAvailable));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mSpokenSubtitlesAvailable)),
+                    sizeof(ap.mSpokenSubtitlesAvailable));
+            serializedOutput->write(
+                    const_cast<char*>(reinterpret_cast<const char*>(&ap.mDialogueEnhancementAvailable)),
+                    sizeof(ap.mDialogueEnhancementAvailable));
+        }
+    }
+}
+
+status_t deserializeAudioPresentations(std::istream* serializedInput,
+        AudioPresentationCollection *presentations) {
+    uint32_t numPresentations;
+    serializedInput->read(reinterpret_cast<char*>(&numPresentations), sizeof(numPresentations));
+    for (uint32_t i = 0; i < numPresentations; ++i) {
+        uint32_t version;
+        serializedInput->read(reinterpret_cast<char*>(&version), sizeof(version));
+        if (version == PRESENTATION_VERSION_1) {
+            AudioPresentationV1 ap;
+            serializedInput->read(
+                    reinterpret_cast<char*>(&ap.mPresentationId),
+                    sizeof(ap.mPresentationId));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mProgramId), sizeof(ap.mProgramId));
+
+            uint32_t numLabels;
+            serializedInput->read(reinterpret_cast<char*>(&numLabels), sizeof(numLabels));
+            for (uint32_t j = 0; j < numLabels; ++j) {
+                uint32_t labelKeySize;
+                serializedInput->read(reinterpret_cast<char*>(&labelKeySize), sizeof(labelKeySize));
+                std::vector<char> labelKey(labelKeySize);
+                serializedInput->read(labelKey.data(), labelKeySize);
+
+                uint32_t labelValSize;
+                serializedInput->read(reinterpret_cast<char*>(&labelValSize), sizeof(labelValSize));
+                std::vector<char> labelVal(labelValSize);
+                serializedInput->read(labelVal.data(), labelValSize);
+                ap.mLabels.emplace(
+                        std::string(reinterpret_cast<char*>(labelKey.data()), labelKeySize),
+                        std::string(reinterpret_cast<char*>(labelVal.data()), labelValSize));
+            }
+            uint32_t languageSize;
+            serializedInput->read(reinterpret_cast<char*>(&languageSize), sizeof(languageSize));
+            std::vector<char> language(languageSize);
+            serializedInput->read(language.data(), languageSize);
+            ap.mLanguage = std::string(reinterpret_cast<char*>(language.data()), languageSize);
+            serializedInput->read(reinterpret_cast<char*>(&ap.mMasteringIndication),
+                                 sizeof(ap.mMasteringIndication));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mAudioDescriptionAvailable),
+                                 sizeof(ap.mAudioDescriptionAvailable));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mSpokenSubtitlesAvailable),
+                                 sizeof(ap.mSpokenSubtitlesAvailable));
+            serializedInput->read(reinterpret_cast<char*>(&ap.mDialogueEnhancementAvailable),
+                                 sizeof(ap.mDialogueEnhancementAvailable));
+            presentations->push_back(std::move(ap));
+        } else {
+            ALOGE("Audio presentation info version is not supported");
+            return INVALID_OPERATION;
+        }
+    }
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
new file mode 100644
index 0000000..4bd4d9f
--- /dev/null
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_PRESENTATION_INFO_H_
+#define AUDIO_PRESENTATION_INFO_H_
+
+#include <map>
+#include <sstream>
+#include <stdint.h>
+#include <vector>
+
+#include <utils/Errors.h>
+
+namespace android {
+
+enum AudioPresentationVersion {
+    PRESENTATION_VERSION_UNDEFINED = 0,
+    PRESENTATION_VERSION_1,
+};
+
+enum MasteringIndication {
+    MASTERING_NOT_INDICATED,
+    MASTERED_FOR_STEREO,
+    MASTERED_FOR_SURROUND,
+    MASTERED_FOR_3D,
+    MASTERED_FOR_HEADPHONE,
+};
+
+struct AudioPresentation {
+    uint32_t mVersion = PRESENTATION_VERSION_UNDEFINED;
+    int32_t mPresentationId = -1;
+    int32_t mProgramId = -1;
+    std::map<std::string, std::string> mLabels;
+    std::string mLanguage;
+    MasteringIndication mMasteringIndication = MASTERING_NOT_INDICATED;
+    bool mAudioDescriptionAvailable = false;
+    bool mSpokenSubtitlesAvailable = false;
+    bool mDialogueEnhancementAvailable = false;
+};
+
+struct AudioPresentationV1 : public AudioPresentation {
+    AudioPresentationV1() {
+        mVersion = PRESENTATION_VERSION_1;
+    }
+};
+
+typedef std::vector<AudioPresentation> AudioPresentationCollection;
+
+void serializeAudioPresentations(const AudioPresentationCollection& presentations,
+                                               std::ostream* serializedOutput);
+status_t deserializeAudioPresentations(std::istream* serializedInput,
+                                                AudioPresentationCollection *presentations);
+}  // namespace android
+
+#endif  // AUDIO_PRESENTATION_INFO_H_
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 641ccfa..8dc8d38 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -20,6 +20,7 @@
 #include <list>
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <media/IMediaExtractor.h>
 #include <media/MediaSource.h>
 #include <utils/Errors.h>
@@ -95,6 +96,9 @@
 
     bool getCachedDuration(int64_t *durationUs, bool *eos) const;
 
+    status_t getAudioPresentations(size_t trackIdx,
+            AudioPresentationCollection *presentations) const;
+
 protected:
     virtual ~NuMediaExtractor();
 
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index aa4a4db..cf93fcf 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -210,6 +210,7 @@
     sp<ABuffer> mDescrambledBuffer;
     List<SubSampleInfo> mSubSamples;
     sp<IDescrambler> mDescrambler;
+    AudioPresentationCollection mAudioPresentations;
 
     // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
     // another payload. event is set if the flushed payload is PES with a sync
@@ -525,6 +526,8 @@
 
         CADescriptor streamCA;
         info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;
+
+        info.mAudioPresentations.clear();
         bool hasStreamCA = false;
         while (ES_info_length > 2 && infoBytesRemaining >= 0) {
             unsigned descriptor_tag = br->getBits(8);
@@ -549,12 +552,94 @@
                        descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
                 unsigned descTagExt = br->getBits(8);
                 ALOGV("      tag_ext = 0x%02x", descTagExt);
-                if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
-                    info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
-                }
                 ES_info_length -= descriptor_length;
                 descriptor_length--;
-                br->skipBits(descriptor_length * 8);
+                // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
+                // audio.
+                if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
+                    info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
+                    br->skipBits(descriptor_length * 8);
+                } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
+                           descriptor_length >= 1) {
+                    // DVB BlueBook A038 Table 110
+                    unsigned num_preselections = br->getBits(5);
+                    br->skipBits(3);  // reserved
+                    for (unsigned i = 0; i < num_preselections; ++i) {
+                        if (br->numBitsLeft() < 16) {
+                            ALOGE("Not enough data left in bitreader!");
+                            return ERROR_MALFORMED;
+                        }
+                        AudioPresentationV1 ap;
+                        ap.mPresentationId = br->getBits(5);  // preselection_id
+
+                        // audio_rendering_indication
+                        ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
+                        ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
+                        ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
+                        ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);
+
+                        bool interactivity_enabled = (br->getBits(1) == 1);
+                        MY_LOGV("      interactivity_enabled = %d", interactivity_enabled);
+
+                        bool language_code_present = (br->getBits(1) == 1);
+                        bool text_label_present = (br->getBits(1) == 1);
+
+                        bool multi_stream_info_present = (br->getBits(1) == 1);
+                        bool future_extension = (br->getBits(1) == 1);
+                        if (language_code_present) {
+                            if (br->numBitsLeft() < 24) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            char language[4];
+                            language[0] = br->getBits(8);
+                            language[1] = br->getBits(8);
+                            language[2] = br->getBits(8);
+                            language[3] = 0;
+                            ap.mLanguage = String8(language);
+                        }
+
+                        // This maps the presentation id to the message id in the
+                        // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
+                        if (text_label_present) {
+                            if (br->numBitsLeft() < 8) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            unsigned message_id = br->getBits(8);
+                            MY_LOGV("      message_id = %u", message_id);
+                        }
+
+                        if (multi_stream_info_present) {
+                            if (br->numBitsLeft() < 8) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            unsigned num_aux_components = br->getBits(3);
+                            br->skipBits(5);  // reserved
+                            if (br->numBitsLeft() < (num_aux_components * 8)) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(num_aux_components * 8);  // component_tag
+                        }
+                        if (future_extension) {
+                            if (br->numBitsLeft() < 8) {
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(3);  // reserved
+                            unsigned future_extension_length = br->getBits(5);
+                            if (br->numBitsLeft() < (future_extension_length * 8)) {
+                                ALOGE("Not enough data left in bitreader!");
+                                return ERROR_MALFORMED;
+                            }
+                            br->skipBits(future_extension_length * 8);  // future_extension_byte
+                        }
+                        info.mAudioPresentations.push_back(std::move(ap));
+                    }
+                } else {
+                    br->skipBits(descriptor_length * 8);
+                }
             } else {
                 ES_info_length -= descriptor_length;
                 br->skipBits(descriptor_length * 8);
@@ -754,7 +839,8 @@
       mEOSReached(false),
       mPrevPTS(0),
       mQueue(NULL),
-      mScrambled(info.mCADescriptor.mSystemID >= 0) {
+      mScrambled(info.mCADescriptor.mSystemID >= 0),
+      mAudioPresentations(info.mAudioPresentations) {
     mSampleEncrypted =
             mStreamType == STREAMTYPE_H264_ENCRYPTED ||
             mStreamType == STREAMTYPE_AAC_ENCRYPTED  ||
@@ -1633,6 +1719,7 @@
                 }
                 mSource = new AnotherPacketSource(meta);
                 mSource->queueAccessUnit(accessUnit);
+                mSource->convertAudioPresentationInfoToMetadata(mAudioPresentations);
                 ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
                         mElementaryPID, mStreamType);
             }
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 9ece21e..0ff2d7e 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -23,6 +23,7 @@
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AudioPresentationInfo.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 #include <utils/RefBase.h>
@@ -163,7 +164,7 @@
     };
 
     enum {
-        // From ISO/IEC 13818-1: 2007 (E), Table 2-29
+        // From ISO/IEC 13818-1: 2007 (E), Table 2-45
         DESCRIPTOR_CA                   = 0x09,
 
         // DVB BlueBook A038 Table 12
@@ -172,8 +173,9 @@
 
     // DVB BlueBook A038 Table 109
     enum {
-        EXT_DESCRIPTOR_DVB_AC4              = 0x15,
-        EXT_DESCRIPTOR_DVB_RESERVED_MAX     = 0x7F,
+        EXT_DESCRIPTOR_DVB_AC4                  = 0x15,
+        EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION   = 0x19,
+        EXT_DESCRIPTOR_DVB_RESERVED_MAX         = 0x7F,
     };
 
 protected:
@@ -196,6 +198,7 @@
         unsigned mTypeExt;
         unsigned mPID;
         CADescriptor mCADescriptor;
+        AudioPresentationCollection mAudioPresentations;
     };
 
     sp<CasManager> mCasManager;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 9e154a3..e2c5031 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -697,4 +697,23 @@
     return firstMeta;
 }
 
+void AnotherPacketSource::convertAudioPresentationInfoToMetadata(
+        const AudioPresentationCollection& presentations) {
+    sp<MetaData> meta = getFormat();
+    if (meta == NULL) {
+        return;
+    }
+    if (presentations.empty()) {
+        // Clear audio presentation info in metadata.
+        Mutex::Autolock autoLock(mLock);
+        meta->remove(kKeyAudioPresentationInfo);
+    } else {
+        std::ostringstream outStream(std::ios::out);
+        serializeAudioPresentations(presentations, &outStream);
+        Mutex::Autolock autoLock(mLock);
+        meta->setData(kKeyAudioPresentationInfo, MetaData::TYPE_NONE,
+                outStream.str().data(), outStream.str().size());
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index f4a6acb..57a6c33 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -85,6 +85,8 @@
     void trimBuffersAfterMeta(const sp<AMessage> &meta);
     sp<AMessage> trimBuffersBeforeMeta(const sp<AMessage> &meta);
 
+    void convertAudioPresentationInfoToMetadata(const AudioPresentationCollection &presentations);
+
 protected:
     virtual ~AnotherPacketSource();
 
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index b282ed8..bf9725c 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -272,6 +272,7 @@
 EXPORT const char* AMEDIAFORMAT_KEY_ALBUMART = "albumart";
 EXPORT const char* AMEDIAFORMAT_KEY_ALBUMARTIST = "albumartist";
 EXPORT const char* AMEDIAFORMAT_KEY_ARTIST = "artist";
+EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO = "audio-presentation-info";
 EXPORT const char* AMEDIAFORMAT_KEY_AUDIO_SESSION_ID = "audio-session-id";
 EXPORT const char* AMEDIAFORMAT_KEY_AUTHOR = "author";
 EXPORT const char* AMEDIAFORMAT_KEY_BITRATE_MODE = "bitrate-mode";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 89cfd5e..658cbac 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -180,6 +180,7 @@
 extern const char* AMEDIAFORMAT_KEY_ALBUMART __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_ALBUMARTIST __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_ARTIST __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_AUTHOR __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_BITS_PER_SAMPLE __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER __INTRODUCED_IN(29);
diff --git a/packages/MediaComponents/apex/java/android/media/MediaUtils.java b/packages/MediaComponents/apex/java/android/media/MediaUtils.java
deleted file mode 100644
index 0f0cb00..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaUtils.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package android.media;
-
-import android.view.KeyEvent;
-
-/**
- * @hide
- */
-public class MediaUtils {
-
-    /**
-     * Adjusting the volume due to a hardware key press.
-     * (Copied version of hidden AudioManager.FLAG_FROM_KEY)
-     */
-    public static final int AUDIO_MANAGER_FLAG_FROM_KEY = 1 << 12;
-
-    // Keep sync with KeyEvent#isMediaKey().
-    public static boolean isMediaKey(int keyCode) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_MEDIA_PLAY:
-            case KeyEvent.KEYCODE_MEDIA_PAUSE:
-            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-            case KeyEvent.KEYCODE_MUTE:
-            case KeyEvent.KEYCODE_HEADSETHOOK:
-            case KeyEvent.KEYCODE_MEDIA_STOP:
-            case KeyEvent.KEYCODE_MEDIA_NEXT:
-            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-            case KeyEvent.KEYCODE_MEDIA_REWIND:
-            case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                return true;
-        }
-        return false;
-    }
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
index fab57e3..1f29185 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
@@ -25,7 +25,6 @@
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.MediaMetadata;
-import android.media.MediaUtils;
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.net.Uri;
@@ -150,9 +149,12 @@
         if (keyEvent == null) {
             throw new IllegalArgumentException("KeyEvent may not be null");
         }
-        if (!MediaUtils.isMediaKey(keyEvent.getKeyCode())) {
+        //TODO(b/119789707): Resolve hidden API usage: KeyEvent#isMediaKey
+        /*
+        if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
             return false;
         }
+        */
         try {
             //TODO(b/119748678): Resolve mContext.getOpPackageName() through this file.
             // Temporarilly it's replaced with "mContext.getOpPackageName()" for compiling.
@@ -197,8 +199,9 @@
             }
 
             case KeyEvent.ACTION_UP: {
-                final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
-                        | MediaUtils.AUDIO_MANAGER_FLAG_FROM_KEY;
+                //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;
                 try {
                     mSessionBinder.adjustVolume("mContext.getOpPackageName()", mCbStub, true, 0,
                             flags);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index e9e1a22..3909202 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -15,7 +15,12 @@
  */
 
 #define LOG_TAG "APM_AudioPolicyManager"
-//#define LOG_NDEBUG 0
+
+// Need to keep the log statements even in production builds
+// to enable VERBOSE logging dynamically.
+// You can enable VERBOSE logging as follows:
+// adb shell setprop log.tag.APM_AudioPolicyManager V
+#define LOG_NDEBUG 0
 
 //#define VERY_VERBOSE_LOGGING
 #ifdef VERY_VERBOSE_LOGGING
@@ -4071,6 +4076,9 @@
         status = NO_INIT;
     }
 
+    // Silence ALOGV statements
+    property_set("log.tag." LOG_TAG, "D");
+
     updateDevicesAndOutputs();
     return status;
 }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 3951479..32b07fa 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -190,7 +190,9 @@
 
     for (auto& cameraId : deviceIds) {
         String8 id8 = String8(cameraId.c_str());
-        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+        if (getCameraState(id8) == nullptr) {
+            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+        }
     }
 
     return OK;
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 97f7fdc..5029d4b 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -490,7 +490,6 @@
     ATRACE_CALL();
     SharedParameters::Lock l(client->getParameters());
     Vector<int32_t> outputStreams;
-    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
 
     /**
      * Set up output streams in the request
@@ -520,7 +519,6 @@
 
     if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
         outputStreams.push(client->getRecordingStreamId());
-        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
     }
 
     res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
@@ -530,10 +528,6 @@
                 &mCaptureId, 1);
     }
     if (res == OK) {
-        res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT,
-                &captureIntent, 1);
-    }
-    if (res == OK) {
         res = mCaptureRequest.sort();
     }
 
@@ -683,6 +677,8 @@
         sp<Camera2Client> &client) {
     ATRACE_CALL();
     status_t res;
+    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+
     if (mCaptureRequest.entryCount() == 0) {
         res = client->getCameraDevice()->createDefaultRequest(
                 CAMERA2_TEMPLATE_STILL_CAPTURE,
@@ -695,6 +691,16 @@
         }
     }
 
+    if (params.state == Parameters::VIDEO_SNAPSHOT) {
+        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+    }
+    res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT, &captureIntent, 1);
+    if (res != OK) {
+        ALOGE("%s: Camera %d: Unable to update capture intent: %s (%d)",
+                __FUNCTION__, client->getCameraId(), strerror(-res), res);
+        return res;
+    }
+
     res = params.updateRequest(&mCaptureRequest);
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to update common entries of capture "
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 32952cc..856af13 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3903,6 +3903,7 @@
 }
 
 void Camera3Device::HalInterface::clear() {
+    mHidlSession_3_5.clear();
     mHidlSession_3_4.clear();
     mHidlSession_3_3.clear();
     mHidlSession.clear();
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 31bdf6d..48f1d37 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -40,9 +40,11 @@
 using device::V2_0::implementation::H2BCameraDeviceCallbacks;
 using device::V2_0::implementation::HidlCameraDeviceUser;
 using service::V2_0::implementation::H2BCameraServiceListener;
-using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
-using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
-using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
+using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
+using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
+using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
+using HProviderIdAndVendorTagSections =
+        frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
 
 sp<HidlCameraService> gHidlCameraService;
 
@@ -215,39 +217,50 @@
 }
 
 Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
-    hidl_vec<HVendorTagSection> hVendorTagSections;
-    // TODO: Could this be just created on the stack since we don't set it to
-    //       global cache or anything ?
-    HStatus hStatus = HStatus::NO_ERROR;
-    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
-    binder::Status serviceRet = mAidlICameraService->getCameraVendorTagDescriptor(desc.get());
-
-    if (!serviceRet.isOk()) {
-        ALOGE("%s: Failed to get VendorTagDescriptor", __FUNCTION__);
-        _hidl_cb(B2HStatus(serviceRet), hVendorTagSections);
+    sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+    if (gCache == nullptr) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+        return Void();
+    }
+    const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
+            &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
+    if (vendorIdsAndTagDescs.size() == 0) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
         return Void();
     }
 
-    const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
-    size_t numSections = sectionNames->size();
-    std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
-    int tagCount = desc->getTagCount();
-    std::vector<uint32_t> tags(tagCount);
-    desc->getTagArray(tags.data());
-    for (int i = 0; i < tagCount; i++) {
-        HVendorTag vt;
-        vt.tagId = tags[i];
-        vt.tagName = desc->getTagName(tags[i]);
-        vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
-        ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
-        tagsBySection[sectionIdx].push_back(vt);
+    hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
+    hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
+    size_t j = 0;
+    for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
+        hidl_vec<HVendorTagSection> hVendorTagSections;
+        sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
+        const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
+        size_t numSections = sectionNames->size();
+        std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
+        int tagCount = desc->getTagCount();
+        std::vector<uint32_t> tags(tagCount);
+        desc->getTagArray(tags.data());
+        for (int i = 0; i < tagCount; i++) {
+            HVendorTag vt;
+            vt.tagId = tags[i];
+            vt.tagName = desc->getTagName(tags[i]);
+            vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
+            ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
+            tagsBySection[sectionIdx].push_back(vt);
+        }
+        hVendorTagSections.resize(numSections);
+        for (size_t s = 0; s < numSections; s++) {
+            hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
+            hVendorTagSections[s].tags = tagsBySection[s];
+        }
+        HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
+                hTagIdsAndVendorTagSections[j];
+        hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
+        hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
+        j++;
     }
-    hVendorTagSections.resize(numSections);
-    for (size_t s = 0; s < numSections; s++) {
-        hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
-        hVendorTagSections[s].tags = tagsBySection[s];
-    }
-    _hidl_cb(hStatus, hVendorTagSections);
+    _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
     return Void();
 }
 
diff --git a/services/soundtrigger/Android.bp b/services/soundtrigger/Android.bp
new file mode 100644
index 0000000..1f2283a
--- /dev/null
+++ b/services/soundtrigger/Android.bp
@@ -0,0 +1,54 @@
+// Copyright 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libsoundtriggerservice",
+
+    srcs: [
+        "SoundTriggerHwService.cpp",
+        "SoundTriggerHalHidl.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libbinder",
+        "libcutils",
+        "libhardware",
+        "libsoundtrigger",
+        "libaudioclient",
+        "libmediautils",
+
+        "libhwbinder",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "libbase",
+        "libaudiohal",
+        "libaudiohal_deathhandler",
+        "android.hardware.soundtrigger@2.0",
+        "android.hardware.soundtrigger@2.1",
+        "android.hardware.soundtrigger@2.2",
+        "android.hardware.audio.common@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+    ],
+
+    include_dirs: ["frameworks/av/services/audioflinger"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
deleted file mode 100644
index 65f1a44..0000000
--- a/services/soundtrigger/Android.mk
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1)
-    ifneq ($(USE_LEGACY_LOCAL_AUDIO_HAL), true)
-        $(error Requires building with USE_LEGACY_LOCAL_AUDIO_HAL=true)
-    endif
-    LOCAL_CFLAGS += -DSOUND_TRIGGER_USE_STUB_MODULE
-endif
-
-LOCAL_SRC_FILES:=               \
-    SoundTriggerHwService.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
-    liblog \
-    libutils \
-    libbinder \
-    libcutils \
-    libhardware \
-    libsoundtrigger \
-    libaudioclient \
-    libmediautils \
-
-ifeq ($(USE_LEGACY_LOCAL_AUDIO_HAL),true)
-# libhardware configuration
-LOCAL_SRC_FILES +=               \
-    SoundTriggerHalLegacy.cpp
-else
-# Treble configuration
-LOCAL_SRC_FILES +=               \
-    SoundTriggerHalHidl.cpp
-
-LOCAL_SHARED_LIBRARIES += \
-    libhwbinder \
-    libhidlbase \
-    libhidlmemory \
-    libhidltransport \
-    libbase \
-    libaudiohal \
-    libaudiohal_deathhandler \
-    android.hardware.soundtrigger@2.0 \
-    android.hardware.soundtrigger@2.1 \
-    android.hardware.soundtrigger@2.2 \
-    android.hardware.audio.common@2.0 \
-    android.hidl.allocator@1.0 \
-    android.hidl.memory@1.0
-endif
-
-
-LOCAL_C_INCLUDES += \
-    frameworks/av/services/audioflinger
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MODULE:= libsoundtriggerservice
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/soundtrigger/SoundTriggerHalLegacy.cpp b/services/soundtrigger/SoundTriggerHalLegacy.cpp
deleted file mode 100644
index 2b78818..0000000
--- a/services/soundtrigger/SoundTriggerHalLegacy.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Log.h>
-#include "SoundTriggerHalLegacy.h"
-
-namespace android {
-
-/* static */
-sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
-{
-    return new SoundTriggerHalLegacy(moduleName);
-}
-
-SoundTriggerHalLegacy::SoundTriggerHalLegacy(const char *moduleName)
-    : mModuleName(moduleName), mHwDevice(NULL)
-{
-}
-
-void SoundTriggerHalLegacy::onFirstRef()
-{
-    const hw_module_t *mod;
-    int rc;
-
-    if (mModuleName == NULL) {
-        mModuleName = "primary";
-    }
-
-    rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
-    if (rc != 0) {
-        ALOGE("couldn't load sound trigger module %s.%s (%s)",
-              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
-        return;
-    }
-    rc = sound_trigger_hw_device_open(mod, &mHwDevice);
-    if (rc != 0) {
-        ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
-              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
-        mHwDevice = NULL;
-        return;
-    }
-    if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
-            mHwDevice->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
-        ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
-        return;
-    }
-}
-
-SoundTriggerHalLegacy::~SoundTriggerHalLegacy()
-{
-    if (mHwDevice != NULL) {
-        sound_trigger_hw_device_close(mHwDevice);
-    }
-}
-
-int SoundTriggerHalLegacy::getProperties(struct sound_trigger_properties *properties)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->get_properties(mHwDevice, properties);
-}
-
-int SoundTriggerHalLegacy::loadSoundModel(struct sound_trigger_sound_model *sound_model,
-                        sound_model_callback_t callback,
-                        void *cookie,
-                        sound_model_handle_t *handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->load_sound_model(mHwDevice, sound_model, callback, cookie, handle);
-}
-
-int SoundTriggerHalLegacy::unloadSoundModel(sound_model_handle_t handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->unload_sound_model(mHwDevice, handle);
-}
-
-int SoundTriggerHalLegacy::startRecognition(sound_model_handle_t handle,
-                         const struct sound_trigger_recognition_config *config,
-                         recognition_callback_t callback,
-                         void *cookie)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->start_recognition(mHwDevice, handle, config, callback, cookie);
-}
-
-int SoundTriggerHalLegacy::stopRecognition(sound_model_handle_t handle)
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    return mHwDevice->stop_recognition(mHwDevice, handle);
-}
-
-int SoundTriggerHalLegacy::stopAllRecognitions()
-{
-    if (mHwDevice == NULL) {
-        return -ENODEV;
-    }
-    if (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
-     mHwDevice->stop_all_recognitions) {
-        return mHwDevice->stop_all_recognitions(mHwDevice);
-    }
-    return -ENOSYS;
-}
-
-} // namespace android
diff --git a/services/soundtrigger/SoundTriggerHalLegacy.h b/services/soundtrigger/SoundTriggerHalLegacy.h
deleted file mode 100644
index 52488de..0000000
--- a/services/soundtrigger/SoundTriggerHalLegacy.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
-#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
-
-#include "SoundTriggerHalInterface.h"
-
-namespace android {
-
-class SoundTriggerHalLegacy : public SoundTriggerHalInterface
-
-{
-public:
-        virtual             ~SoundTriggerHalLegacy();
-
-        virtual int getProperties(struct sound_trigger_properties *properties);
-
-        /*
-         * Load a sound model. Once loaded, recognition of this model can be started and stopped.
-         * Only one active recognition per model at a time. The SoundTrigger service will handle
-         * concurrent recognition requests by different users/applications on the same model.
-         * The implementation returns a unique handle used by other functions (unload_sound_model(),
-         * start_recognition(), etc...
-         */
-        virtual int loadSoundModel(struct sound_trigger_sound_model *sound_model,
-                                sound_model_callback_t callback,
-                                void *cookie,
-                                sound_model_handle_t *handle);
-
-        /*
-         * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome
-         * implementation limitations.
-         */
-        virtual int unloadSoundModel(sound_model_handle_t handle);
-
-        /* Start recognition on a given model. Only one recognition active at a time per model.
-         * Once recognition succeeds of fails, the callback is called.
-         * TODO: group recognition configuration parameters into one struct and add key phrase options.
-         */
-        virtual int startRecognition(sound_model_handle_t handle,
-                                 const struct sound_trigger_recognition_config *config,
-                                 recognition_callback_t callback,
-                                 void *cookie);
-
-        /* Stop recognition on a given model.
-         * The implementation does not have to call the callback when stopped via this method.
-         */
-        virtual int stopRecognition(sound_model_handle_t handle);
-
-        /* Stop recognition on all models.
-         * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_1 or above.
-         * If no implementation is provided, stop_recognition will be called for each running model.
-         */
-        int stopAllRecognitions();
-
-        // RefBase
-        virtual     void        onFirstRef();
-
-private:
-
-        friend class SoundTriggerHalInterface;
-
-        explicit SoundTriggerHalLegacy(const char *moduleName = NULL);
-
-        const char *mModuleName;
-        struct sound_trigger_hw_device*        mHwDevice;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_LEGACY_H
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 7915068..944abcc 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -36,11 +36,7 @@
 #include <system/sound_trigger.h>
 #include "SoundTriggerHwService.h"
 
-#ifdef SOUND_TRIGGER_USE_STUB_MODULE
-#define HW_MODULE_PREFIX "stub"
-#else
 #define HW_MODULE_PREFIX "primary"
-#endif
 namespace android {
 
 SoundTriggerHwService::SoundTriggerHwService()