Merge "Camera NDK: New lifecycle for ACameraMetadata_fromCameraMetadata"
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index 5a60243..49614cd 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -9,6 +9,10 @@
         },
         {
           "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
+        },
+        // TODO: b/149314419
+        {
+          "exclude-filter": "android.media.cts.AudioPlaybackCaptureTest"
         }
       ]
     }
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 592ffa9..ca721df 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -11,8 +11,8 @@
     static_libs: [
         "libmedia_midiiowrapper",
         "libsonivox",
-        "libstagefright_foundation"
-    ],
-
-
+        "libstagefright_foundation",
+        "libwatchdog",
+        "libbase",
+    ]
 }
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index 9f4f9e6..d0efb2f 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -26,6 +26,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <libsonivox/eas_reverb.h>
+#include <watchdog/Watchdog.h>
 
 namespace android {
 
@@ -116,6 +117,7 @@
         MediaBufferHelper **outBuffer, const ReadOptions *options)
 {
     ALOGV("MidiSource::read");
+
     MediaBufferHelper *buffer;
     // process an optional seek request
     int64_t seekTimeUs;
@@ -139,6 +141,8 @@
 }
 
 // MidiEngine
+using namespace std::chrono_literals;
+static constexpr auto kTimeout = 10s;
 
 MidiEngine::MidiEngine(CDataSource *dataSource,
         AMediaFormat *fileMetadata,
@@ -147,6 +151,8 @@
             mEasHandle(NULL),
             mEasConfig(NULL),
             mIsInitialized(false) {
+    Watchdog watchdog(kTimeout);
+
     mIoWrapper = new MidiIoWrapper(dataSource);
     // spin up a new EAS engine
     EAS_I32 temp;
@@ -186,6 +192,8 @@
 }
 
 MidiEngine::~MidiEngine() {
+    Watchdog watchdog(kTimeout);
+
     if (mEasHandle) {
         EAS_CloseFile(mEasData, mEasHandle);
     }
@@ -217,12 +225,16 @@
 }
 
 status_t MidiEngine::seekTo(int64_t positionUs) {
+    Watchdog watchdog(kTimeout);
+
     ALOGV("seekTo %lld", (long long)positionUs);
     EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false);
     return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR;
 }
 
 MediaBufferHelper* MidiEngine::readBuffer() {
+    Watchdog watchdog(kTimeout);
+
     EAS_STATE state;
     EAS_State(mEasData, mEasHandle, &state);
     if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
diff --git a/media/extractors/tests/Android.bp b/media/extractors/tests/Android.bp
index 059c308..fa39b64 100644
--- a/media/extractors/tests/Android.bp
+++ b/media/extractors/tests/Android.bp
@@ -33,6 +33,7 @@
         "libmp4extractor",
         "libaudioutils",
         "libdatasource",
+        "libwatchdog",
 
         "libstagefright",
         "libstagefright_id3",
@@ -65,6 +66,7 @@
         "libcrypto",
         "libhidlmemory",
         "libhidlbase",
+        "libbase",
     ],
 
     include_dirs: [
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index d468239..0522099 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -86,6 +86,7 @@
     mDeviceAddress = parcel->readString8();
     mCbFlags = (uint32_t)parcel->readInt32();
     mAllowPrivilegedPlaybackCapture = parcel->readBool();
+    mVoiceCommunicationCaptureAllowed = parcel->readBool();
     size_t size = (size_t)parcel->readInt32();
     if (size > MAX_CRITERIA_PER_MIX) {
         size = MAX_CRITERIA_PER_MIX;
@@ -110,6 +111,7 @@
     parcel->writeString8(mDeviceAddress);
     parcel->writeInt32(mCbFlags);
     parcel->writeBool(mAllowPrivilegedPlaybackCapture);
+    parcel->writeBool(mVoiceCommunicationCaptureAllowed);
     size_t size = mCriteria.size();
     if (size > MAX_CRITERIA_PER_MIX) {
         size = MAX_CRITERIA_PER_MIX;
@@ -206,11 +208,4 @@
             && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
 }
 
-bool AudioMix::hasMatchingRuleForUsage(std::function<bool (audio_usage_t)>const& func) const {
-    return std::any_of(mCriteria.begin(), mCriteria.end(), [func](auto& criterion) {
-            return criterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE
-              && func(criterion.mValue.mUsage);
-          });
-}
-
 } // namespace android
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 20d2c0b..00fe278 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -18,7 +18,6 @@
 #ifndef ANDROID_AUDIO_POLICY_H
 #define ANDROID_AUDIO_POLICY_H
 
-#include <functional>
 #include <binder/Parcel.h>
 #include <media/AudioDeviceTypeAddr.h>
 #include <system/audio.h>
@@ -113,13 +112,6 @@
     /** returns true if this mix can be used for uid-device affinity routing */
     bool isDeviceAffinityCompatible() const;
 
-    /**
-     * returns true if the mix has a capture rule for a usage that
-     * matches the given predicate
-     */
-    bool hasMatchingRuleForUsage(
-        std::function<bool (audio_usage_t)>const& func) const;
-
     mutable Vector<AudioMixMatchCriterion> mCriteria;
     uint32_t        mMixType;
     audio_config_t  mFormat;
@@ -129,6 +121,8 @@
     uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
     /** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
     bool            mAllowPrivilegedPlaybackCapture = false;
+    /** Indicates if the caller can capture voice communication output */
+    bool            mVoiceCommunicationCaptureAllowed = false;
 };
 
 
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 74b48f3..1709d1e 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -4,6 +4,7 @@
     srcs: [
         "DevicesFactoryHalInterface.cpp",
         "EffectsFactoryHalInterface.cpp",
+        "FactoryHalHidl.cpp",
     ],
 
     cflags: [
@@ -12,11 +13,17 @@
         "-Werror",
     ],
 
