Merge changes from topic "volume_fixes"

* changes:
  audio policy: add call assistant volume stream
  [AudioPolicy] fix volume regression
  [AudioPolicy][Engine] Attributes of strategy not populated
  Revert "Revert "[audiopolicy][enginebase] Fix schema verification""
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/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/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/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/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/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);