-    shared_libs: [
+    required: [
         "libaudiohal@2.0",
         "libaudiohal@4.0",
         "libaudiohal@5.0",
         "libaudiohal@6.0",
+    ],
+
+    shared_libs: [
+        "libdl",
+        "libhidlbase",
+        "liblog",
         "libutils",
     ],
 
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index d5336fa..325a547 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-#include <libaudiohal/FactoryHalHidl.h>
-
 #include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <media/audiohal/FactoryHalHidl.h>
 
 namespace android {
 
 // static
 sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
-    return createPreferedImpl<DevicesFactoryHalInterface>();
+    return createPreferredImpl<DevicesFactoryHalInterface>(
+            "android.hardware.audio", "IDevicesFactory");
 }
 
 } // namespace android
-
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index d15b14e..bc3b4c1 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-#include <libaudiohal/FactoryHalHidl.h>
-
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <media/audiohal/FactoryHalHidl.h>
 
 namespace android {
 
 // static
 sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
-    return createPreferedImpl<EffectsFactoryHalInterface>();
+    return createPreferredImpl<EffectsFactoryHalInterface>(
+            "android.hardware.audio.effect", "IEffectsFactory");
 }
 
 // static
diff --git a/media/libaudiohal/FactoryHalHidl.cpp b/media/libaudiohal/FactoryHalHidl.cpp
new file mode 100644
index 0000000..5985ef0
--- /dev/null
+++ b/media/libaudiohal/FactoryHalHidl.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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_TAG "FactoryHalHidl"
+
+#include <media/audiohal/FactoryHalHidl.h>
+
+#include <dlfcn.h>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <utils/Log.h>
+
+namespace android::detail {
+
+namespace {
+/** Supported HAL versions, in order of preference.
+ */
+const char* sAudioHALVersions[] = {
+    "6.0",
+    "5.0",
+    "4.0",
+    "2.0",
+    nullptr
+};
+
+bool createHalService(const std::string& version, const std::string& interface,
+        void** rawInterface) {
+    const std::string libName = "libaudiohal@" + version + ".so";
+    const std::string factoryFunctionName = "create" + interface;
+    constexpr int dlMode = RTLD_LAZY;
+    void* handle = nullptr;
+    dlerror(); // clear
+    handle = dlopen(libName.c_str(), dlMode);
+    if (handle == nullptr) {
+        const char* error = dlerror();
+        ALOGE("Failed to dlopen %s: %s", libName.c_str(),
+                error != nullptr ? error : "unknown error");
+        return false;
+    }
+    void* (*factoryFunction)();
+    *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
+    if (!factoryFunction) {
+        const char* error = dlerror();
+        ALOGE("Factory function %s not found in library %s: %s",
+                factoryFunctionName.c_str(), libName.c_str(),
+                error != nullptr ? error : "unknown error");
+        dlclose(handle);
+        return false;
+    }
+    *rawInterface = (*factoryFunction)();
+    ALOGW_IF(!*rawInterface, "Factory function %s from %s returned nullptr",
+            factoryFunctionName.c_str(), libName.c_str());
+    return true;
+}
+
+bool hasHalService(const std::string& package, const std::string& version,
+        const std::string& interface) {
+    using ::android::hidl::manager::V1_0::IServiceManager;
+    sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
+    if (!sm) {
+        ALOGE("Failed to obtain HIDL ServiceManager");
+        return false;
+    }
+    // Since audio HAL doesn't support multiple clients, avoid instantiating
+    // the interface right away. Instead, query the transport type for it.
+    using ::android::hardware::Return;
+    using Transport = IServiceManager::Transport;
+    const std::string fqName = package + "@" + version + "::" + interface;
+    const std::string instance = "default";
+    Return<Transport> transport = sm->getTransport(fqName, instance);
+    if (!transport.isOk()) {
+        ALOGE("Failed to obtain transport type for %s/%s: %s",
+                fqName.c_str(), instance.c_str(), transport.description().c_str());
+        return false;
+    }
+    return transport != Transport::EMPTY;
+}
+
+}  // namespace
+
+void* createPreferredImpl(const std::string& package, const std::string& interface) {
+    for (auto version = detail::sAudioHALVersions; version != nullptr; ++version) {
+        void* rawInterface = nullptr;
+        if (hasHalService(package, *version, interface)
+                && createHalService(*version, interface, &rawInterface)) {
+            return rawInterface;
+        }
+    }
+    return nullptr;
+}
+
+}  // namespace android::detail
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index e96a68c..967fba1 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -16,12 +16,11 @@
         "StreamHalHidl.cpp",
     ],
 
-    export_include_dirs: ["include"],
-
     cflags: [
         "-Wall",
         "-Wextra",
         "-Werror",
+        "-fvisibility=hidden",
     ],
     shared_libs: [
         "android.hardware.audio.common-util",
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index c30da3c..e6e9688 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -20,7 +20,7 @@
 #define LOG_TAG "DevicesFactoryHalHidl"
 //#define LOG_NDEBUG 0
 
-#include "android/hidl/manager/1.0/IServiceManager.h"
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
 #include <media/audiohal/hidl/HalDeathHandler.h>
 #include <utils/Log.h>
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index a5aef1b..52f150a 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -20,7 +20,6 @@
 #include "DevicesFactoryHalHidl.h"
 #include "DevicesFactoryHalHybrid.h"
 #include "DevicesFactoryHalLocal.h"
-#include <libaudiohal/FactoryHalHidl.h>
 
 namespace android {
 namespace CPP_VERSION {
@@ -47,8 +46,7 @@
 
 } // namespace CPP_VERSION
 
-template <>
-sp<DevicesFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
     auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
     return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
 }
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 867b72d..9192a31 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -24,7 +24,6 @@
 #include "EffectHalHidl.h"
 #include "EffectsFactoryHalHidl.h"
 #include "HidlUtils.h"
-#include <libaudiohal/FactoryHalHidl.h>
 
 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
 using ::android::hardware::Return;
@@ -162,8 +161,7 @@
 } // namespace CPP_VERSION
 } // namespace effect
 
-template<>
-sp<EffectsFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+extern "C" __attribute__((visibility("default"))) void* createIEffectsFactory() {
     auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
     return service ? new effect::CPP_VERSION::EffectsFactoryHalHidl(service) : nullptr;
 }
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
deleted file mode 100644
index 271bafc..0000000
--- a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
+++ /dev/null
@@ -1,66 +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 ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
-#define ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
-
-/** @file Library entry points to create the HAL factories. */
-
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <utils/StrongPointer.h>
-
-#include <array>
-#include <utility>
-
-namespace android {
-
-/** Supported HAL versions, in order of preference.
- * Implementation should use specialize the `create*FactoryHal` for their version.
- * Client should use `createPreferedImpl<*FactoryHal>()` to instantiate
- * the preferred available impl.
- */
-enum class AudioHALVersion {
-    V6_0,
-    V5_0,
-    V4_0,
-    V2_0,
-    end, // used for iterating over supported versions
-};
-
-/** Template function to fully specialized for each version and each Interface. */
-template <AudioHALVersion, class Interface>
-sp<Interface> createFactoryHal();
-
-/** @Return the preferred available implementation or nullptr if none are available. */
-template <class Interface, AudioHALVersion version = AudioHALVersion{}>
-static sp<Interface> createPreferedImpl() {
-    if constexpr (version == AudioHALVersion::end) {
-        return nullptr; // tried all version, all returned nullptr
-    } else {
-        if (auto created = createFactoryHal<version, Interface>(); created != nullptr) {
-           return created;
-        }
-
-        using Raw = std::underlying_type_t<AudioHALVersion>; // cast as enum class do not support ++
-        return createPreferedImpl<Interface, AudioHALVersion(Raw(version) + 1)>();
-    }
-}
-
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/include/media/audiohal/FactoryHalHidl.h b/media/libaudiohal/include/media/audiohal/FactoryHalHidl.h
new file mode 100644
index 0000000..d353ed0
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/FactoryHalHidl.h
@@ -0,0 +1,40 @@
+/*
+ * 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 ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
+#define ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
+
+#include <string>
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace detail {
+
+void* createPreferredImpl(const std::string& package, const std::string& interface);
+
+}  // namespace detail
+
+/** @Return the preferred available implementation or nullptr if none are available. */
+template <class Interface>
+static sp<Interface> createPreferredImpl(const std::string& package, const std::string& interface) {
+    return sp<Interface>{static_cast<Interface*>(detail::createPreferredImpl(package, interface))};
+}
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
diff --git a/media/libmediahelper/TypeConverter.cpp b/media/libmediahelper/TypeConverter.cpp
index d300c7a..6382ce4 100644
--- a/media/libmediahelper/TypeConverter.cpp
+++ b/media/libmediahelper/TypeConverter.cpp
@@ -315,6 +315,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ASSISTANT),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_REROUTING),
     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_PATCH),
+    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_CALL_ASSISTANT),
     TERMINATOR
 };
 
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index fb26fae..eb7ac7d 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -75,16 +75,21 @@
 // followed by one or more characters in the range [a-zA-Z0-9_.].
 // Special symbols such as !@#$%^&*()[]{}<>,:;'"\/?|+-=~ are reserved.
 //
-// A property that ends with a ! will have duplicate values listed instead
+// Properties within this header should include special suffixes like '#'
+// directly in the string for brevity.  Code outside of this header should
+// use the macro constant for the special symbols for searchability.
+
+// Any property that ends with a # will have duplicate values listed instead
 // of suppressed in the Time Machine.
-//
+#define AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED '#'
+
 #define AMEDIAMETRICS_PROP_AUXEFFECTID    "auxEffectId"    // int32 (AudioTrack)
 #define AMEDIAMETRICS_PROP_CHANNELCOUNT   "channelCount"   // int32
 #define AMEDIAMETRICS_PROP_CHANNELMASK    "channelMask"    // int32
 #define AMEDIAMETRICS_PROP_CONTENTTYPE    "contentType"    // string attributes (AudioTrack)
 #define AMEDIAMETRICS_PROP_DURATIONNS     "durationNs"     // int64 duration time span
 #define AMEDIAMETRICS_PROP_ENCODING       "encoding"       // string value of format
-#define AMEDIAMETRICS_PROP_EVENT          "event!"         // string value (often func name)
+#define AMEDIAMETRICS_PROP_EVENT          "event#"         // string value (often func name)
 
 // TODO: fix inconsistency in flags: AudioRecord / AudioTrack int32,  AudioThread string
 #define AMEDIAMETRICS_PROP_FLAGS          "flags"
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 2457561..44dbfe9 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -280,7 +280,7 @@
 
     std::shared_ptr<std::list<sp<ExtractorPlugin>>> newList(new std::list<sp<ExtractorPlugin>>());
 
-    android_namespace_t *mediaNs = android_get_exported_namespace("media");
+    android_namespace_t *mediaNs = android_get_exported_namespace("com.android.media");
     if (mediaNs != NULL) {
         const android_dlextinfo dlextinfo = {
             .flags = ANDROID_DLEXT_USE_NAMESPACE,
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index 3c3fff7..fac9511 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -9,6 +9,10 @@
         },
         {
           "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
+        },
+        // TODO: b/149314419
+        {
+          "exclude-filter": "android.media.cts.AudioPlaybackCaptureTest"
         }
       ]
     },
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index cff14ac..986c9ac 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -1423,7 +1423,7 @@
     // stall since no future events are expected.
     mEndOfStream = true;
 
-    if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
+    if (mExecuting && !haveAvailableBuffers_l()) {
         submitEndOfInputStream_l();
     }
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index 6b45ea2..c67dc2b 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -47,9 +47,6 @@
     export_include_dirs: ["include"],
 
     cflags: [
-        "-DOSCL_EXPORT_REF=",
-        "-DOSCL_IMPORT_REF=",
-
         "-Werror",
     ],
 
@@ -74,8 +71,6 @@
     local_include_dirs: ["src"],
 
     cflags: [
-        "-DOSCL_EXPORT_REF=",
-        "-DOSCL_IMPORT_REF=",
     ],
 
     static_libs: ["libstagefright_m4vh263dec"],
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
index 6d4868c..1f404ce 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
@@ -35,6 +35,13 @@
 #define PV_TRUE  1
 #define PV_FALSE 0
 
+#ifndef OSCL_IMPORT_REF
+#define OSCL_IMPORT_REF /* empty */
+#endif
+#ifndef OSCL_EXPORT_REF
+#define OSCL_EXPORT_REF /* empty */
+#endif
+
 /* flag for post-processing  4/25/00 */
 
 #ifdef DEC_NOPOSTPROC
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
index e335c9b..655491a 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
@@ -32,7 +32,6 @@
     ],
 
     cflags: [
-        "-DOSCL_IMPORT_REF=",
         "-Werror",
         "-Wall",
     ],
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 2738187..846f614 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -23,10 +23,6 @@
 
     cflags: [
         "-DBX_RC",
-        "-DOSCL_IMPORT_REF=",
-        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
-        "-DOSCL_EXPORT_REF=",
-
         "-Werror",
     ],
 
@@ -55,9 +51,6 @@
 
     cflags: [
         "-DBX_RC",
-        "-DOSCL_IMPORT_REF=",
-        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
-        "-DOSCL_EXPORT_REF=",
     ],
 
     static_libs: ["libstagefright_m4vh263enc"],
@@ -81,8 +74,6 @@
     local_include_dirs: ["src"],
 
     cflags: [
-        "-DOSCL_EXPORT_REF=",
-        "-DOSCL_IMPORT_REF=",
         "-DBX_RC",
         "-Wall",
         "-Werror",
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index d5a3ff1..9f824b1 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -39,6 +39,16 @@
 #define PV_TRUE  1
 #define PV_FALSE 0
 
+#ifndef OSCL_IMPORT_REF
+#define OSCL_IMPORT_REF /* empty */
+#endif
+#ifndef OSCL_EXPORT_REF
+#define OSCL_EXPORT_REF /* empty */
+#endif
+#ifndef OSCL_UNUSED_ARG
+#define OSCL_UNUSED_ARG(x) ((void)(x))
+#endif
+
 typedef enum
 {
     SHORT_HEADER,
diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp
new file mode 100644
index 0000000..849623a
--- /dev/null
+++ b/media/libwatchdog/Android.bp
@@ -0,0 +1,36 @@
+// Copyright 2020 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 {
+    name: "libwatchdog",
+    srcs: [
+        "Watchdog.cpp",
+    ],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "liblog",
+    ],
+    static_libs: [
+        "libbase",
+    ],
+    target: {
+        windows: {
+            enabled: false,
+        },
+        darwin: {
+            enabled: false,
+        },
+    },
+    apex_available: ["com.android.media"],
+}
diff --git a/media/libwatchdog/Watchdog.cpp b/media/libwatchdog/Watchdog.cpp
new file mode 100644
index 0000000..bb012b9
--- /dev/null
+++ b/media/libwatchdog/Watchdog.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 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_TAG "Watchdog"
+
+#include <watchdog/Watchdog.h>
+
+#include <android-base/logging.h>
+#include <android-base/threads.h>
+#include <signal.h>
+#include <time.h>
+#include <cstring>
+#include <utils/Log.h>
+
+namespace android {
+
+Watchdog::Watchdog(::std::chrono::steady_clock::duration timeout) {
+    // Create the timer.
+    struct sigevent sev;
+    sev.sigev_notify = SIGEV_THREAD_ID;
+    sev.sigev_notify_thread_id = base::GetThreadId();
+    sev.sigev_signo = SIGABRT;
+    sev.sigev_value.sival_ptr = &mTimerId;
+    int err = timer_create(CLOCK_MONOTONIC, &sev, &mTimerId);
+    if (err != 0) {
+        PLOG(FATAL) << "Failed to create timer";
+    }
+
+    // Start the timer.
+    struct itimerspec spec;
+    memset(&spec, 0, sizeof(spec));
+    auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout);
+    LOG_ALWAYS_FATAL_IF(timeout.count() <= 0, "Duration must be positive");
+    spec.it_value.tv_sec = ns.count() / 1000000000;
+    spec.it_value.tv_nsec = ns.count() % 1000000000;
+    err = timer_settime(mTimerId, 0, &spec, nullptr);
+    if (err != 0) {
+        PLOG(FATAL) << "Failed to start timer";
+    }
+}
+
+Watchdog::~Watchdog() {
+    // Delete the timer.
+    int err = timer_delete(mTimerId);
+    if (err != 0) {
+        PLOG(FATAL) << "Failed to delete timer";
+    }
+}
+
+}  // namespace android
diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/libwatchdog/include/watchdog/Watchdog.h
new file mode 100644
index 0000000..2819f8a
--- /dev/null
+++ b/media/libwatchdog/include/watchdog/Watchdog.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 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_WATCHDOG_H
+#define ANDROID_WATCHDOG_H
+
+#include <chrono>
+#include <time.h>
+
+namespace android {
+
+/*
+ * An RAII-style object, which would crash the process if a timeout expires
+ * before the object is destroyed.
+ * The calling thread would be sent a SIGABORT, which would typically result in
+ * a stack trace.
+ *
+ * Sample usage:
+ * {
+ *     Watchdog watchdog(std::chrono::milliseconds(10));
+ *     DoSomething();
+ * }
+ * // If we got here, the function completed in time.
+ */
+class Watchdog final {
+public:
+    Watchdog(std::chrono::steady_clock::duration timeout);
+    ~Watchdog();
+
+private:
+    timer_t mTimerId;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_WATCHDOG_H
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index ed77aac..49d8b4a 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -296,6 +296,12 @@
 
 #if __ANDROID_API__ >= 30
 /**
+ * An optional key describing the low latency decoding mode. This is an optional parameter
+ * that applies only to decoders. If enabled, the decoder doesn't hold input and output
+ * data more than required by the codec standards.
+ * The associated value is an integer (0 or 1): 1 when low-latency decoding is enabled,
+ * 0 otherwise. The default value is 0.
+ *
  * Available since API level 30.
  */
 extern const char* AMEDIAFORMAT_KEY_LOW_LATENCY __INTRODUCED_IN(30);
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index f06d026..3873600 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -3,8 +3,6 @@
 cc_library_shared {
     name: "libaudioflinger",
 
-    tidy: false, // b/146435095, segmentation fault with Effects.cpp
-
     srcs: [
         "AudioFlinger.cpp",
         "AudioHwDevice.cpp",
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ad09680..3726b9a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1902,9 +1902,11 @@
         mStreamTypes[stream].volume = 0.0f;
         mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
     }
-    // Audio patch volume is always max
+    // Audio patch and call assistant volume are always max
     mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
     mStreamTypes[AUDIO_STREAM_PATCH].mute = false;
+    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].volume = 1.0f;
+    mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].mute = false;
 }
 
 AudioFlinger::PlaybackThread::~PlaybackThread()
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index bf1a34f..ed51389 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -224,6 +224,10 @@
                 hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
                 return MixMatchStatus::NO_MATCH;
             }
+            if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION &&
+                !mix->mVoiceCommunicationCaptureAllowed) {
+                return MixMatchStatus::NO_MATCH;
+            }
             if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
                   attributes.usage == AUDIO_USAGE_MEDIA ||
                   attributes.usage == AUDIO_USAGE_GAME ||
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 46b950c..1bc7fe3 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -107,6 +107,13 @@
 engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
 {
     auto loadVolumeConfig = [](auto &volumeGroups, auto &volumeConfig) {
+        // Ensure name unicity to prevent duplicate
+        LOG_ALWAYS_FATAL_IF(std::any_of(std::begin(volumeGroups), std::end(volumeGroups),
+                                     [&volumeConfig](const auto &volumeGroup) {
+                return volumeConfig.name == volumeGroup.second->getName(); }),
+                            "group name %s defined twice, review the configuration",
+                            volumeConfig.name.c_str());
+
         sp<VolumeGroup> volumeGroup = new VolumeGroup(volumeConfig.name, volumeConfig.indexMin,
                                                       volumeConfig.indexMax);
         volumeGroups[volumeGroup->getId()] = volumeGroup;
@@ -125,13 +132,21 @@
         }
         return volumeGroup;
     };
-    auto addSupportedStreamAttributes = [](auto &group, auto &volumeGroup, auto &strategy) {
-        volumeGroup->addSupportedStream(group.stream);
+    auto addSupportedAttributesToGroup = [](auto &group, auto &volumeGroup, auto &strategy) {
         for (const auto &attr : group.attributesVect) {
             strategy->addAttributes({group.stream, volumeGroup->getId(), attr});
             volumeGroup->addSupportedAttributes(attr);
         }
     };
+    auto checkStreamForGroups = [](auto streamType, const auto &volumeGroups) {
+        const auto &iter = std::find_if(std::begin(volumeGroups), std::end(volumeGroups),
+                                     [&streamType](const auto &volumeGroup) {
+            const auto& streams = volumeGroup.second->getStreamTypes();
+            return std::find(std::begin(streams), std::end(streams), streamType) !=
+                    std::end(streams);
+        });
+        return iter != end(volumeGroups);
+    };
 
     auto result = engineConfig::parse();
     if (result.parsedConfig == nullptr) {
@@ -140,15 +155,30 @@
         android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);
         result = {std::make_unique<engineConfig::Config>(config),
                   static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
+    } else {
+        // Append for internal use only volume groups (e.g. rerouting/patch)
+        result.parsedConfig->volumeGroups.insert(
+                    std::end(result.parsedConfig->volumeGroups),
+                    std::begin(gSystemVolumeGroups), std::end(gSystemVolumeGroups));
     }
+    // Append for internal use only strategies (e.g. rerouting/patch)
+    result.parsedConfig->productStrategies.insert(
+                std::end(result.parsedConfig->productStrategies),
+                std::begin(gOrderedSystemStrategies), std::end(gOrderedSystemStrategies));
+
+
     ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
 
     engineConfig::VolumeGroup defaultVolumeConfig;
+    engineConfig::VolumeGroup defaultSystemVolumeConfig;
     for (auto &volumeConfig : result.parsedConfig->volumeGroups) {
         // save default volume config for streams not defined in configuration
         if (volumeConfig.name.compare("AUDIO_STREAM_MUSIC") == 0) {
             defaultVolumeConfig = volumeConfig;
         }
+        if (volumeConfig.name.compare("AUDIO_STREAM_PATCH") == 0) {
+            defaultSystemVolumeConfig = volumeConfig;
+        }
         loadVolumeConfig(mVolumeGroups, volumeConfig);
     }
     for (auto& strategyConfig : result.parsedConfig->productStrategies) {
@@ -157,18 +187,31 @@
             const auto &iter = std::find_if(begin(mVolumeGroups), end(mVolumeGroups),
                                          [&group](const auto &volumeGroup) {
                     return group.volumeGroup == volumeGroup.second->getName(); });
-            if (group.stream != AUDIO_STREAM_DEFAULT) {
-                if (iter == end(mVolumeGroups)) {
-                    ALOGW("%s: No configuration of %s found, using default volume configuration"
-                            , __FUNCTION__, group.volumeGroup.c_str());
-                    defaultVolumeConfig.name = group.volumeGroup;
-                    sp<VolumeGroup> volumeGroup =
-                            loadVolumeConfig(mVolumeGroups, defaultVolumeConfig);
-                    addSupportedStreamAttributes(group, volumeGroup, strategy);
+            sp<VolumeGroup> volumeGroup = nullptr;
+            // If no volume group provided for this strategy, creates a new one using
+            // Music Volume Group configuration (considered as the default)
+            if (iter == end(mVolumeGroups)) {
+                engineConfig::VolumeGroup volumeConfig;
+                if (group.stream >= AUDIO_STREAM_PUBLIC_CNT) {
+                    volumeConfig = defaultSystemVolumeConfig;
                 } else {
-                    addSupportedStreamAttributes(group, iter->second, strategy);
+                    volumeConfig = defaultVolumeConfig;
                 }
+                ALOGW("%s: No configuration of %s found, using default volume configuration"
+                        , __FUNCTION__, group.volumeGroup.c_str());
+                volumeConfig.name = group.volumeGroup;
+                volumeGroup = loadVolumeConfig(mVolumeGroups, volumeConfig);
+            } else {
+                volumeGroup = iter->second;
             }
+            if (group.stream != AUDIO_STREAM_DEFAULT) {
+                // A legacy stream can be assigned once to a volume group
+                LOG_ALWAYS_FATAL_IF(checkStreamForGroups(group.stream, mVolumeGroups),
+                                    "stream %s already assigned to a volume group, "
+                                    "review the configuration", toString(group.stream).c_str());
+                volumeGroup->addSupportedStream(group.stream);
+            }
+            addSupportedAttributesToGroup(group, volumeGroup, strategy);
         }
         product_strategy_t strategyId = strategy->getId();
         mProductStrategies[strategyId] = strategy;
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index fbce801..981582e 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -113,7 +113,7 @@
     },
     {"STRATEGY_CALL_ASSISTANT",
      {
-         {"", AUDIO_STREAM_PATCH, "AUDIO_STREAM_PATCH",
+         {"", AUDIO_STREAM_CALL_ASSISTANT, "AUDIO_STREAM_CALL_ASSISTANT",
           {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_CALL_ASSISTANT, AUDIO_SOURCE_DEFAULT, 0, ""}}
          }
      },
@@ -125,15 +125,22 @@
             AUDIO_FLAG_BEACON, ""}}
          }
      },
-    },
-    {"STRATEGY_REROUTING",
+    }
+};
+
+/**
+ * For Internal use of respectively audio policy and audioflinger
+ * For compatibility reason why apm volume config file, volume group name is the stream type.
+ */
+const engineConfig::ProductStrategies gOrderedSystemStrategies = {
+    {"rerouting",
      {
          {"", AUDIO_STREAM_REROUTING, "AUDIO_STREAM_REROUTING",
           {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
          }
      },
     },
-    {"STRATEGY_PATCH",
+    {"patch",
      {
          {"", AUDIO_STREAM_PATCH, "AUDIO_STREAM_PATCH",
           {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
@@ -141,6 +148,28 @@
      },
     }
 };
+const engineConfig::VolumeGroups gSystemVolumeGroups = {
+    {"AUDIO_STREAM_REROUTING", 0, 1,
+     {
+         {"DEVICE_CATEGORY_SPEAKER", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_HEADSET", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_EARPIECE", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_EXT_MEDIA", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_HEARING_AID", {{0,0}, {100, 0}}},
+
+     }
+    },
+    {"AUDIO_STREAM_PATCH", 0, 1,
+     {
+         {"DEVICE_CATEGORY_SPEAKER", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_HEADSET", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_EARPIECE", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_EXT_MEDIA", {{0,0}, {100, 0}}},
+         {"DEVICE_CATEGORY_HEARING_AID", {{0,0}, {100, 0}}},
+
+     }
+    }
+};
 
 const engineConfig::Config gDefaultEngineConfig = {
     1.0,
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
index 337de71..f598cf2 100644
--- a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
@@ -147,10 +147,6 @@
     <ProductStrategy name="notification">
         <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="ring">
             <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
         </AttributesGroup>
     </ProductStrategy>
     <ProductStrategy name="system">
@@ -167,19 +163,5 @@
         </AttributesGroup>
     </ProductStrategy>
 
-    <!-- Routing Strategy rerouting may be removed as following media??? -->
-    <ProductStrategy name="rerouting">
-        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-    <!-- Patch stream needs full scale volume, define it otherwise switch to default... -->
-    <ProductStrategy name="patch">
-        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
 </ProductStrategies>
 
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
index 97e6144..97a25a8 100644
--- a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
@@ -189,57 +189,5 @@
         </volume>
     </volumeGroup>
 
-    <volumeGroup>
-        <name>rerouting</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-    </volumeGroup>
-
-    <volumeGroup>
-        <name>patch</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-    </volumeGroup>
-
 </volumeGroups>
 
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
index 3634313..f598cf2 100644
--- a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
@@ -147,10 +147,6 @@
     <ProductStrategy name="notification">
         <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="ring">
             <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
-            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
         </AttributesGroup>
     </ProductStrategy>
     <ProductStrategy name="system">
@@ -167,18 +163,5 @@
         </AttributesGroup>
     </ProductStrategy>
 
-    <!-- Routing Strategy rerouting may be removed as following media??? -->
-    <ProductStrategy name="rerouting">
-        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-    <!-- Patch stream needs full scale volume, define it otherwise switch to default... -->
-    <ProductStrategy name="patch">
-        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
 </ProductStrategies>
 
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
index 97e6144..97a25a8 100644
--- a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
@@ -189,57 +189,5 @@
         </volume>
     </volumeGroup>
 
-    <volumeGroup>
-        <name>rerouting</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-    </volumeGroup>
-
-    <volumeGroup>
-        <name>patch</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID">
-            <point>0,0</point>
-            <point>100,0</point>
-        </volume>
-    </volumeGroup>
-
 </volumeGroups>
 
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
index b1c0dcf..a7388da 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -97,20 +97,5 @@
         </AttributesGroup>
     </ProductStrategy>
 
-    <!-- Routing Strategy rerouting may be removed as following media??? -->
-    <ProductStrategy name="STRATEGY_REROUTING">
-        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-    <!-- Default product strategy has empty attributes -->
-    <ProductStrategy name="STRATEGY_PATCH">
-        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-
 </ProductStrategies>
 
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
index 0f9614e..8aa71ca 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -215,26 +215,6 @@
         <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
         <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID"  ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     </volumeGroup>
-    <volumeGroup>
-        <name>rerouting</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
-    </volumeGroup>
 
-    <volumeGroup>
-        <name>patch</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
-    </volumeGroup>
 </volumeGroups>
 
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
index b1c0dcf..a7388da 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -97,20 +97,5 @@
         </AttributesGroup>
     </ProductStrategy>
 
-    <!-- Routing Strategy rerouting may be removed as following media??? -->
-    <ProductStrategy name="STRATEGY_REROUTING">
-        <AttributesGroup streamType="AUDIO_STREAM_REROUTING" volumeGroup="rerouting">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-    <!-- Default product strategy has empty attributes -->
-    <ProductStrategy name="STRATEGY_PATCH">
-        <AttributesGroup streamType="AUDIO_STREAM_PATCH" volumeGroup="patch">
-            <Attributes></Attributes>
-        </AttributesGroup>
-    </ProductStrategy>
-
-
 </ProductStrategies>
 
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
index a259950..d5c3896 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -217,26 +217,5 @@
         <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID"  ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     </volumeGroup>
 
-    <volumeGroup>
-        <name>rerouting</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
-    </volumeGroup>
-
-    <volumeGroup>
-        <name>patch</name>
-        <indexMin>0</indexMin>
-        <indexMax>1</indexMax>
-        <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
-        <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
-    </volumeGroup>
 </volumeGroups>
 
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
index d34dbe3..80f4eab 100644
--- a/services/audiopolicy/service/Android.mk
+++ b/services/audiopolicy/service/Android.mk
@@ -26,7 +26,6 @@
     libaudioutils \
     libaudiofoundation \
     libhardware_legacy \
-    libaudiopolicy \
     libaudiopolicymanager \
     libmedia_helper \
     libmediametrics \
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 8bc2837..ba3d4ff 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1215,26 +1215,14 @@
         return PERMISSION_DENIED;
     }
 
-    // Require CAPTURE_VOICE_COMMUNICATION_OUTPUT if one of the
-    // mixes is a render|loopback mix that aim to capture audio played with
-    // USAGE_VOICE_COMMUNICATION.
+    // If one of the mixes has needCaptureVoiceCommunicationOutput set to true, then we
+    // need to verify that the caller still has CAPTURE_VOICE_COMMUNICATION_OUTPUT
     bool needCaptureVoiceCommunicationOutput =
         std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
-            return is_mix_loopback_render(mix.mRouteFlags) &&
-                mix.hasMatchingRuleForUsage([] (auto usage) {
-                    return usage == AUDIO_USAGE_VOICE_COMMUNICATION;});
-            });
+            return mix.mVoiceCommunicationCaptureAllowed; });
 
-    // Require CAPTURE_MEDIA_OUTPUT if there is a mix for priveliged capture
-    // which is trying to capture any usage which is not USAGE_VOICE_COMMUNICATION.
-    // (If USAGE_VOICE_COMMUNICATION should be captured, then CAPTURE_VOICE_COMMUNICATION_OUTPUT
-    //  is required, even if it is not privileged capture).
     bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
-            return mix.mAllowPrivilegedPlaybackCapture &&
-                mix.hasMatchingRuleForUsage([] (auto usage) {
-                    return usage != AUDIO_USAGE_VOICE_COMMUNICATION;
-                });
-            });
+            return mix.mAllowPrivilegedPlaybackCapture; });
 
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     const pid_t callingPid = IPCThreadState::self()->getCallingPid();
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index 9d6d169..3f4bab0 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -33,6 +33,9 @@
         "liblog",
         "libavservices_minijail",
     ],
+    header_libs: [
+        "bionic_libc_platform_headers",
+    ],
     target: {
         android: {
             product_variables: {
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 3c4125b..afb7692 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -28,6 +28,8 @@
 #include <android-base/properties.h>
 #include <utils/misc.h>
 
+#include <bionic/reserved_signals.h>
+
 // from LOCAL_C_INCLUDES
 #include "MediaExtractorService.h"
 #include "MediaUtils.h"
@@ -49,6 +51,10 @@
 
     signal(SIGPIPE, SIG_IGN);
 
+    // Do not assist platform profilers (relevant only on debug builds).
+    // Otherwise, the signal handler can violate the seccomp policy.
+    signal(BIONIC_SIGNAL_PROFILER, SIG_IGN);
+
     //b/62255959: this forces libutis.so to dlopen vendor version of libutils.so
     //before minijail is on. This is dirty but required since some syscalls such
     //as pread64 are used by linker but aren't allowed in the minijail. By
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 38f9be6..118072e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -41,6 +41,9 @@
 getgroups32: 1
 nanosleep: 1
 getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
 
 # for dynamically loading extractors
 pread64: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index 8fd8787..481e29e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -30,6 +30,9 @@
 getrlimit: 1
 nanosleep: 1
 getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
 
 # for FileSource
 readlinkat: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index 05915d1..15fb24e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -39,6 +39,9 @@
 getgroups32: 1
 nanosleep: 1
 getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
 
 # for dynamically loading extractors
 getdents64: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
index e6a55d0..4f2646c 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -34,6 +34,9 @@
 getrlimit: 1
 nanosleep: 1
 getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
 
 # for dynamically loading extractors
 getdents64: 1
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index 0440e5b..e048d0e 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -56,7 +56,8 @@
  * The TimeMachine is used to record timing changes of MediaAnalyticItem
  * properties.
  *
- * Any URL that ends with '!' will have a time sequence that keeps duplicates.
+ * Any URL that ends with '#' (AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED)
+ * will have a time sequence that keeps duplicates.
  *
  * The TimeMachine is NOT thread safe.
  */
@@ -126,7 +127,7 @@
             auto& timeSequence = mPropertyMap[property];
             Elem el{std::forward<T>(e)};
             if (timeSequence.empty()           // no elements
-                    || property.back() == '!'  // keep duplicates TODO: remove?
+                    || property.back() == AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED
                     || timeSequence.rbegin()->second != el) { // value changed
                 timeSequence.emplace(time, std::move(el));
             }
diff --git a/services/mediametrics/statsd_drm.cpp b/services/mediametrics/statsd_drm.cpp
index b12f4f3..4f2e861 100644
--- a/services/mediametrics/statsd_drm.cpp
+++ b/services/mediametrics/statsd_drm.cpp
@@ -35,6 +35,9 @@
 
 #include <statslog.h>
 
+#include <array>
+#include <string>
+
 namespace android {
 
 // mediadrm
@@ -107,8 +110,14 @@
 // drmmanager
 bool statsd_drmmanager(const mediametrics::Item *item)
 {
+    using namespace std::string_literals;
     if (item == NULL) return false;
 
+    if (!enabled_statsd) {
+        ALOGV("NOT sending: drmmanager data");
+        return true;
+    }
+
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
@@ -123,16 +132,22 @@
     char *mime_types = NULL;
     (void) item->getCString("mime_types", &mime_types);
 
-    if (enabled_statsd) {
-        android::util::stats_write(android::util::MEDIAMETRICS_DRMMANAGER_REPORTED,
-                                   timestamp, pkgName.c_str(), pkgVersionCode,
-                                   mediaApexVersion,
-                                   plugin_id, description,
-                                   method_id, mime_types);
-    } else {
-        ALOGV("NOT sending: drmmanager data");
+    // Corresponds to the 13 APIs tracked in the MediametricsDrmManagerReported statsd proto
+    // Please see also DrmManager::kMethodIdMap
+    std::array<int64_t, 13> methodCounts{};
+    for (size_t i = 0; i < methodCounts.size() ; i++) {
+        item->getInt64(("method"s + std::to_string(i)).c_str(), &methodCounts[i]);
     }
 
+    android::util::stats_write(android::util::MEDIAMETRICS_DRMMANAGER_REPORTED,
+                               timestamp, pkgName.c_str(), pkgVersionCode, mediaApexVersion,
+                               plugin_id, description, method_id, mime_types,
+                               methodCounts[0], methodCounts[1], methodCounts[2],
+                               methodCounts[3], methodCounts[4], methodCounts[5],
+                               methodCounts[6], methodCounts[7], methodCounts[8],
+                               methodCounts[9], methodCounts[10], methodCounts[11],
+                               methodCounts[12]);
+
     free(plugin_id);
     free(description);
     free(mime_types);