AudioFlinger: revert adjust standby delay on VOIP RX output am: 0ca47c2bf2 am: 66c2205bb0 am: 4708f16cc5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/23531926

Change-Id: Ib8ae94a26caff6d3abd600a66088208fffb3d0af
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index d064123..cee44b9 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -126,7 +126,6 @@
     static_libs: [
         "libmediautils",
         "liblog",
-        "libdl",
         "libdrmframeworkcommon",
         "libselinux",
         "libstagefright_foundation",
@@ -144,4 +143,4 @@
              "android-drm-team@google.com",
          ],
      },
-}
\ No newline at end of file
+}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 881c74e..156cec1 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1598,7 +1598,8 @@
         watcher->inputDelay(inputDelayValue)
                 .pipelineDelay(pipelineDelayValue)
                 .outputDelay(outputDelayValue)
-                .smoothnessFactor(kSmoothnessFactor);
+                .smoothnessFactor(kSmoothnessFactor)
+                .tunneled(mTunneled);
         watcher->flush();
     }
 
@@ -2007,6 +2008,7 @@
             newInputDelay.value_or(input->inputDelay) +
             newPipelineDelay.value_or(input->pipelineDelay) +
             kSmoothnessFactor;
+        input->inputDelay = newInputDelay.value_or(input->inputDelay);
         if (input->buffers->isArrayMode()) {
             if (input->numSlots >= newNumSlots) {
                 input->numExtraSlots = 0;
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 82c31a8..228ad7e 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -478,19 +478,56 @@
                 mInitCheck = NO_INIT;
                 return;
             case C2PlanarLayout::TYPE_RGB:
-                ALOGD("Converter: unrecognized color format "
-                        "(client %d component %d) for RGB layout",
-                        mClientColorFormat, mComponentColorFormat);
-                mInitCheck = NO_INIT;
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB;
                 // TODO: support MediaImage layout
-                return;
+                switch (mClientColorFormat) {
+                    case COLOR_FormatSurface:
+                    case COLOR_FormatRGBFlexible:
+                    case COLOR_Format24bitBGR888:
+                    case COLOR_Format24bitRGB888:
+                        ALOGD("Converter: accept color format "
+                                "(client %d component %d) for RGB layout",
+                                mClientColorFormat, mComponentColorFormat);
+                        break;
+                    default:
+                        ALOGD("Converter: unrecognized color format "
+                                "(client %d component %d) for RGB layout",
+                                mClientColorFormat, mComponentColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 3) {
+                    ALOGD("Converter: %d planes for RGB layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
             case C2PlanarLayout::TYPE_RGBA:
-                ALOGD("Converter: unrecognized color format "
-                        "(client %d component %d) for RGBA layout",
-                        mClientColorFormat, mComponentColorFormat);
-                mInitCheck = NO_INIT;
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA;
                 // TODO: support MediaImage layout
-                return;
+                switch (mClientColorFormat) {
+                    case COLOR_FormatSurface:
+                    case COLOR_FormatRGBAFlexible:
+                    case COLOR_Format32bitABGR8888:
+                    case COLOR_Format32bitARGB8888:
+                    case COLOR_Format32bitBGRA8888:
+                        ALOGD("Converter: accept color format "
+                                "(client %d component %d) for RGBA layout",
+                                mClientColorFormat, mComponentColorFormat);
+                        break;
+                    default:
+                        ALOGD("Converter: unrecognized color format "
+                                "(client %d component %d) for RGBA layout",
+                                mClientColorFormat, mComponentColorFormat);
+                        mInitCheck = BAD_VALUE;
+                        return;
+                }
+                if (layout.numPlanes != 4) {
+                    ALOGD("Converter: %d planes for RGBA layout", layout.numPlanes);
+                    mInitCheck = BAD_VALUE;
+                    return;
+                }
+                break;
             default:
                 mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
                 if (layout.numPlanes == 1) {
diff --git a/media/codec2/sfplugin/PipelineWatcher.cpp b/media/codec2/sfplugin/PipelineWatcher.cpp
index bc9197c..fa70a28 100644
--- a/media/codec2/sfplugin/PipelineWatcher.cpp
+++ b/media/codec2/sfplugin/PipelineWatcher.cpp
@@ -45,6 +45,11 @@
     return *this;
 }
 
+PipelineWatcher &PipelineWatcher::tunneled(bool value) {
+    mTunneled = value;
+    return *this;
+}
+
 void PipelineWatcher::onWorkQueued(
         uint64_t frameIndex,
         std::vector<std::shared_ptr<C2Buffer>> &&buffers,
@@ -87,8 +92,13 @@
     ALOGV("onWorkDone(frameIndex=%llu)", (unsigned long long)frameIndex);
     auto it = mFramesInPipeline.find(frameIndex);
     if (it == mFramesInPipeline.end()) {
-        ALOGD("onWorkDone: frameIndex not found (%llu); ignored",
-              (unsigned long long)frameIndex);
+        if (!mTunneled) {
+            ALOGD("onWorkDone: frameIndex not found (%llu); ignored",
+                  (unsigned long long)frameIndex);
+        } else {
+            ALOGV("onWorkDone: frameIndex not found (%llu); ignored",
+                  (unsigned long long)frameIndex);
+        }
         return;
     }
     (void)mFramesInPipeline.erase(it);
diff --git a/media/codec2/sfplugin/PipelineWatcher.h b/media/codec2/sfplugin/PipelineWatcher.h
index 1e23147..b29c7cd 100644
--- a/media/codec2/sfplugin/PipelineWatcher.h
+++ b/media/codec2/sfplugin/PipelineWatcher.h
@@ -37,7 +37,8 @@
         : mInputDelay(0),
           mPipelineDelay(0),
           mOutputDelay(0),
-          mSmoothnessFactor(0) {}
+          mSmoothnessFactor(0),
+          mTunneled(false) {}
     ~PipelineWatcher() = default;
 
     /**
@@ -65,6 +66,12 @@
     PipelineWatcher &smoothnessFactor(uint32_t value);
 
     /**
+     * \param value the new tunneled value
+     * \return  this object
+     */
+    PipelineWatcher &tunneled(bool value);
+
+    /**
      * Client queued a work item to the component.
      *
      * \param frameIndex  input frame index of this work
@@ -122,6 +129,7 @@
     uint32_t mPipelineDelay;
     uint32_t mOutputDelay;
     uint32_t mSmoothnessFactor;
+    bool mTunneled;
 
     struct Frame {
         Frame(std::vector<std::shared_ptr<C2Buffer>> &&b,
diff --git a/media/libaudiohal/impl/EffectProxy.cpp b/media/libaudiohal/impl/EffectProxy.cpp
index b61532d..3bb045b 100644
--- a/media/libaudiohal/impl/EffectProxy.cpp
+++ b/media/libaudiohal/impl/EffectProxy.cpp
@@ -20,6 +20,7 @@
 //#define LOG_NDEBUG 0
 
 #include <fmq/AidlMessageQueue.h>
+#include <system/audio_aidl_utils.h>
 #include <utils/Log.h>
 
 #include "EffectProxy.h"
@@ -32,6 +33,7 @@
 using ::aidl::android::hardware::audio::effect::Parameter;
 using ::aidl::android::hardware::audio::effect::State;
 using ::aidl::android::media::audio::common::AudioUuid;
+using ::android::audio::utils::toString;
 
 namespace android {
 namespace effect {
@@ -54,7 +56,7 @@
 
 // sub effect must have same proxy UUID as EffectProxy, and the type UUID must match.
 ndk::ScopedAStatus EffectProxy::addSubEffect(const Descriptor& sub) {
-    ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
     if (0 != mSubEffects.count(sub.common.id) || !sub.common.id.proxy.has_value() ||
         sub.common.id.proxy.value() != mIdentity.uuid) {
         ALOGE("%s sub effect already exist or mismatch %s", __func__, sub.toString().c_str());
@@ -92,15 +94,15 @@
 }
 
 ndk::ScopedAStatus EffectProxy::create() {
-    ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
     ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
 
     for (auto& sub : mSubEffects) {
         auto& effectHandle = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
-        ALOGI("%s sub-effect %s", __func__, sub.first.uuid.toString().c_str());
+        ALOGI("%s sub-effect %s", __func__, toString(sub.first.uuid).c_str());
         status = mFactory->createEffect(sub.first.uuid, &effectHandle);
         if (!status.isOk() || !effectHandle) {
-            ALOGE("%s sub-effect failed %s", __func__, sub.first.uuid.toString().c_str());
+            ALOGE("%s sub-effect failed %s", __func__, toString(sub.first.uuid).c_str());
             break;
         }
     }
@@ -113,7 +115,7 @@
 }
 
 ndk::ScopedAStatus EffectProxy::destroy() {
-    ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
     return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
         ndk::ScopedAStatus status = mFactory->destroyEffect(effect);
         if (status.isOk()) {
@@ -131,7 +133,7 @@
     const auto& itor = std::find_if(mSubEffects.begin(), mSubEffects.end(), [&](const auto& sub) {
         const auto& desc = std::get<SubEffectTupleIndex::DESCRIPTOR>(sub.second);
         ALOGI("%s: isOffload %d sub-effect: %s, flags %s", __func__, offload->isOffload,
-              desc.common.id.uuid.toString().c_str(), desc.common.flags.toString().c_str());
+              toString(desc.common.id.uuid).c_str(), desc.common.flags.toString().c_str());
         return offload->isOffload ==
                (desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL);
     });
@@ -143,7 +145,7 @@
 
     mActiveSub = itor->first;
     ALOGI("%s: active %soffload sub-effect: %s, flags %s", __func__,
-          offload->isOffload ? "" : "non-", mActiveSub.uuid.toString().c_str(),
+          offload->isOffload ? "" : "non-", toString(mActiveSub.uuid).c_str(),
           std::get<SubEffectTupleIndex::DESCRIPTOR>(itor->second).common.flags.toString().c_str());
     return ndk::ScopedAStatus::ok();
 }
@@ -152,14 +154,14 @@
 ndk::ScopedAStatus EffectProxy::open(const Parameter::Common& common,
                                      const std::optional<Parameter::Specific>& specific,
                                      IEffect::OpenEffectReturn* ret __unused) {
-    ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
     ndk::ScopedAStatus status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
             EX_ILLEGAL_ARGUMENT, "nullEffectHandle");
     for (auto& sub : mSubEffects) {
         auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
         auto& openRet = std::get<SubEffectTupleIndex::RETURN>(sub.second);
         if (!effect || !(status = effect->open(common, specific, &openRet)).isOk()) {
-            ALOGE("%s: failed to open UUID %s", __func__, sub.first.uuid.toString().c_str());
+            ALOGE("%s: failed to open UUID %s", __func__, toString(sub.first.uuid).c_str());
             break;
         }
     }
@@ -173,7 +175,7 @@
 }
 
 ndk::ScopedAStatus EffectProxy::close() {
-    ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
     return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
         return effect->close();
     });
@@ -203,7 +205,7 @@
 
 // Handle with active sub-effect first, only send to other sub-effects when success
 ndk::ScopedAStatus EffectProxy::command(CommandId id) {
-    ALOGV("%s: %s, command %s", __func__, mIdentity.type.toString().c_str(),
+    ALOGV("%s: %s, command %s", __func__, toString(mIdentity.type).c_str(),
           android::internal::ToString(id).c_str());
     return runWithActiveSubEffectThenOthers(
             [&](const std::shared_ptr<IEffect>& effect) -> ndk::ScopedAStatus {
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 7b9088e..f278ca0 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -28,6 +28,7 @@
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionEffect.h>
 #include <system/audio.h>
+#include <system/audio_aidl_utils.h>
 #include <utils/Log.h>
 
 #include "EffectBufferHalAidl.h"
@@ -43,6 +44,7 @@
 using ::aidl::android::media::audio::common::AudioSource;
 using ::aidl::android::media::audio::common::AudioStreamType;
 using ::aidl::android::media::audio::common::AudioUuid;
+using ::android::audio::utils::toString;
 using ::android::base::unexpected;
 using ::android::detail::AudioHalVersionInfo;
 
@@ -188,7 +190,7 @@
                 statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
     }
     if (aidlEffect == nullptr) {
-        ALOGE("%s failed to create effect with UUID: %s", __func__, aidlUuid.toString().c_str());
+        ALOGE("%s failed to create effect with UUID: %s", __func__, toString(aidlUuid).c_str());
         return NAME_NOT_FOUND;
     }
     Descriptor desc;
@@ -244,10 +246,10 @@
     auto matchIt = std::find_if(list.begin(), list.end(),
                                 [&](const auto& desc) { return desc.common.id.uuid == uuid; });
     if (matchIt == list.end()) {
-        ALOGE("%s UUID not found in HAL and proxy list %s", __func__, uuid.toString().c_str());
+        ALOGE("%s UUID not found in HAL and proxy list %s", __func__, toString(uuid).c_str());
         return BAD_VALUE;
     }
-    ALOGI("%s UUID impl found %s", __func__, uuid.toString().c_str());
+    ALOGI("%s UUID impl found %s", __func__, toString(uuid).c_str());
 
     *pDescriptor = VALUE_OR_RETURN_STATUS(
             ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
@@ -266,10 +268,10 @@
     std::copy_if(mProxyDescList.begin(), mProxyDescList.end(), std::back_inserter(result),
                  [&](auto& desc) { return desc.common.id.type == type; });
     if (result.empty()) {
-        ALOGW("%s UUID type not found in HAL and proxy list %s", __func__, type.toString().c_str());
+        ALOGW("%s UUID type not found in HAL and proxy list %s", __func__, toString(type).c_str());
         return BAD_VALUE;
     }
-    ALOGI("%s UUID type found %zu \n %s", __func__, result.size(), type.toString().c_str());
+    ALOGI("%s UUID type found %zu \n %s", __func__, result.size(), toString(type).c_str());
 
     *descriptors = VALUE_OR_RETURN_STATUS(
             aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
index 309765a..6160d7d 100644
--- a/media/libaudioprocessing/Android.bp
+++ b/media/libaudioprocessing/Android.bp
@@ -72,6 +72,10 @@
     ],
 
     whole_static_libs: ["libaudioprocessing_base"],
+
+    export_shared_lib_headers: [
+        "libvibrator",
+    ],
 }
 
 cc_library_static {
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
index e23530e..a1de7b3 100644
--- a/media/libeffects/factory/EffectsConfigLoader.c
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -137,7 +137,7 @@
                  kLibraryPathRoot[i],
                  lib_name);
         if (F_OK == access(path, 0)) {
-            strcpy(lib_path_out, path);
+            strlcpy(lib_path_out, path, PATH_MAX);
             ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
                 "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
             return 0;
diff --git a/media/libeffects/factory/test/DumpConfig.cpp b/media/libeffects/factory/test/DumpConfig.cpp
index 0a156b4..331826f 100644
--- a/media/libeffects/factory/test/DumpConfig.cpp
+++ b/media/libeffects/factory/test/DumpConfig.cpp
@@ -14,54 +14,49 @@
  * limitations under the License.
  */
 
+#include <getopt.h>
+
 #include <media/EffectsFactoryApi.h>
-#include <unistd.h>
 #include "EffectsXmlConfigLoader.h"
 #include "EffectsConfigLoader.h"
 
 int main(int argc, char* argv[]) {
-    const char* path = nullptr;
-    bool legacyFormat;
+    const char* const short_opts = "lx:h";
+    const option long_opts[] = {{"legacy", no_argument, nullptr, 'l'},
+                                {"xml", optional_argument, nullptr, 'x'},
+                                {"help", no_argument, nullptr, 'h'}};
 
-    if (argc == 2 && strcmp(argv[1], "--legacy") == 0) {
-        legacyFormat = true;
-        fprintf(stderr, "Dumping legacy effect config file\n");
-    } else if ((argc == 2 || argc == 3) && strcmp(argv[1], "--xml") == 0) {
-        legacyFormat = false;
-        if (argc == 3) {
-            fprintf(stderr, "Dumping XML effect config file: %s\n", path);
-        } else {
-            fprintf(stderr, "Dumping default XML effect config file.\n");
+    const auto opt = getopt_long(argc, argv, short_opts, long_opts, nullptr);
+    switch (opt) {
+        case 'l': { // -l or --legacy
+            printf("Dumping legacy effect config file\n");
+            if (EffectLoadEffectConfig() < 0) {
+                fprintf(stderr, "loadEffectConfig failed, see logcat for detail.\n");
+                return 1;
+            }
+            return EffectDumpEffects(STDOUT_FILENO);
         }
-    } else {
-        fprintf(stderr, "Invalid arguments.\n"
-                        "Usage: %s [--legacy|--xml [FILE]]\n", argv[0]);
-        return 1;
-    }
-
-    if (!legacyFormat) {
-        ssize_t ret = EffectLoadXmlEffectConfig(path);
-        if (ret < 0) {
-            fprintf(stderr, "loadXmlEffectConfig failed, see logcat for detail.\n");
-            return 2;
+        case 'x': { // -x or --xml
+            printf("Dumping effect config file: %s\n", (optarg == NULL) ? "default" : optarg);
+            ssize_t ret = EffectLoadXmlEffectConfig(optarg);
+            if (ret < 0) {
+                fprintf(stderr, "loadXmlEffectConfig failed, see logcat for detail.\n");
+                return 1;
+            }
+            if (ret > 0) {
+                printf("Partially failed to load config. Skipped %zu elements.\n",
+                        (size_t)ret);
+            }
+            return EffectDumpEffects(STDOUT_FILENO);
         }
-        if (ret > 0) {
-            fprintf(stderr, "Partially failed to load config. Skipped %zu elements, "
-                    "see logcat for detail.\n", (size_t)ret);
+        case 'h': // -h or --help
+        default: {
+            printf("Usage: %s\n"
+                   "--legacy (or -l):        Legacy audio effect config file to load\n"
+                   "--xml (or -x) <FILE>:    Audio effect config file to load\n"
+                   "--help (or -h):          Show this help\n",
+                   argv[0]);
+            return 0;
         }
     }
-
-    if (legacyFormat) {
-        auto ret = EffectLoadEffectConfig();
-        if (ret < 0) {
-            fprintf(stderr, "loadEffectConfig failed, see logcat for detail.\n");
-            return 3;
-        }
-        fprintf(stderr, "legacy loadEffectConfig has probably succeed, see logcat to make sure.\n");
-    }
-
-    if (EffectDumpEffects(STDOUT_FILENO) != 0) {
-        fprintf(stderr, "Effect dump failed, see logcat for detail.\n");
-        return 4;
-    }
 }
diff --git a/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
index e8ac480..e2177db 100644
--- a/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
+++ b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
@@ -31,6 +31,7 @@
                 (audio_effect_library_t*)dlsym(effectLib, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
         if (effectInterface == nullptr) {
             ALOGE("dlsym failed: %s", dlerror());
+            dlclose(effectLib);
             exit(-1);
         }
         symbol = (audio_effect_library_t)(*effectInterface);
diff --git a/media/libeffects/spatializer/tests/SpatializerTest.cpp b/media/libeffects/spatializer/tests/SpatializerTest.cpp
index 110fbb1..3db42b6 100644
--- a/media/libeffects/spatializer/tests/SpatializerTest.cpp
+++ b/media/libeffects/spatializer/tests/SpatializerTest.cpp
@@ -30,6 +30,7 @@
                 (audio_effect_library_t*)dlsym(effectLib, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
         if (effectInterface == nullptr) {
             ALOGE("dlsym failed: %s", dlerror());
+            dlclose(effectLib);
             exit(-1);
         }
         symbol = (audio_effect_library_t)(*effectInterface);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index e5f2b2b..485923f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2224,6 +2224,11 @@
                 -ret, strerror(-ret));
             return ret;
         }
+        if (mVideoDecoder != NULL) {
+            sp<AMessage> params = new AMessage();
+            params->setInt32("android._video-scaling", mode);
+            mVideoDecoder->setParameters(params);
+        }
     }
     return OK;
 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 8da09c4..f4143da 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -459,6 +459,14 @@
         codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
         mCodec->setParameters(codecParams);
     }
+
+    int32_t videoScalingMode;
+    if (params->findInt32("android._video-scaling", &videoScalingMode)
+            && mCodec != NULL) {
+        sp<AMessage> codecParams = new AMessage();
+        codecParams->setInt32("android._video-scaling", videoScalingMode);
+        mCodec->setParameters(codecParams);
+    }
 }
 
 void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 9dae16e..bcb4756 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -157,7 +157,8 @@
       mTotalBuffersQueued(0),
       mLastAudioBufferDrained(0),
       mUseAudioCallback(false),
-      mWakeLock(new AWakeLock()) {
+      mWakeLock(new AWakeLock()),
+      mNeedVideoClearAnchor(false) {
     CHECK(mediaClock != NULL);
     mPlaybackRate = mPlaybackSettings.mSpeed;
     mMediaClock->setPlaybackRate(mPlaybackRate);
@@ -234,6 +235,10 @@
             return err;
         }
     }
+
+    if (!mHasAudio && mHasVideo) {
+        mNeedVideoClearAnchor = true;
+    }
     mPlaybackSettings = rate;
     mPlaybackRate = rate.mSpeed;
     mMediaClock->setPlaybackRate(mPlaybackRate);
@@ -327,7 +332,6 @@
             mNextVideoTimeMediaUs = -1;
         }
 
-        mMediaClock->clearAnchor();
         mVideoLateByUs = 0;
         mSyncQueues = false;
     }
@@ -1371,6 +1375,10 @@
 
     {
         Mutex::Autolock autoLock(mLock);
+        if (mNeedVideoClearAnchor && !mHasAudio) {
+            mNeedVideoClearAnchor = false;
+            clearAnchorTime();
+        }
         if (mAnchorTimeMediaUs < 0) {
             mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs);
             mAnchorTimeMediaUs = mediaTimeUs;
@@ -1525,6 +1533,8 @@
                         mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
             }
         }
+    } else {
+        mHasVideo = false;
     }
 }
 
@@ -1686,6 +1696,7 @@
         } else {
             notifyComplete = mNotifyCompleteVideo;
             mNotifyCompleteVideo = false;
+            mHasVideo = false;
         }
 
         // If we're currently syncing the queues, i.e. dropping audio while
@@ -1698,7 +1709,17 @@
         // is flushed.
         syncQueuesDone_l();
     }
-    clearAnchorTime();
+
+    if (audio && mDrainVideoQueuePending) {
+        // Audio should not clear anchor(MediaClock) directly, because video
+        // postDrainVideoQueue sets msg kWhatDrainVideoQueue into MediaClock
+        // timer, clear anchor without update immediately may block msg posting.
+        // So, postpone clear action to video to ensure anchor can be updated
+        // immediately after clear
+        mNeedVideoClearAnchor = true;
+    } else {
+        clearAnchorTime();
+    }
 
     ALOGV("flushing %s", audio ? "audio" : "video");
     if (audio) {
diff --git a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
index 2ca040f..f0c0a35 100644
--- a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
@@ -332,6 +332,9 @@
     int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames);
 
     DISALLOW_EVIL_CONSTRUCTORS(Renderer);
+
+private:
+    bool mNeedVideoClearAnchor;
 };
 
 } // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 505775b..a91b24a 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -293,6 +293,8 @@
         }
     }
 
+    void setSurfaceParameters(const sp<AMessage> &msg);
+
 private:
     // Handles an OMX message. Returns true iff message was handled.
     bool onOMXMessage(const sp<AMessage> &msg);
@@ -6511,6 +6513,59 @@
     postFillThisBuffer(eligible);
 }
 
+void ACodec::BaseState::setSurfaceParameters(const sp<AMessage> &msg) {
+    sp<AMessage> params;
+    CHECK(msg->findMessage("params", &params));
+
+    status_t err = mCodec->setSurfaceParameters(params);
+    if (err != OK) {
+        ALOGE("[%s] Unable to set input surface parameters (err %d)",
+                mCodec->mComponentName.c_str(),
+                err);
+        return;
+    }
+
+    int64_t timeOffsetUs;
+    if (params->findInt64(PARAMETER_KEY_OFFSET_TIME, &timeOffsetUs)) {
+        params->removeEntryAt(params->findEntryByName(PARAMETER_KEY_OFFSET_TIME));
+
+        if (params->countEntries() == 0) {
+            msg->removeEntryAt(msg->findEntryByName("params"));
+            return;
+        }
+    }
+
+    int64_t skipFramesBeforeUs;
+    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
+        params->removeEntryAt(params->findEntryByName("skip-frames-before"));
+
+        if (params->countEntries() == 0) {
+            msg->removeEntryAt(msg->findEntryByName("params"));
+            return;
+        }
+    }
+
+    int32_t dropInputFrames;
+    if (params->findInt32(PARAMETER_KEY_SUSPEND, &dropInputFrames)) {
+        params->removeEntryAt(params->findEntryByName(PARAMETER_KEY_SUSPEND));
+
+        if (params->countEntries() == 0) {
+            msg->removeEntryAt(msg->findEntryByName("params"));
+            return;
+        }
+    }
+
+    int64_t stopTimeUs;
+    if (params->findInt64("stop-time-us", &stopTimeUs)) {
+        params->removeEntryAt(params->findEntryByName("stop-time-us"));
+
+        if (params->countEntries() == 0) {
+            msg->removeEntryAt(msg->findEntryByName("params"));
+            return;
+        }
+    }
+}
+
 bool ACodec::BaseState::onOMXFillBufferDone(
         IOMX::buffer_id bufferID,
         size_t rangeOffset, size_t rangeLength,
@@ -7411,6 +7466,13 @@
 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatSetParameters:
+        {
+            BaseState::setSurfaceParameters(msg);
+            if (msg->countEntries() > 0) {
+                mCodec->deferMessage(msg);
+            }
+            return true;
+        }
         case kWhatShutdown:
         {
             mCodec->deferMessage(msg);
@@ -7487,6 +7549,13 @@
 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatSetParameters:
+        {
+            BaseState::setSurfaceParameters(msg);
+            if (msg->countEntries() > 0) {
+                mCodec->deferMessage(msg);
+            }
+            return true;
+        }
         case kWhatShutdown:
         {
             mCodec->deferMessage(msg);
@@ -7766,27 +7835,7 @@
     return handled;
 }
 
-status_t ACodec::setParameters(const sp<AMessage> &params) {
-    int32_t videoBitrate;
-    if (params->findInt32("video-bitrate", &videoBitrate)) {
-        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
-        InitOMXParams(&configParams);
-        configParams.nPortIndex = kPortIndexOutput;
-        configParams.nEncodeBitrate = videoBitrate;
-
-        status_t err = mOMXNode->setConfig(
-                OMX_IndexConfigVideoBitrate,
-                &configParams,
-                sizeof(configParams));
-
-        if (err != OK) {
-            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
-                   videoBitrate, err);
-
-            return err;
-        }
-    }
-
+status_t ACodec::setSurfaceParameters(const sp<AMessage> &params) {
     int64_t timeOffsetUs;
     if (params->findInt64(PARAMETER_KEY_OFFSET_TIME, &timeOffsetUs)) {
         if (mGraphicBufferSource == NULL) {
@@ -7874,9 +7923,41 @@
         mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
     }
 
+    return OK;
+}
+
+status_t ACodec::setParameters(const sp<AMessage> &params) {
+    status_t err;
+
+    int32_t videoBitrate;
+    if (params->findInt32("video-bitrate", &videoBitrate)) {
+        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
+        InitOMXParams(&configParams);
+        configParams.nPortIndex = kPortIndexOutput;
+        configParams.nEncodeBitrate = videoBitrate;
+
+        err = mOMXNode->setConfig(
+                OMX_IndexConfigVideoBitrate,
+                &configParams,
+                sizeof(configParams));
+
+        if (err != OK) {
+            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
+                   videoBitrate, err);
+
+            return err;
+        }
+    }
+
+    err = setSurfaceParameters(params);
+    if (err != OK) {
+        ALOGE("Failed to set input surface parameters (err %d)", err);
+        return err;
+    }
+
     int32_t tmp;
     if (params->findInt32("request-sync", &tmp)) {
-        status_t err = requestIDRFrame();
+        err = requestIDRFrame();
 
         if (err != OK) {
             ALOGE("Requesting a sync frame failed w/ err %d", err);
@@ -7891,7 +7972,7 @@
         rateFloat = (float) rateInt; // 16MHz (FLINTMAX) is OK for upper bound.
     }
     if (rateFloat > 0) {
-        status_t err = setOperatingRate(rateFloat, mIsVideo);
+        err = setOperatingRate(rateFloat, mIsVideo);
         if (err != OK) {
             ALOGI("Failed to set parameter 'operating-rate' (err %d)", err);
         }
@@ -7900,7 +7981,7 @@
     int32_t intraRefreshPeriod = 0;
     if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
             && intraRefreshPeriod > 0) {
-        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
+        err = setIntraRefreshPeriod(intraRefreshPeriod, false);
         if (err != OK) {
             ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
                     mComponentName.c_str());
@@ -7910,7 +7991,7 @@
 
     int32_t lowLatency = 0;
     if (params->findInt32("low-latency", &lowLatency)) {
-        status_t err = setLowLatency(lowLatency);
+        err = setLowLatency(lowLatency);
         if (err != OK) {
             return err;
         }
@@ -7918,7 +7999,7 @@
 
     int32_t latency = 0;
     if (params->findInt32("latency", &latency) && latency > 0) {
-        status_t err = setLatency(latency);
+        err = setLatency(latency);
         if (err != OK) {
             ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
                     mComponentName.c_str());
@@ -7930,7 +8011,7 @@
     if (params->findInt32("audio-presentation-presentation-id", &presentationId)) {
         int32_t programId = -1;
         params->findInt32("audio-presentation-program-id", &programId);
-        status_t err = setAudioPresentation(presentationId, programId);
+        err = setAudioPresentation(presentationId, programId);
         if (err != OK) {
             ALOGI("[%s] failed setAudioPresentation. Failure is fine since this key is optional",
                     mComponentName.c_str());
@@ -8003,7 +8084,7 @@
     {
         int32_t tunnelPeek = 0;
         if (params->findInt32(TUNNEL_PEEK_KEY, &tunnelPeek)) {
-            status_t err = setTunnelPeek(tunnelPeek);
+            err = setTunnelPeek(tunnelPeek);
             if (err != OK) {
                 return err;
             }
@@ -8012,7 +8093,7 @@
     {
         int32_t tunnelPeekSetLegacy = 0;
         if (params->findInt32(TUNNEL_PEEK_SET_LEGACY_KEY, &tunnelPeekSetLegacy)) {
-            status_t err = setTunnelPeekLegacy(tunnelPeekSetLegacy);
+            err = setTunnelPeekLegacy(tunnelPeekSetLegacy);
             if (err != OK) {
                 return err;
             }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index c93d033..3579d9e 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -31,7 +31,6 @@
 #include <utils/Log.h>
 
 #include <functional>
-#include <fcntl.h>
 
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -564,6 +563,10 @@
     mResetStatus = OK;
     mPreAllocFirstTime = true;
     mPrevAllTracksTotalMetaDataSizeEstimate = 0;
+    mIsFirstChunk = false;
+    mDone = false;
+    mThread = 0;
+    mDriftTimeUs = 0;
 
     // Following variables only need to be set for the first recording session.
     // And they will stay the same for all the recording sessions.
diff --git a/media/libstagefright/VideoFrameSchedulerBase.cpp b/media/libstagefright/VideoFrameSchedulerBase.cpp
index 0d1517b..965014c 100644
--- a/media/libstagefright/VideoFrameSchedulerBase.cpp
+++ b/media/libstagefright/VideoFrameSchedulerBase.cpp
@@ -451,7 +451,7 @@
                 return origRenderTime;
             }
 
-            ATRACE_INT("FRAME_VSYNCS", vsyncsForLastFrame);
+            ATRACE_INT64("FRAME_VSYNCS", vsyncsForLastFrame);
         }
         mLastVsyncTime = nextVsyncTime;
     }
@@ -460,7 +460,7 @@
     renderTime -= (renderTime - mVsyncTime) % mVsyncPeriod;
     renderTime += mVsyncPeriod / 2;
     ALOGV("adjusting render: %lld => %lld", (long long)origRenderTime, (long long)renderTime);
-    ATRACE_INT("FRAME_FLIP_IN(ms)", (renderTime - now) / 1000000);
+    ATRACE_INT64("FRAME_FLIP_IN(ms)", (renderTime - now) / 1000000);
     return renderTime;
 }
 
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 08c7917..e535d5d 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -603,6 +603,7 @@
             status_t internalError = UNKNOWN_ERROR);
 
     status_t requestIDRFrame();
+    status_t setSurfaceParameters(const sp<AMessage> &params);
     status_t setParameters(const sp<AMessage> &params);
 
     // set vendor extension parameters specified in params that are supported by the codec
diff --git a/media/libstagefright/tests/HEVC/AndroidTest.xml b/media/libstagefright/tests/HEVC/AndroidTest.xml
index ff850a2..00bb3e5 100644
--- a/media/libstagefright/tests/HEVC/AndroidTest.xml
+++ b/media/libstagefright/tests/HEVC/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="false" />
         <option name="push" value="HEVCUtilsUnitTest->/data/local/tmp/HEVCUtilsUnitTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest.zip?unzip=true"
-            value="/data/local/tmp/HEVCUtilsUnitTest/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="HEVCUtilsUnitTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="HEVCUtilsUnitTest-1.0" />
+        <option name="dynamic-config-module" value="HEVCUtilsUnitTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="HEVCUtilsUnitTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/HEVCUtilsUnitTest/" />
+        <option name="native-test-flag" value="-P /sdcard/tests/HEVCUtilsUnitTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/libstagefright/tests/HEVC/DynamicConfig.xml b/media/libstagefright/tests/HEVC/DynamicConfig.xml
new file mode 100644
index 0000000..517449c
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/libstagefright/tests/extractorFactory/AndroidTest.xml b/media/libstagefright/tests/extractorFactory/AndroidTest.xml
index 3aa6392..f1d4201 100644
--- a/media/libstagefright/tests/extractorFactory/AndroidTest.xml
+++ b/media/libstagefright/tests/extractorFactory/AndroidTest.xml
@@ -18,14 +18,21 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="ExtractorFactoryTest->/data/local/tmp/ExtractorFactoryTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip?unzip=true"
-            value="/data/local/tmp/ExtractorFactoryTestRes/" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="ExtractorFactoryTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="extractor-1.5" />
+        <option name="dynamic-config-module" value="ExtractorFactoryTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="ExtractorFactoryTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/ExtractorFactoryTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/extractor-1.5/" />
     </test>
 </configuration>
diff --git a/media/libstagefright/tests/extractorFactory/DynamicConfig.xml b/media/libstagefright/tests/extractorFactory/DynamicConfig.xml
new file mode 100644
index 0000000..0258808
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.5.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/libstagefright/tests/writer/AndroidTest.xml b/media/libstagefright/tests/writer/AndroidTest.xml
index cc890fe..0b0eb01 100644
--- a/media/libstagefright/tests/writer/AndroidTest.xml
+++ b/media/libstagefright/tests/writer/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="writerTest->/data/local/tmp/writerTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes-1.1.zip?unzip=true"
-            value="/data/local/tmp/WriterTestRes/" />
     </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="writerTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="WriterTestRes-1.2" />
+        <option name="dynamic-config-module" value="writerTest" />
+    </target_preparer>
+
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="writerTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/WriterTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/WriterTestRes-1.2/" />
         <option name="native-test-flag" value="-C true" />
     </test>
 </configuration>
diff --git a/media/libstagefright/tests/writer/DynamicConfig.xml b/media/libstagefright/tests/writer/DynamicConfig.xml
new file mode 100644
index 0000000..e6dc502
--- /dev/null
+++ b/media/libstagefright/tests/writer/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes-1.2.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/libstagefright/timedtext/test/AndroidTest.xml b/media/libstagefright/timedtext/test/AndroidTest.xml
index 3654e23..0d5d79f 100644
--- a/media/libstagefright/timedtext/test/AndroidTest.xml
+++ b/media/libstagefright/timedtext/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="TimedTextUnitTest->/data/local/tmp/TimedTextUnitTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/timedtext/test/TimedTextUnitTest.zip?unzip=true"
-            value="/data/local/tmp/TimedTextUnitTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="TimedTextUnitTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="TimedTextUnitTest-1.0" />
+        <option name="dynamic-config-module" value="TimedTextUnitTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="TimedTextUnitTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/TimedTextUnitTestRes/" />
+        <option name="native-test-flag" value="-P /data/local/tmp/TimedTextUnitTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/libstagefright/timedtext/test/DynamicConfig.xml b/media/libstagefright/timedtext/test/DynamicConfig.xml
new file mode 100644
index 0000000..e36277e
--- /dev/null
+++ b/media/libstagefright/timedtext/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/timedtext/test/TimedTextUnitTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index afc873c..2f204f9 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -55,4 +55,5 @@
     name: "media_codecs",
     srcs: ["media_codecs.xsd"],
     package_name: "media.codecs",
+    root_elements: ["MediaCodecs"],
 }
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
index 95c347a..7de5955 100644
--- a/media/libstagefright/xmlparser/api/current.txt
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -171,7 +171,6 @@
 
   public class XmlParser {
     ctor public XmlParser();
-    method public static media.codecs.Included readIncluded(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static media.codecs.MediaCodecs readMediaCodecs(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
diff --git a/media/module/bqhelper/GraphicBufferSource.cpp b/media/module/bqhelper/GraphicBufferSource.cpp
index 3202cc5..4bb2215 100644
--- a/media/module/bqhelper/GraphicBufferSource.cpp
+++ b/media/module/bqhelper/GraphicBufferSource.cpp
@@ -589,7 +589,7 @@
 
 void GraphicBufferSource::onDataspaceChanged_l(
         android_dataspace dataspace, android_pixel_format pixelFormat) {
-    ALOGD("got buffer with new dataSpace #%x", dataspace);
+    ALOGD("got buffer with new dataSpace %#x", dataspace);
     mLastDataspace = dataspace;
 
     if (ColorUtils::convertDataSpaceToV0(dataspace)) {
diff --git a/media/module/codecs/amrnb/dec/test/AndroidTest.xml b/media/module/codecs/amrnb/dec/test/AndroidTest.xml
index 1a9e678..539fa5c 100644
--- a/media/module/codecs/amrnb/dec/test/AndroidTest.xml
+++ b/media/module/codecs/amrnb/dec/test/AndroidTest.xml
@@ -13,19 +13,27 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for Amr-nb Decoder unit test">
+<configuration description="Test module config for Amr-wb Decoder unit test">
     <option name="test-suite-tag" value="AmrnbDecoderTest" />
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="AmrnbDecoderTest->/data/local/tmp/AmrnbDecoderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest.zip?unzip=true"
-            value="/data/local/tmp/AmrnbDecoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="AmrnbDecoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="AmrnbDecoderTest-1.0" />
+        <option name="dynamic-config-module" value="AmrnbDecoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="AmrnbDecoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/AmrnbDecoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/AmrnbDecoderTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/amrnb/dec/test/DynamicConfig.xml b/media/module/codecs/amrnb/dec/test/DynamicConfig.xml
new file mode 100644
index 0000000..de81c48
--- /dev/null
+++ b/media/module/codecs/amrnb/dec/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/amrnb/enc/test/AndroidTest.xml b/media/module/codecs/amrnb/enc/test/AndroidTest.xml
index 9fe61b1..1509728 100644
--- a/media/module/codecs/amrnb/enc/test/AndroidTest.xml
+++ b/media/module/codecs/amrnb/enc/test/AndroidTest.xml
@@ -13,19 +13,27 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Test module config for Amr-nb Encoder unit test">
+<configuration description="Test module config for Amr-wb Encoder unit test">
     <option name="test-suite-tag" value="AmrnbEncoderTest" />
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="AmrnbEncoderTest->/data/local/tmp/AmrnbEncoderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/enc/test/AmrnbEncoderTest.zip?unzip=true"
-            value="/data/local/tmp/AmrnbEncoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="AmrnbEncoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="AmrnbEncoderTest-1.0" />
+        <option name="dynamic-config-module" value="AmrnbEncoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="AmrnbEncoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/AmrnbEncoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/AmrnbEncoderTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/amrnb/enc/test/DynamicConfig.xml b/media/module/codecs/amrnb/enc/test/DynamicConfig.xml
new file mode 100644
index 0000000..b22df38
--- /dev/null
+++ b/media/module/codecs/amrnb/enc/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrnb/enc/test/AmrnbEncoderTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/amrwb/dec/test/AndroidTest.xml b/media/module/codecs/amrwb/dec/test/AndroidTest.xml
index e211a1f..392df03 100644
--- a/media/module/codecs/amrwb/dec/test/AndroidTest.xml
+++ b/media/module/codecs/amrwb/dec/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="AmrwbDecoderTest->/data/local/tmp/AmrwbDecoderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrwb/test/AmrwbDecoderTest.zip?unzip=true"
-            value="/data/local/tmp/AmrwbDecoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="AmrwbDecoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="AmrwbDecoderTest-1.0" />
+        <option name="dynamic-config-module" value="AmrwbDecoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="AmrwbDecoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/AmrwbDecoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/AmrwbDecoderTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/amrwb/dec/test/DynamicConfig.xml b/media/module/codecs/amrwb/dec/test/DynamicConfig.xml
new file mode 100644
index 0000000..d41517f
--- /dev/null
+++ b/media/module/codecs/amrwb/dec/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrwb/test/AmrwbDecoderTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/amrwb/enc/test/AndroidTest.xml b/media/module/codecs/amrwb/enc/test/AndroidTest.xml
index 46f147c..8822cb2 100644
--- a/media/module/codecs/amrwb/enc/test/AndroidTest.xml
+++ b/media/module/codecs/amrwb/enc/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="AmrwbEncoderTest->/data/local/tmp/AmrwbEncoderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrwbenc/test/AmrwbEncoderTest.zip?unzip=true"
-            value="/data/local/tmp/AmrwbEncoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="AmrwbEncoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="AmrwbEncoderTest-1.0" />
+        <option name="dynamic-config-module" value="AmrwbEncoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="AmrwbEncoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/AmrwbEncoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/AmrwbEncoderTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/amrwb/enc/test/DynamicConfig.xml b/media/module/codecs/amrwb/enc/test/DynamicConfig.xml
new file mode 100644
index 0000000..1cf5bf5
--- /dev/null
+++ b/media/module/codecs/amrwb/enc/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/amrwbenc/test/AmrwbEncoderTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/flac/dec/test/AndroidTest.xml b/media/module/codecs/flac/dec/test/AndroidTest.xml
index bebba8e..015f728 100644
--- a/media/module/codecs/flac/dec/test/AndroidTest.xml
+++ b/media/module/codecs/flac/dec/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="FlacDecoderTest->/data/local/tmp/FlacDecoderTest/" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/flac/dec/test/FlacDecoder.zip?unzip=true"
-            value="/data/local/tmp/FlacDecoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="FlacDecoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="FlacDecoder-1.0" />
+        <option name="dynamic-config-module" value="FlacDecoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="FlacDecoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/FlacDecoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/FlacDecoder-1.0/" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/media/module/codecs/flac/dec/test/DynamicConfig.xml b/media/module/codecs/flac/dec/test/DynamicConfig.xml
new file mode 100644
index 0000000..0258808
--- /dev/null
+++ b/media/module/codecs/flac/dec/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.5.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml b/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
index 8bb4d1c..bd620d6 100755
--- a/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
+++ b/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
@@ -19,14 +19,22 @@
         <option name="cleanup" value="true" />
         <option name="push" value="Mpeg4H263DecoderTest->/data/local/tmp/Mpeg4H263DecoderTest" />
         <option name="append-bitness" value="true" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.1.zip?unzip=true"
-            value="/data/local/tmp/Mpeg4H263DecoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="Mpeg4H263DecoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="Mpeg4H263DecoderTest-1.2" />
+        <option name="dynamic-config-module" value="Mpeg4H263DecoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="Mpeg4H263DecoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/Mpeg4H263DecoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/Mpeg4H263DecoderTest-1.2/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/m4v_h263/dec/test/DynamicConfig.xml b/media/module/codecs/m4v_h263/dec/test/DynamicConfig.xml
new file mode 100644
index 0000000..5219361
--- /dev/null
+++ b/media/module/codecs/m4v_h263/dec/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.2.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml b/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
index 5218932..6b352b0 100644
--- a/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
+++ b/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="Mpeg4H263EncoderTest->/data/local/tmp/Mpeg4H263EncoderTest/" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263Encoder.zip?unzip=true"
-            value="/data/local/tmp/Mpeg4H263EncoderTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="Mpeg4H263EncoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="Mpeg4H263Encoder-1.1" />
+        <option name="dynamic-config-module" value="Mpeg4H263EncoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="Mpeg4H263EncoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/Mpeg4H263EncoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/Mpeg4H263Encoder-1.1/" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/media/module/codecs/m4v_h263/enc/test/DynamicConfig.xml b/media/module/codecs/m4v_h263/enc/test/DynamicConfig.xml
new file mode 100644
index 0000000..ceb33ef
--- /dev/null
+++ b/media/module/codecs/m4v_h263/enc/test/DynamicConfig.xml
@@ -0,0 +1,21 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263Encoder-1.1.zip
+            </value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/codecs/mp3dec/test/AndroidTest.xml b/media/module/codecs/mp3dec/test/AndroidTest.xml
index 29952eb..d16f152 100644
--- a/media/module/codecs/mp3dec/test/AndroidTest.xml
+++ b/media/module/codecs/mp3dec/test/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="Mp3DecoderTest->/data/local/tmp/Mp3DecoderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.2.zip?unzip=true"
-            value="/data/local/tmp/Mp3DecoderTestRes/" />
+</target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="Mp3DecoderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="Mp3DecoderTest-1.3" />
+        <option name="dynamic-config-module" value="Mp3DecoderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="Mp3DecoderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/Mp3DecoderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/Mp3DecoderTest-1.3/" />
     </test>
 </configuration>
diff --git a/media/module/codecs/mp3dec/test/DynamicConfig.xml b/media/module/codecs/mp3dec/test/DynamicConfig.xml
new file mode 100644
index 0000000..048940b
--- /dev/null
+++ b/media/module/codecs/mp3dec/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.3.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/esds/tests/AndroidTest.xml b/media/module/esds/tests/AndroidTest.xml
index a4fbc7f..87ca58c 100644
--- a/media/module/esds/tests/AndroidTest.xml
+++ b/media/module/esds/tests/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="ESDSTest->/data/local/tmp/ESDSTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip?unzip=true"
-            value="/data/local/tmp/ESDSTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="ESDSTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="ESDSTestRes-1.1" />
+        <option name="dynamic-config-module" value="ESDSTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="ESDSTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/ESDSTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/ESDSTestRes-1.1/" />
     </test>
 </configuration>
diff --git a/media/module/esds/tests/DynamicConfig.xml b/media/module/esds/tests/DynamicConfig.xml
new file mode 100644
index 0000000..9718dda
--- /dev/null
+++ b/media/module/esds/tests/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.1.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/extractors/mp3/VBRISeeker.cpp b/media/module/extractors/mp3/VBRISeeker.cpp
index ca51b88..a50754b 100644
--- a/media/module/extractors/mp3/VBRISeeker.cpp
+++ b/media/module/extractors/mp3/VBRISeeker.cpp
@@ -84,7 +84,7 @@
          scale,
          entrySize);
 
-    if (entrySize > 4) {
+    if (entrySize < 1 || entrySize > 4) {
         ALOGE("invalid VBRI entry size: %zu", entrySize);
         return NULL;
     }
@@ -122,16 +122,13 @@
 
     off64_t offset = post_id3_pos;
     for (size_t i = 0; i < numEntries; ++i) {
-        uint32_t numBytes;
+        uint32_t numBytes = 0;
+        // entrySize is known to be [1..4]
         switch (entrySize) {
             case 1: numBytes = buffer[i]; break;
             case 2: numBytes = U16_AT(buffer + 2 * i); break;
             case 3: numBytes = U24_AT(buffer + 3 * i); break;
-            default:
-            {
-                CHECK_EQ(entrySize, 4u);
-                numBytes = U32_AT(buffer + 4 * i); break;
-            }
+            case 4: numBytes = U32_AT(buffer + 4 * i); break;
         }
 
         numBytes *= scale;
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 1d88785..38cf29d 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -26,7 +26,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <log/log.h>
 #include <utils/Log.h>
 
 #include "AC4Parser.h"
@@ -6501,6 +6500,16 @@
             AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
         }
 
+        void *presentationsData;
+        size_t presentationsSize;
+        if (AMediaFormat_getBuffer(
+                    mFormat, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+                    &presentationsData, &presentationsSize)) {
+            AMediaFormat_setBuffer(
+                    meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+                    presentationsData, presentationsSize);
+        }
+
         ++mCurrentSampleIndex;
 
         *out = mBuffer;
diff --git a/media/module/extractors/tests/AndroidTest.xml b/media/module/extractors/tests/AndroidTest.xml
index fc8152c..22669df 100644
--- a/media/module/extractors/tests/AndroidTest.xml
+++ b/media/module/extractors/tests/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="ExtractorUnitTest->/data/local/tmp/ExtractorUnitTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.4.zip?unzip=true"
-            value="/data/local/tmp/ExtractorUnitTestRes/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="ExtractorUnitTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="extractor-1.5" />
+        <option name="dynamic-config-module" value="ExtractorUnitTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="ExtractorUnitTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/ExtractorUnitTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/extractor-1.5/" />
     </test>
 </configuration>
diff --git a/media/module/extractors/tests/DynamicConfig.xml b/media/module/extractors/tests/DynamicConfig.xml
new file mode 100644
index 0000000..0258808
--- /dev/null
+++ b/media/module/extractors/tests/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor-1.5.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/foundation/tests/AVCUtils/AndroidTest.xml b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
index 6a088a8..e30bfbf 100644
--- a/media/module/foundation/tests/AVCUtils/AndroidTest.xml
+++ b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
@@ -18,14 +18,22 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="false" />
         <option name="push" value="AVCUtilsUnitTest->/data/local/tmp/AVCUtilsUnitTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip?unzip=true"
-            value="/data/local/tmp/AVCUtilsUnitTest/" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="AVCUtilsUnitTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="AVCUtilsUnitTest-1.0" />
+        <option name="dynamic-config-module" value="AVCUtilsUnitTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="AVCUtilsUnitTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/AVCUtilsUnitTest/" />
+        <option name="native-test-flag" value="-P /sdcard/test/AVCUtilsUnitTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/foundation/tests/AVCUtils/DynamicConfig.xml b/media/module/foundation/tests/AVCUtils/DynamicConfig.xml
new file mode 100644
index 0000000..e5b8bad
--- /dev/null
+++ b/media/module/foundation/tests/AVCUtils/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value> https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/foundation/tests/OpusHeader/AndroidTest.xml b/media/module/foundation/tests/OpusHeader/AndroidTest.xml
index afee16a..4aa4cd2 100644
--- a/media/module/foundation/tests/OpusHeader/AndroidTest.xml
+++ b/media/module/foundation/tests/OpusHeader/AndroidTest.xml
@@ -18,14 +18,21 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="OpusHeaderTest->/data/local/tmp/OpusHeaderTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/OpusHeader/OpusHeader.zip?unzip=true"
-            value="/data/local/tmp/OpusHeaderTestRes/" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="OpusHeaderTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="OpusHeader-1.0" />
+        <option name="dynamic-config-module" value="OpusHeaderTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="OpusHeaderTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/OpusHeaderTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/OpusHeader-1.0/" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/media/module/foundation/tests/OpusHeader/DynamicConfig.xml b/media/module/foundation/tests/OpusHeader/DynamicConfig.xml
new file mode 100644
index 0000000..ebac328
--- /dev/null
+++ b/media/module/foundation/tests/OpusHeader/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+        <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/OpusHeader/OpusHeader-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/id3/test/AndroidTest.xml b/media/module/id3/test/AndroidTest.xml
index 50f9253..b169994 100644
--- a/media/module/id3/test/AndroidTest.xml
+++ b/media/module/id3/test/AndroidTest.xml
@@ -18,14 +18,21 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="ID3Test->/data/local/tmp/ID3Test" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test-1.2.zip?unzip=true"
-            value="/data/local/tmp/ID3TestRes/" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="ID3Test" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="ID3TestRes-1.3" />
+        <option name="dynamic-config-module" value="ID3Test" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="ID3Test" />
-        <option name="native-test-flag" value="-P /data/local/tmp/ID3TestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/ID3TestRes-1.3/" />
     </test>
 </configuration>
diff --git a/media/module/id3/test/DynamicConfig.xml b/media/module/id3/test/DynamicConfig.xml
new file mode 100644
index 0000000..5ae4fcd
--- /dev/null
+++ b/media/module/id3/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test-1.3.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/metadatautils/test/AndroidTest.xml b/media/module/metadatautils/test/AndroidTest.xml
index d6497f3..ce8c4d6 100644
--- a/media/module/metadatautils/test/AndroidTest.xml
+++ b/media/module/metadatautils/test/AndroidTest.xml
@@ -18,13 +18,21 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="false" />
         <option name="push" value="MetaDataUtilsTest->/data/local/tmp/MetaDataUtilsTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip?unzip=true"
-            value="/data/local/tmp/MetaDataUtilsTestRes/" />
     </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="MetaDataUtilsTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="MetaDataUtilsTest-1.1" />
+        <option name="dynamic-config-module" value="MetaDataUtilsTest" />
+    </target_preparer>
+
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="MetaDataUtilsTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/MetaDataUtilsTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/MetaDataUtilsTest-1.1/" />
     </test>
 </configuration>
diff --git a/media/module/metadatautils/test/DynamicConfig.xml b/media/module/metadatautils/test/DynamicConfig.xml
new file mode 100644
index 0000000..9d80bf3
--- /dev/null
+++ b/media/module/metadatautils/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.1.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/module/mpeg2ts/test/AndroidTest.xml b/media/module/mpeg2ts/test/AndroidTest.xml
index ac1294d..836c9f8 100644
--- a/media/module/mpeg2ts/test/AndroidTest.xml
+++ b/media/module/mpeg2ts/test/AndroidTest.xml
@@ -18,14 +18,21 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="Mpeg2tsUnitTest->/data/local/tmp/Mpeg2tsUnitTest" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.zip?unzip=true"
-            value="/data/local/tmp/Mpeg2tsUnitTestRes/" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="Mpeg2tsUnitTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="Mpeg2tsUnitTest-1.0" />
+        <option name="dynamic-config-module" value="Mpeg2tsUnitTest" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="Mpeg2tsUnitTest" />
-        <option name="native-test-flag" value="-P /data/local/tmp/Mpeg2tsUnitTestRes/" />
+        <option name="native-test-flag" value="-P /sdcard/test/Mpeg2tsUnitTest-1.0/" />
     </test>
 </configuration>
diff --git a/media/module/mpeg2ts/test/DynamicConfig.xml b/media/module/mpeg2ts/test/DynamicConfig.xml
new file mode 100644
index 0000000..017a3c6
--- /dev/null
+++ b/media/module/mpeg2ts/test/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest-1.0.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
index 1890661..1b66b01 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
+++ b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
@@ -14,18 +14,26 @@
      limitations under the License.
 -->
 <configuration description="Runs Media Benchmark Tests">
+    <option name="test-tag" value="MediaBenchmarkTest" />
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
-        <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/tests/benchmark/MediaBenchmark.zip?unzip=true"
-            value="/data/local/tmp/MediaBenchmark/res/" />
     </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="cleanup-apks" value="false" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+        <option name="target" value="host" />
+        <option name="config-filename" value="MediaBenchmarkTest" />
+        <option name="version" value="1.0"/>
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
+        <option name="push-all" value="true" />
+        <option name="media-folder-name" value="MediaBenchmarkTest-1.1" />
+        <option name="dynamic-config-module" value="MediaBenchmarkTest" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="MediaBenchmarkTest.apk" />
     </target_preparer>
 
-    <option name="test-tag" value="MediaBenchmarkTest" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.media.benchmark" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/media/tests/benchmark/MediaBenchmarkTest/DynamicConfig.xml b/media/tests/benchmark/MediaBenchmarkTest/DynamicConfig.xml
new file mode 100644
index 0000000..1278f29
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/DynamicConfig.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2021 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.
+-->
+
+<dynamicConfig>
+    <entry key="media_files_url">
+            <value>https://storage.googleapis.com/android_media/frameworks/av/media/tests/benchmark/MediaBenchmark-1.1.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml b/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml
index 24dbccc..2bef254 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml
+++ b/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml
@@ -1,4 +1,4 @@
 <resources>
-    <string name="input_file_path">/data/local/tmp/MediaBenchmark/res/</string>
+    <string name="input_file_path">/sdcard/test/MediaBenchmarkTest-1.1/</string>
     <string name="output_file_path">/data/local/tmp/MediaBenchmark/output/</string>
 </resources>
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 663df69..fc18886 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -147,29 +147,15 @@
         "AudioFlinger.cpp",
         "AudioHwDevice.cpp",
         "AudioStreamOut.cpp",
-        "AudioWatchdog.cpp",
-        "BufLog.cpp",
         "DeviceEffectManager.cpp",
         "Effects.cpp",
-        "FastCapture.cpp",
-        "FastCaptureDumpState.cpp",
-        "FastCaptureState.cpp",
-        "FastMixer.cpp",
-        "FastMixerDumpState.cpp",
-        "FastMixerState.cpp",
-        "FastThread.cpp",
-        "FastThreadDumpState.cpp",
-        "FastThreadState.cpp",
         "MelReporter.cpp",
-        "NBAIO_Tee.cpp",
         "PatchCommandThread.cpp",
         "PatchPanel.cpp",
         "PropertyUtils.cpp",
         "SpdifStreamOut.cpp",
-        "StateQueue.cpp",
         "Threads.cpp",
         "Tracks.cpp",
-        "TypedLogger.cpp",
     ],
 
     include_dirs: [
@@ -184,7 +170,9 @@
         "effect-aidl-cpp",
         "libaudioclient_aidl_conversion",
         "libactivitymanager_aidl",
+        "libaudioflinger_fastpath",
         "libaudioflinger_timing",
+        "libaudioflinger_utils",
         "libaudiofoundation",
         "libaudiohal",
         "libaudioprocessing",
@@ -214,7 +202,6 @@
 
     static_libs: [
         "libcpustats",
-        "libsndfile",
         "libpermission",
     ],
 
@@ -232,7 +219,6 @@
     ],
 
     cflags: [
-        "-DSTATE_QUEUE_INSTANTIATIONS=\"StateQueueInstantiations.cpp\"",
         "-fvisibility=hidden",
         "-Werror",
         "-Wall",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 325adfa..69a3f65 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -59,7 +59,6 @@
 
 #include "AudioFlinger.h"
 #include "EffectConfiguration.h"
-#include "NBAIO_Tee.h"
 #include "PropertyUtils.h"
 
 #include <media/AudioResamplerPublic.h>
@@ -87,9 +86,8 @@
 #include <private/android_filesystem_config.h>
 
 //#define BUFLOG_NDEBUG 0
-#include <BufLog.h>
-
-#include "TypedLogger.h"
+#include <afutils/BufLog.h>
+#include <afutils/TypedLogger.h>
 
 // ----------------------------------------------------------------------------
 
@@ -1262,18 +1260,19 @@
         }
 
         // Look for sync events awaiting for a session to be used.
-        for (size_t i = 0; i < mPendingSyncEvents.size(); i++) {
-            if (mPendingSyncEvents[i]->triggerSession() == sessionId) {
-                if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
+        for (auto it = mPendingSyncEvents.begin(); it != mPendingSyncEvents.end();) {
+            if ((*it)->triggerSession() == sessionId) {
+                if (thread->isValidSyncEvent(*it)) {
                     if (lStatus == NO_ERROR) {
-                        (void) track->setSyncEvent(mPendingSyncEvents[i]);
+                        (void) track->setSyncEvent(*it);
                     } else {
-                        mPendingSyncEvents[i]->cancel();
+                        (*it)->cancel();
                     }
-                    mPendingSyncEvents.removeAt(i);
-                    i--;
+                    it = mPendingSyncEvents.erase(it);
+                    continue;
                 }
             }
+            ++it;
         }
         if ((output.flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
             setAudioHwSyncForSession_l(thread, sessionId);
@@ -3001,14 +3000,6 @@
         return nullptr;
     }
 
-#ifndef MULTICHANNEL_EFFECT_CHAIN
-    if (flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
-        ALOGE("openOutput_l() cannot create spatializer thread "
-                "without #define MULTICHANNEL_EFFECT_CHAIN");
-        return nullptr;
-    }
-#endif
-
     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
 
     // FOR TESTING ONLY:
@@ -4003,15 +3994,16 @@
     track->setTeePatchesToUpdate(std::move(teePatches));
 }
 
-sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
+sp<audioflinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
                                     audio_session_t triggerSession,
                                     audio_session_t listenerSession,
-                                    sync_event_callback_t callBack,
+                                    const audioflinger::SyncEventCallback& callBack,
                                     const wp<RefBase>& cookie)
 {
     Mutex::Autolock _l(mLock);
 
-    sp<SyncEvent> event = new SyncEvent(type, triggerSession, listenerSession, callBack, cookie);
+    auto event = sp<audioflinger::SyncEvent>::make(
+            type, triggerSession, listenerSession, callBack, cookie);
     status_t playStatus = NAME_NOT_FOUND;
     status_t recStatus = NAME_NOT_FOUND;
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
@@ -4027,7 +4019,7 @@
         }
     }
     if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
-        mPendingSyncEvents.add(event);
+        mPendingSyncEvents.emplace_back(event);
     } else {
         ALOGV("createSyncEvent() invalid event %d", event->type());
         event.clear();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 10bfdb9..fe03fc7 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -79,6 +79,9 @@
 #include <mediautils/Synchronization.h>
 #include <mediautils/ThreadSnapshot.h>
 
+#include <afutils/AudioWatchdog.h>
+#include <afutils/NBAIO_Tee.h>
+
 #include <audio_utils/clock.h>
 #include <audio_utils/FdToString.h>
 #include <audio_utils/LinearMap.h>
@@ -89,15 +92,15 @@
 
 #include <sounddose/SoundDoseManager.h>
 #include <timing/MonotonicFrameCounter.h>
+#include <timing/SyncEvent.h>
+#include <timing/SynchronizedRecordState.h>
 
-#include "FastCapture.h"
-#include "FastMixer.h"
+#include <fastpath/FastCapture.h>
+#include <fastpath/FastMixer.h>
 #include <media/nbaio/NBAIO.h>
-#include "AudioWatchdog.h"
 #include "AudioStreamOut.h"
 #include "SpdifStreamOut.h"
 #include "AudioHwDevice.h"
-#include "NBAIO_Tee.h"
 #include "ThreadMetrics.h"
 #include "TrackMetrics.h"
 #include "AllocatorFactory.h"
@@ -383,47 +386,10 @@
 
     static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;
 
-    class SyncEvent;
-
-    typedef void (*sync_event_callback_t)(const wp<SyncEvent>& event) ;
-
-    class SyncEvent : public RefBase {
-    public:
-        SyncEvent(AudioSystem::sync_event_t type,
-                  audio_session_t triggerSession,
-                  audio_session_t listenerSession,
-                  sync_event_callback_t callBack,
-                  const wp<RefBase>& cookie)
-        : mType(type), mTriggerSession(triggerSession), mListenerSession(listenerSession),
-          mCallback(callBack), mCookie(cookie)
-        {}
-
-        virtual ~SyncEvent() {}
-
-        void trigger() {
-            Mutex::Autolock _l(mLock);
-            if (mCallback) mCallback(wp<SyncEvent>(this));
-        }
-        bool isCancelled() const { Mutex::Autolock _l(mLock); return (mCallback == NULL); }
-        void cancel() { Mutex::Autolock _l(mLock); mCallback = NULL; }
-        AudioSystem::sync_event_t type() const { return mType; }
-        audio_session_t triggerSession() const { return mTriggerSession; }
-        audio_session_t listenerSession() const { return mListenerSession; }
-        wp<RefBase> cookie() const { return mCookie; }
-
-    private:
-          const AudioSystem::sync_event_t mType;
-          const audio_session_t mTriggerSession;
-          const audio_session_t mListenerSession;
-          sync_event_callback_t mCallback;
-          const wp<RefBase> mCookie;
-          mutable Mutex mLock;
-    };
-
-    sp<SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
+    sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
                                         audio_session_t triggerSession,
                                         audio_session_t listenerSession,
-                                        sync_event_callback_t callBack,
+                                        const audioflinger::SyncEventCallback& callBack,
                                         const wp<RefBase>& cookie);
 
     bool        btNrecIsOff() const { return mBtNrecIsOff.load(); }
@@ -643,13 +609,6 @@
     };
 
     // --- PlaybackThread ---
-#ifdef FLOAT_EFFECT_CHAIN
-#define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_FLOAT
-using effect_buffer_t = float;
-#else
-#define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_16_BIT
-using effect_buffer_t = int16_t;
-#endif
 
 #include "Threads.h"
 
@@ -994,8 +953,8 @@
                 bool        masterMute_l() const;
                 AudioHwDevice* loadHwModule_l(const char *name);
 
-                Vector < sp<SyncEvent> > mPendingSyncEvents; // sync events awaiting for a session
-                                                             // to be created
+                // sync events awaiting for a session to be created.
+                std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents;
 
                 // Effect chains without a valid thread
                 DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains;
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index ede8e3f..845697a 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -41,15 +41,4 @@
 // uncomment to log CPU statistics every n wall clock seconds
 //#define DEBUG_CPU_USAGE 10
 
-// define FLOAT_EFFECT_CHAIN to request float effects (falls back to int16_t if unavailable)
-#define FLOAT_EFFECT_CHAIN
-
-#ifdef FLOAT_EFFECT_CHAIN
-// define FLOAT_AUX to process aux effect buffers in float (FLOAT_EFFECT_CHAIN must be defined)
-#define FLOAT_AUX
-
-// define MULTICHANNEL_EFFECT_CHAIN to allow multichannel effects (FLOAT_EFFECT_CHAIN defined)
-#define MULTICHANNEL_EFFECT_CHAIN
-#endif
-
 #endif // ANDROID_AUDIOFLINGER_CONFIGURATION_H
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 77aa804..071504a 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -573,9 +573,7 @@
       mDisableWaitCnt(0),    // set by process() and updateState()
       mOffloaded(false),
       mIsOutput(false)
-#ifdef FLOAT_EFFECT_CHAIN
       , mSupportsFloat(false)
-#endif
 {
     ALOGV("Constructor %p pinned %d", this, pinned);
     int lStatus;
@@ -694,31 +692,16 @@
                             mConfig.inputCfg.buffer.frameCount,
                             mConfig.outputCfg.buffer.frameCount);
     const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
-#ifdef FLOAT_EFFECT_CHAIN
         accumulate_float(
                 mConfig.outputCfg.buffer.f32,
                 mConfig.inputCfg.buffer.f32,
                 safeInputOutputSampleCount);
-#else
-        accumulate_i16(
-                mConfig.outputCfg.buffer.s16,
-                mConfig.inputCfg.buffer.s16,
-                safeInputOutputSampleCount);
-#endif
     };
     const auto copyInputToOutput = [this, safeInputOutputSampleCount]() {
-#ifdef FLOAT_EFFECT_CHAIN
         memcpy(
                 mConfig.outputCfg.buffer.f32,
                 mConfig.inputCfg.buffer.f32,
                 safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
-
-#else
-        memcpy(
-                mConfig.outputCfg.buffer.s16,
-                mConfig.inputCfg.buffer.s16,
-                safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
-#endif
     };
 
     if (isProcessEnabled()) {
@@ -727,35 +710,14 @@
             if (auxType) {
                 // We overwrite the aux input buffer here and clear after processing.
                 // aux input is always mono.
-#ifdef FLOAT_EFFECT_CHAIN
-                if (mSupportsFloat) {
-#ifndef FLOAT_AUX
-                    // Do in-place float conversion for auxiliary effect input buffer.
-                    static_assert(sizeof(float) <= sizeof(int32_t),
-                            "in-place conversion requires sizeof(float) <= sizeof(int32_t)");
 
-                    memcpy_to_float_from_q4_27(
-                            mConfig.inputCfg.buffer.f32,
-                            mConfig.inputCfg.buffer.s32,
-                            mConfig.inputCfg.buffer.frameCount);
-#endif // !FLOAT_AUX
-                } else
-#endif // FLOAT_EFFECT_CHAIN
-                {
-#ifdef FLOAT_AUX
+                if (!mSupportsFloat) {
                     memcpy_to_i16_from_float(
                             mConfig.inputCfg.buffer.s16,
                             mConfig.inputCfg.buffer.f32,
                             mConfig.inputCfg.buffer.frameCount);
-#else
-                    memcpy_to_i16_from_q4_27(
-                            mConfig.inputCfg.buffer.s16,
-                            mConfig.inputCfg.buffer.s32,
-                            mConfig.inputCfg.buffer.frameCount);
-#endif
                 }
             }
-#ifdef FLOAT_EFFECT_CHAIN
             sp<EffectBufferHalInterface> inBuffer = mInBuffer;
             sp<EffectBufferHalInterface> outBuffer = mOutBuffer;
 
@@ -802,9 +764,7 @@
                     outBuffer = mOutConversionBuffer;
                 }
             }
-#endif
             ret = mEffectInterface->process();
-#ifdef FLOAT_EFFECT_CHAIN
             if (!mSupportsFloat) { // convert output int16_t back to float.
                 sp<EffectBufferHalInterface> target =
                         mOutChannelCountRequested != outChannelCount
@@ -821,11 +781,8 @@
                         sizeof(float),
                         sizeof(float) * outChannelCount * mConfig.outputCfg.buffer.frameCount);
             }
-#endif
         } else {
-#ifdef FLOAT_EFFECT_CHAIN
             data_bypass:
-#endif
             if (!auxType  /* aux effects do not require data bypass */
                     && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
                 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
@@ -844,13 +801,8 @@
 
         // clear auxiliary effect input buffer for next accumulation
         if (auxType) {
-#ifdef FLOAT_AUX
             const size_t size =
                     mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(float);
-#else
-            const size_t size =
-                    mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(int32_t);
-#endif
             memset(mConfig.inputCfg.buffer.raw, 0, size);
         }
     } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
@@ -905,23 +857,6 @@
             ALOGV("Overriding auxiliary effect input channels %#x as MONO",
                     mConfig.inputCfg.channels);
         }
-#ifndef MULTICHANNEL_EFFECT_CHAIN
-        if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) {
-            mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-            ALOGV("Overriding auxiliary effect output channels %#x as STEREO",
-                    mConfig.outputCfg.channels);
-        }
-#endif
-    } else {
-#ifndef MULTICHANNEL_EFFECT_CHAIN
-        // TODO: Update this logic when multichannel effects are implemented.
-        // For offloaded tracks consider mono output as stereo for proper effect initialization
-        if (channelMask == AUDIO_CHANNEL_OUT_MONO) {
-            mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-            mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
-            ALOGV("Overriding effect input and output as STEREO");
-        }
-#endif
     }
     if (isHapticGenerator()) {
         audio_channel_mask_t hapticChannelMask = callback->hapticChannelMask();
@@ -933,8 +868,8 @@
     mOutChannelCountRequested =
             audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
 
-    mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT;
-    mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT;
+    mConfig.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+    mConfig.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
 
     // Don't use sample rate for thread if effect isn't offloadable.
     if (callback->isOffloadOrDirect() && !isOffloaded()) {
@@ -982,7 +917,6 @@
         status = cmdStatus;
     }
 
-#ifdef MULTICHANNEL_EFFECT_CHAIN
     if (status != NO_ERROR &&
             EffectConfiguration::isHidl() && // only HIDL effects support channel conversion
             mIsOutput &&
@@ -1008,9 +942,7 @@
             status = cmdStatus;
         }
     }
-#endif
 
-#ifdef FLOAT_EFFECT_CHAIN
     if (status == NO_ERROR) {
         mSupportsFloat = true;
     }
@@ -1036,7 +968,6 @@
             ALOGE("%s failed %d with int16_t (as well as float)", __func__, status);
         }
     }
-#endif
 
     if (status == NO_ERROR) {
         // Establish Buffer strategy
@@ -1349,7 +1280,6 @@
     mInBuffer = buffer;
     mEffectInterface->setInBuffer(buffer);
 
-#ifdef FLOAT_EFFECT_CHAIN
     // aux effects do in place conversion to float - we don't allocate mInConversionBuffer.
     // Theoretically insert effects can also do in-place conversions (destroying
     // the original buffer) when the output buffer is identical to the input buffer,
@@ -1381,7 +1311,6 @@
             ALOGE("%s cannot create mInConversionBuffer", __func__);
         }
     }
-#endif
 }
 
 void AudioFlinger::EffectModule::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
@@ -1397,7 +1326,6 @@
     mOutBuffer = buffer;
     mEffectInterface->setOutBuffer(buffer);
 
-#ifdef FLOAT_EFFECT_CHAIN
     // Note: Any effect that does not accumulate does not need mOutConversionBuffer and
     // can do in-place conversion from int16_t to float.  We don't optimize here.
     const uint32_t outChannelCount =
@@ -1425,7 +1353,6 @@
             ALOGE("%s cannot create mOutConversionBuffer", __func__);
         }
     }
-#endif
 }
 
 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
@@ -1721,15 +1648,12 @@
             mConfig.outputCfg.format,
             formatToString((audio_format_t)mConfig.outputCfg.format).c_str());
 
-#ifdef FLOAT_EFFECT_CHAIN
-
     result.appendFormat("\t\t- HAL buffers:\n"
             "\t\t\tIn(%s) InConversion(%s) Out(%s) OutConversion(%s)\n",
             dumpInOutBuffer(true /* isInput */, mInBuffer).c_str(),
             dumpInOutBuffer(true /* isInput */, mInConversionBuffer).c_str(),
             dumpInOutBuffer(false /* isInput */, mOutBuffer).c_str(),
             dumpInOutBuffer(false /* isInput */, mOutConversionBuffer).c_str());
-#endif
 
     write(fd, result.string(), result.length());
 
@@ -2262,7 +2186,7 @@
     if (mInBuffer == NULL) {
         return;
     }
-    const size_t frameSize = audio_bytes_per_sample(EFFECT_BUFFER_FORMAT)
+    const size_t frameSize = audio_bytes_per_sample(AUDIO_FORMAT_PCM_FLOAT)
             * mEffectCallback->inChannelCount(mEffects[0]->id());
 
     memset(mInBuffer->audioBuffer()->raw, 0, mEffectCallback->frameCount() * frameSize);
@@ -2363,13 +2287,9 @@
         // calling the process in effect engine
         size_t numSamples = mEffectCallback->frameCount();
         sp<EffectBufferHalInterface> halBuffer;
-#ifdef FLOAT_EFFECT_CHAIN
+
         status_t result = mEffectCallback->allocateHalBuffer(
                 numSamples * sizeof(float), &halBuffer);
-#else
-        status_t result = mEffectCallback->allocateHalBuffer(
-                numSamples * sizeof(int32_t), &halBuffer);
-#endif
         if (result != OK) return result;
 
         effect->configure();
@@ -2536,7 +2456,8 @@
 
             // make sure the input buffer configuration for the new first effect in the chain
             // is updated if needed (can switch from HAL channel mask to mixer channel mask)
-            if (i == 0 && size > 1) {
+            if (type != EFFECT_FLAG_TYPE_AUXILIARY // TODO(b/284522658) breaks for aux FX, why?
+                    && i == 0 && size > 1) {
                 mEffects[0]->configure();
                 mEffects[0]->setInBuffer(mInBuffer);
                 mEffects[0]->updateAccessMode();      // reconfig if neeeded.
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 885d3e5..57acc67 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -323,13 +323,11 @@
     audio_io_handle_t mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
     bool     mIsOutput;             // direction of the AF thread
 
-#ifdef FLOAT_EFFECT_CHAIN
     bool    mSupportsFloat;         // effect supports float processing
     sp<EffectBufferHalInterface> mInConversionBuffer;  // Buffers for HAL conversion if needed.
     sp<EffectBufferHalInterface> mOutConversionBuffer;
     uint32_t mInChannelCountRequested;
     uint32_t mOutChannelCountRequested;
-#endif
 
     class AutoLockReentrant {
     public:
@@ -494,14 +492,14 @@
     void setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
         mInBuffer = buffer;
     }
-    effect_buffer_t *inBuffer() const {
-        return mInBuffer != 0 ? reinterpret_cast<effect_buffer_t*>(mInBuffer->ptr()) : NULL;
+    float *inBuffer() const {
+        return mInBuffer != 0 ? reinterpret_cast<float*>(mInBuffer->ptr()) : NULL;
     }
     void setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
         mOutBuffer = buffer;
     }
-    effect_buffer_t *outBuffer() const {
-        return mOutBuffer != 0 ? reinterpret_cast<effect_buffer_t*>(mOutBuffer->ptr()) : NULL;
+    float *outBuffer() const {
+        return mOutBuffer != 0 ? reinterpret_cast<float*>(mOutBuffer->ptr()) : NULL;
     }
 
     void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 0e1a3c9..51bb93b 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -117,8 +117,8 @@
             status_t    attachAuxEffect(int EffectId);
             void        setAuxBuffer(int EffectId, int32_t *buffer);
             int32_t     *auxBuffer() const { return mAuxBuffer; }
-            void        setMainBuffer(effect_buffer_t *buffer) { mMainBuffer = buffer; }
-            effect_buffer_t *mainBuffer() const { return mMainBuffer; }
+            void        setMainBuffer(float *buffer) { mMainBuffer = buffer; }
+            float       *mainBuffer() const { return mMainBuffer; }
             int         auxEffectId() const { return mAuxEffectId; }
     virtual status_t    getTimestamp(AudioTimestamp& timestamp);
             void        signal();
@@ -132,7 +132,7 @@
 // implement FastMixerState::VolumeProvider interface
     virtual gain_minifloat_packed_t getVolumeLR();
 
-    virtual status_t    setSyncEvent(const sp<SyncEvent>& event);
+            status_t    setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
 
     virtual bool        isFastTrack() const { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
 
@@ -297,7 +297,7 @@
 
     bool                mResetDone;
     const audio_stream_type_t mStreamType;
-    effect_buffer_t     *mMainBuffer;
+    float     *mMainBuffer;
 
     int32_t             *mAuxBuffer;
     int                 mAuxEffectId;
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index f0a5f76..d91a210 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -58,7 +58,7 @@
             void        appendDumpHeader(String8& result);
             void        appendDump(String8& result, bool active);
 
-            void        handleSyncStartEvent(const sp<SyncEvent>& event);
+            void        handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event);
             void        clearSyncStartEvent();
 
             void        updateTrackFrameInfo(int64_t trackFramesReleased,
@@ -107,12 +107,10 @@
 
             // sync event triggering actual audio capture. Frames read before this event will
             // be dropped and therefore not read by the application.
-            sp<SyncEvent>                       mSyncStartEvent;
+            sp<audioflinger::SyncEvent>        mSyncStartEvent;
 
-            // number of captured frames to drop after the start sync event has been received.
-            // when < 0, maximum frames to drop before starting capture even if sync event is
-            // not received
-            ssize_t                             mFramesToDrop;
+            audioflinger::SynchronizedRecordState
+                    mSynchronizedRecordState{mSampleRate}; // sampleRate defined in base
 
             // used by resampler to find source frames
             ResamplerBufferProvider            *mResamplerBufferProvider;
diff --git a/services/audioflinger/StateQueueInstantiations.cpp b/services/audioflinger/StateQueueInstantiations.cpp
deleted file mode 100644
index 6f4505e..0000000
--- a/services/audioflinger/StateQueueInstantiations.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Configuration.h"
-#include "FastMixerState.h"
-#include "FastCaptureState.h"
-#include "StateQueue.h"
-
-// FIXME hack for gcc
-
-namespace android {
-
-template class StateQueue<FastMixerState>;      // typedef FastMixerStateQueue
-template class StateQueue<FastCaptureState>;    // typedef FastCaptureStateQueue
-
-}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 700bdd2..95883d9 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -76,8 +76,6 @@
 #include <media/audiohal/StreamHalInterface.h>
 
 #include "AudioFlinger.h"
-#include "FastMixer.h"
-#include "FastCapture.h"
 #include <mediautils/SchedulingPolicyService.h>
 #include <mediautils/ServiceUtilities.h>
 
@@ -91,10 +89,10 @@
 #include <cpustats/ThreadCpuUsage.h>
 #endif
 
-#include "AutoPark.h"
+#include <fastpath/AutoPark.h>
 
 #include <pthread.h>
-#include "TypedLogger.h"
+#include <afutils/TypedLogger.h>
 
 // ----------------------------------------------------------------------------
 
@@ -1410,15 +1408,6 @@
 
     switch (mType) {
     case MIXER: {
-#ifndef MULTICHANNEL_EFFECT_CHAIN
-        // Reject any effect on mixer multichannel sinks.
-        // TODO: fix both format and multichannel issues with effects.
-        if (mChannelCount != FCC_2) {
-            ALOGW("%s: effect %s for multichannel(%d) on MIXER thread %s",
-                    __func__, desc->name, mChannelCount, mThreadName);
-            return BAD_VALUE;
-        }
-#endif
         audio_output_flags_t flags = mOutput->flags;
         if (hasFastMixer() || (flags & AUDIO_OUTPUT_FLAG_FAST)) {
             if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
@@ -1471,15 +1460,6 @@
                 __func__, desc->name, mThreadName);
         return BAD_VALUE;
     case DUPLICATING:
-#ifndef MULTICHANNEL_EFFECT_CHAIN
-        // Reject any effect on mixer multichannel sinks.
-        // TODO: fix both format and multichannel issues with effects.
-        if (mChannelCount != FCC_2) {
-            ALOGW("%s: effect %s for multichannel(%d) on DUPLICATING thread %s",
-                    __func__, desc->name, mChannelCount, mThreadName);
-            return BAD_VALUE;
-        }
-#endif
         if (audio_is_global_session(sessionId)) {
             ALOGW("%s: global effect %s on DUPLICATING thread %s",
                     __func__, desc->name, mThreadName);
@@ -3200,7 +3180,7 @@
     free(mEffectBuffer);
     mEffectBuffer = NULL;
     if (mEffectBufferEnabled) {
-        mEffectBufferFormat = EFFECT_BUFFER_FORMAT;
+        mEffectBufferFormat = AUDIO_FORMAT_PCM_FLOAT;
         mEffectBufferSize = mNormalFrameCount * mixerChannelCount
                 * audio_bytes_per_sample(mEffectBufferFormat);
         (void)posix_memalign(&mEffectBuffer, 32, mEffectBufferSize);
@@ -3357,7 +3337,7 @@
     return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000);
 }
 
-status_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<SyncEvent>& event)
+status_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<audioflinger::SyncEvent>& event)
 {
     if (!isValidSyncEvent(event)) {
         return BAD_VALUE;
@@ -3376,7 +3356,8 @@
     return NAME_NOT_FOUND;
 }
 
-bool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const
+bool AudioFlinger::PlaybackThread::isValidSyncEvent(
+        const sp<audioflinger::SyncEvent>& event) const
 {
     return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
 }
@@ -3640,7 +3621,7 @@
 {
     audio_session_t session = chain->sessionId();
     sp<EffectBufferHalInterface> halInBuffer, halOutBuffer;
-    effect_buffer_t *buffer = nullptr; // only used for non global sessions
+    float *buffer = nullptr; // only used for non global sessions
 
     if (mType == SPATIALIZER) {
         if (!audio_is_global_session(session)) {
@@ -3658,7 +3639,7 @@
             size_t numSamples = mNormalFrameCount
                     * (audio_channel_count_from_out_mask(channelMask) + mHapticChannelCount);
             status_t result = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
-                    numSamples * sizeof(effect_buffer_t),
+                    numSamples * sizeof(float),
                     &halInBuffer);
             if (result != OK) return result;
 
@@ -3668,11 +3649,8 @@
                     &halOutBuffer);
             if (result != OK) return result;
 
-#ifdef FLOAT_EFFECT_CHAIN
             buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
-#else
-            buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
-#endif
+
             ALOGV("addEffectChain_l() creating new input buffer %p session %d",
                     buffer, session);
         } else {
@@ -3700,7 +3678,7 @@
         halOutBuffer = halInBuffer;
         ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
         if (!audio_is_global_session(session)) {
-            buffer = halInBuffer ? reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData())
+            buffer = halInBuffer ? reinterpret_cast<float*>(halInBuffer->externalData())
                                  : buffer;
             // Only one effect chain can be present in direct output thread and it uses
             // the sink buffer as input
@@ -3709,14 +3687,11 @@
                         * (audio_channel_count_from_out_mask(mMixerChannelMask)
                                                              + mHapticChannelCount);
                 const status_t allocateStatus = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
-                        numSamples * sizeof(effect_buffer_t),
+                        numSamples * sizeof(float),
                         &halInBuffer);
                 if (allocateStatus != OK) return allocateStatus;
-#ifdef FLOAT_EFFECT_CHAIN
+
                 buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
-#else
-                buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
-#endif
                 ALOGV("addEffectChain_l() creating new input buffer %p session %d",
                         buffer, session);
             }
@@ -3800,7 +3775,7 @@
             for (size_t j = 0; j < mTracks.size(); ++j) {
                 sp<Track> track = mTracks[j];
                 if (session == track->sessionId()) {
-                    track->setMainBuffer(reinterpret_cast<effect_buffer_t*>(mSinkBuffer));
+                    track->setMainBuffer(reinterpret_cast<float*>(mSinkBuffer));
                     chain->decTrackCnt();
                 }
             }
@@ -3853,7 +3828,7 @@
 bool AudioFlinger::PlaybackThread::threadLoop()
 NO_THREAD_SAFETY_ANALYSIS  // manual locking of AudioFlinger
 {
-    tlNBLogWriter = mNBLogWriter.get();
+    aflog::setThreadWriter(mNBLogWriter.get());
 
     Vector< sp<Track> > tracksToRemove;
 
@@ -4220,12 +4195,12 @@
 
                         const size_t audioBufferSize = mNormalFrameCount
                             * audio_bytes_per_frame(hapticSessionChannelCount,
-                                                    EFFECT_BUFFER_FORMAT);
+                                                    AUDIO_FORMAT_PCM_FLOAT);
                         memcpy_by_audio_format(
                                 (uint8_t*)effectChains[i]->outBuffer() + audioBufferSize,
-                                EFFECT_BUFFER_FORMAT,
+                                AUDIO_FORMAT_PCM_FLOAT,
                                 (const uint8_t*)effectChains[i]->inBuffer() + audioBufferSize,
-                                EFFECT_BUFFER_FORMAT, mNormalFrameCount * mHapticChannelCount);
+                                AUDIO_FORMAT_PCM_FLOAT, mNormalFrameCount * mHapticChannelCount);
                     }
                 }
             }
@@ -4718,7 +4693,8 @@
     if ((mOutput->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
         if (*volume != mLeftVolFloat) {
             result = mOutput->stream->setVolume(*volume, *volume);
-            ALOGE_IF(result != OK,
+            // HAL can return INVALID_OPERATION if operation is not supported.
+            ALOGE_IF(result != OK && result != INVALID_OPERATION,
                      "Error when setting output stream volume: %d", result);
             if (result == NO_ERROR) {
                 mLeftVolFloat = *volume;
@@ -5916,7 +5892,7 @@
                 mAudioMixer->setParameter(
                         trackId,
                         AudioMixer::TRACK,
-                        AudioMixer::MIXER_FORMAT, (void *)EFFECT_BUFFER_FORMAT);
+                        AudioMixer::MIXER_FORMAT, (void *)AUDIO_FORMAT_PCM_FLOAT);
                 mAudioMixer->setParameter(
                         trackId,
                         AudioMixer::TRACK,
@@ -8464,7 +8440,11 @@
                     overrun = OVERRUN_FALSE;
                 }
 
-                if (activeTrack->mFramesToDrop == 0) {
+                // MediaSyncEvent handling: Synchronize AudioRecord to AudioTrack completion.
+                const ssize_t framesToDrop =
+                        activeTrack->mSynchronizedRecordState.updateRecordFrames(framesOut);
+                if (framesToDrop == 0) {
+                    // no sync event, process normally, otherwise ignore.
                     if (framesOut > 0) {
                         activeTrack->mSink.frameCount = framesOut;
                         // Sanitize before releasing if the track has no access to the source data
@@ -8474,28 +8454,7 @@
                         }
                         activeTrack->releaseBuffer(&activeTrack->mSink);
                     }
-                } else {
-                    // FIXME could do a partial drop of framesOut
-                    if (activeTrack->mFramesToDrop > 0) {
-                        activeTrack->mFramesToDrop -= (ssize_t)framesOut;
-                        if (activeTrack->mFramesToDrop <= 0) {
-                            activeTrack->clearSyncStartEvent();
-                        }
-                    } else {
-                        activeTrack->mFramesToDrop += framesOut;
-                        if (activeTrack->mFramesToDrop >= 0 || activeTrack->mSyncStartEvent == 0 ||
-                                activeTrack->mSyncStartEvent->isCancelled()) {
-                            ALOGW("Synced record %s, session %d, trigger session %d",
-                                  (activeTrack->mFramesToDrop >= 0) ? "timed out" : "cancelled",
-                                  activeTrack->sessionId(),
-                                  (activeTrack->mSyncStartEvent != 0) ?
-                                          activeTrack->mSyncStartEvent->triggerSession() :
-                                          AUDIO_SESSION_NONE);
-                            activeTrack->clearSyncStartEvent();
-                        }
-                    }
                 }
-
                 if (framesOut == 0) {
                     break;
                 }
@@ -8828,20 +8787,10 @@
     if (event == AudioSystem::SYNC_EVENT_NONE) {
         recordTrack->clearSyncStartEvent();
     } else if (event != AudioSystem::SYNC_EVENT_SAME) {
-        recordTrack->mSyncStartEvent = mAudioFlinger->createSyncEvent(event,
-                                       triggerSession,
-                                       recordTrack->sessionId(),
-                                       syncStartEventCallback,
-                                       recordTrack);
-        // Sync event can be cancelled by the trigger session if the track is not in a
-        // compatible state in which case we start record immediately
-        if (recordTrack->mSyncStartEvent->isCancelled()) {
-            recordTrack->clearSyncStartEvent();
-        } else {
-            // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs
-            recordTrack->mFramesToDrop = -(ssize_t)
-                    ((AudioSystem::kSyncRecordStartTimeOutMs * recordTrack->mSampleRate) / 1000);
-        }
+        recordTrack->mSynchronizedRecordState.startRecording(
+                mAudioFlinger->createSyncEvent(
+                        event, triggerSession,
+                        recordTrack->sessionId(), syncStartEventCallback, recordTrack));
     }
 
     {
@@ -8923,9 +8872,9 @@
     }
 }
 
-void AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event)
+void AudioFlinger::RecordThread::syncStartEventCallback(const wp<audioflinger::SyncEvent>& event)
 {
-    sp<SyncEvent> strongEvent = event.promote();
+    sp<audioflinger::SyncEvent> strongEvent = event.promote();
 
     if (strongEvent != 0) {
         sp<RefBase> ptr = strongEvent->cookie().promote();
@@ -8964,12 +8913,14 @@
     return false;
 }
 
-bool AudioFlinger::RecordThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const
+bool AudioFlinger::RecordThread::isValidSyncEvent(
+        const sp<audioflinger::SyncEvent>& /* event */) const
 {
     return false;
 }
 
-status_t AudioFlinger::RecordThread::setSyncEvent(const sp<SyncEvent>& event __unused)
+status_t AudioFlinger::RecordThread::setSyncEvent(
+        const sp<audioflinger::SyncEvent>& event __unused)
 {
 #if 0   // This branch is currently dead code, but is preserved in case it will be needed in future
     if (!isValidSyncEvent(event)) {
@@ -10536,12 +10487,13 @@
     // and because it can cause a recursive mutex lock on stop().
 }
 
-status_t AudioFlinger::MmapThread::setSyncEvent(const sp<SyncEvent>& event __unused)
+status_t AudioFlinger::MmapThread::setSyncEvent(const sp<audioflinger::SyncEvent>& /* event */)
 {
     return BAD_VALUE;
 }
 
-bool AudioFlinger::MmapThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const
+bool AudioFlinger::MmapThread::isValidSyncEvent(
+        const sp<audioflinger::SyncEvent>& /* event */) const
 {
     return false;
 }
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index e88134b..b2700db 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -520,8 +520,8 @@
                                                  audio_session_t sessionId,
                                                  bool threadLocked);
 
-                virtual status_t    setSyncEvent(const sp<SyncEvent>& event) = 0;
-                virtual bool        isValidSyncEvent(const sp<SyncEvent>& event) const = 0;
+                virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
+                virtual bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const = 0;
 
                 // Return a reference to a per-thread heap which can be used to allocate IMemory
                 // objects that will be read-only to client processes, read/write to mediaserver,
@@ -1021,8 +1021,8 @@
                 status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
                 // Consider also removing and passing an explicit mMainBuffer initialization
                 // parameter to AF::PlaybackThread::Track::Track().
-                effect_buffer_t *sinkBuffer() const {
-                    return reinterpret_cast<effect_buffer_t *>(mSinkBuffer); };
+                float *sinkBuffer() const {
+                    return reinterpret_cast<float *>(mSinkBuffer); };
 
     virtual     void detachAuxEffect_l(int effectId);
                 status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track>& track,
@@ -1038,8 +1038,8 @@
                 virtual product_strategy_t getStrategyForSession_l(audio_session_t sessionId);
 
 
-                virtual status_t setSyncEvent(const sp<SyncEvent>& event);
-                virtual bool     isValidSyncEvent(const sp<SyncEvent>& event) const;
+                status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
+                bool     isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const override;
 
                 // called with AudioFlinger lock held
                         bool     invalidateTracks_l(audio_stream_type_t streamType);
@@ -1995,10 +1995,10 @@
             // FIXME replace by Set [and implement Bag/Multiset for other uses].
             KeyedVector<audio_session_t, bool> sessionIds() const;
 
-    virtual status_t setSyncEvent(const sp<SyncEvent>& event);
-    virtual bool     isValidSyncEvent(const sp<SyncEvent>& event) const;
+            status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
+            bool     isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const override;
 
-    static void syncStartEventCallback(const wp<SyncEvent>& event);
+    static void syncStartEventCallback(const wp<audioflinger::SyncEvent>& event);
 
     virtual size_t      frameCount() const { return mFrameCount; }
             bool        hasFastCapture() const { return mFastCapture != 0; }
@@ -2202,8 +2202,8 @@
                                 // Note: using mActiveTracks as no mTracks here.
                                 return ThreadBase::hasAudioSession_l(sessionId, mActiveTracks);
                             }
-    virtual     status_t    setSyncEvent(const sp<SyncEvent>& event);
-    virtual     bool        isValidSyncEvent(const sp<SyncEvent>& event) const;
+    virtual     status_t    setSyncEvent(const sp<audioflinger::SyncEvent>& event);
+    virtual     bool        isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const;
 
     virtual     void        checkSilentMode_l() {}
     virtual     void        processVolume_l() {}
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 254fb91..d5b6a98 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -67,7 +67,7 @@
                                 pid_t creatorPid,
                                 uid_t uid,
                                 bool isOut,
-                                alloc_type alloc = ALLOC_CBLK,
+                                const alloc_type alloc = ALLOC_CBLK,
                                 track_type type = TYPE_DEFAULT,
                                 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
                                 std::string metricsId = {});
@@ -84,7 +84,7 @@
             pid_t       creatorPid() const { return mCreatorPid; }
 
             audio_port_handle_t portId() const { return mPortId; }
-    virtual status_t    setSyncEvent(const sp<SyncEvent>& event);
+    virtual status_t    setSyncEvent(const sp<audioflinger::SyncEvent>& event);
 
             sp<IMemory> getBuffers() const { return mBufferMemory; }
             void*       buffer() const { return mBuffer; }
@@ -352,6 +352,7 @@
                                     // this could be a track type if needed later
 
     const wp<ThreadBase> mThread;
+    const alloc_type     mAllocType;
     /*const*/ sp<Client> mClient;   // see explanation at ~TrackBase() why not const
     sp<IMemory>         mCblkMemory;
     audio_track_cblk_t* mCblk;
@@ -375,7 +376,7 @@
 
     const audio_session_t mSessionId;
     uid_t               mUid;
-    Vector < sp<SyncEvent> >mSyncEvents;
+    std::list<sp<audioflinger::SyncEvent>> mSyncEvents;
     const bool          mIsOut;
     sp<ServerProxy>     mServerProxy;
     const int           mId;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 7d2c4db..00c88bc 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -90,12 +90,13 @@
             pid_t creatorPid,
             uid_t clientUid,
             bool isOut,
-            alloc_type alloc,
+            const alloc_type alloc,
             track_type type,
             audio_port_handle_t portId,
             std::string metricsId)
     :   RefBase(),
         mThread(thread),
+        mAllocType(alloc),
         mClient(client),
         mCblk(NULL),
         // mBuffer, mBufferSize
@@ -277,6 +278,10 @@
         // relying on the automatic clear() at end of scope.
         mClient.clear();
     }
+    if (mAllocType == ALLOC_LOCAL) {
+        free(mBuffer);
+        mBuffer = nullptr;
+    }
     // flush the binder command buffer
     IPCThreadState::self()->flushCommands();
 }
@@ -298,9 +303,10 @@
     mServerProxy->releaseBuffer(&buf);
 }
 
-status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
+status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(
+        const sp<audioflinger::SyncEvent>& event)
 {
-    mSyncEvents.add(event);
+    mSyncEvents.emplace_back(event);
     return NO_ERROR;
 }
 
@@ -1673,12 +1679,13 @@
 
 void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
 {
-    for (size_t i = 0; i < mSyncEvents.size();) {
-        if (mSyncEvents[i]->type() == type) {
-            mSyncEvents[i]->trigger();
-            mSyncEvents.removeAt(i);
+    for (auto it = mSyncEvents.begin(); it != mSyncEvents.end();) {
+        if ((*it)->type() == type) {
+            ALOGV("%s: triggering SyncEvent type %d", __func__, type);
+            (*it)->trigger();
+            it = mSyncEvents.erase(it);
         } else {
-            ++i;
+            ++it;
         }
     }
 }
@@ -1710,7 +1717,8 @@
     return vlr;
 }
 
-status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
+status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(
+        const sp<audioflinger::SyncEvent>& event)
 {
     if (isTerminated() || mState == PAUSED ||
             ((framesReady() == 0) && ((mSharedBuffer != 0) ||
@@ -1924,6 +1932,8 @@
         }
     }
 
+    ALOGV("%s: trackFramesReleased:%lld  sinkFramesWritten:%lld  setDrained: %d",
+        __func__, (long long)trackFramesReleased, (long long)sinkFramesWritten, drained);
     mAudioTrackServerProxy->setDrained(drained);
     // Set correction for flushed frames that are not accounted for in released.
     local.mFlushed = mAudioTrackServerProxy->framesFlushed();
@@ -2498,7 +2508,6 @@
                   type, portId,
                   std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD) + std::to_string(portId)),
         mOverflow(false),
-        mFramesToDrop(0),
         mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
         mRecordBufferConverter(NULL),
         mFlags(flags),
@@ -2700,27 +2709,24 @@
     result.append("\n");
 }
 
-void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
+// This is invoked by SyncEvent callback.
+void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(
+        const sp<audioflinger::SyncEvent>& event)
 {
-    if (event == mSyncStartEvent) {
-        ssize_t framesToDrop = 0;
-        sp<ThreadBase> threadBase = mThread.promote();
-        if (threadBase != 0) {
-            // TODO: use actual buffer filling status instead of 2 buffers when info is available
-            // from audio HAL
-            framesToDrop = threadBase->mFrameCount * 2;
-        }
-        mFramesToDrop = framesToDrop;
+    size_t framesToDrop = 0;
+    sp<ThreadBase> threadBase = mThread.promote();
+    if (threadBase != 0) {
+        // TODO: use actual buffer filling status instead of 2 buffers when info is available
+        // from audio HAL
+        framesToDrop = threadBase->mFrameCount * 2;
     }
+
+    mSynchronizedRecordState.onPlaybackFinished(event, framesToDrop);
 }
 
 void AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
 {
-    if (mSyncStartEvent != 0) {
-        mSyncStartEvent->cancel();
-        mSyncStartEvent.clear();
-    }
-    mFramesToDrop = 0;
+    mSynchronizedRecordState.clear();
 }
 
 void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
diff --git a/services/audioflinger/TypedLogger.cpp b/services/audioflinger/TypedLogger.cpp
deleted file mode 100644
index 57c206b..0000000
--- a/services/audioflinger/TypedLogger.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- * Copyright 2017, 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 "AudioFlinger"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <pthread.h>
-#include "TypedLogger.h"
-
-namespace android {
-thread_local NBLog::Writer *tlNBLogWriter;
-}
diff --git a/services/audioflinger/afutils/Android.bp b/services/audioflinger/afutils/Android.bp
new file mode 100644
index 0000000..4309bf5
--- /dev/null
+++ b/services/audioflinger/afutils/Android.bp
@@ -0,0 +1,40 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_services_audioflinger_license"],
+}
+
+cc_library {
+    name: "libaudioflinger_utils",
+
+    defaults: [
+        "audioflinger_flags_defaults",
+    ],
+
+    srcs: [
+        "AudioWatchdog.cpp",
+        "BufLog.cpp",
+        "NBAIO_Tee.cpp",
+        "TypedLogger.cpp",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "libbase",
+        "liblog",
+        "libnbaio",
+        "libnblog",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libsndfile",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/audioflinger",  // for configuration
+    ],
+}
diff --git a/services/audioflinger/AudioWatchdog.cpp b/services/audioflinger/afutils/AudioWatchdog.cpp
similarity index 100%
rename from services/audioflinger/AudioWatchdog.cpp
rename to services/audioflinger/afutils/AudioWatchdog.cpp
diff --git a/services/audioflinger/AudioWatchdog.h b/services/audioflinger/afutils/AudioWatchdog.h
similarity index 100%
rename from services/audioflinger/AudioWatchdog.h
rename to services/audioflinger/afutils/AudioWatchdog.h
diff --git a/services/audioflinger/BufLog.cpp b/services/audioflinger/afutils/BufLog.cpp
similarity index 100%
rename from services/audioflinger/BufLog.cpp
rename to services/audioflinger/afutils/BufLog.cpp
diff --git a/services/audioflinger/BufLog.h b/services/audioflinger/afutils/BufLog.h
similarity index 100%
rename from services/audioflinger/BufLog.h
rename to services/audioflinger/afutils/BufLog.h
diff --git a/services/audioflinger/NBAIO_Tee.cpp b/services/audioflinger/afutils/NBAIO_Tee.cpp
similarity index 100%
rename from services/audioflinger/NBAIO_Tee.cpp
rename to services/audioflinger/afutils/NBAIO_Tee.cpp
diff --git a/services/audioflinger/NBAIO_Tee.h b/services/audioflinger/afutils/NBAIO_Tee.h
similarity index 100%
rename from services/audioflinger/NBAIO_Tee.h
rename to services/audioflinger/afutils/NBAIO_Tee.h
diff --git a/services/audioflinger/afutils/TypedLogger.cpp b/services/audioflinger/afutils/TypedLogger.cpp
new file mode 100644
index 0000000..7c546a5
--- /dev/null
+++ b/services/audioflinger/afutils/TypedLogger.cpp
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2017, 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 "AudioFlinger"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <pthread.h>
+#include "TypedLogger.h"
+
+namespace android::aflog {
+
+// External linkage access of thread local storage outside of this shared library
+// causes orphaned memory allocations.  This occurs in the implementation of
+// __emutls_get_address(), see b/284657986.
+//
+// We only expose a thread local storage getter and setter here, not the
+// actual thread local variable.
+
+namespace {
+thread_local NBLog::Writer *tlNBLogWriter;
+} // namespace
+
+NBLog::Writer *getThreadWriter() {
+    return tlNBLogWriter;
+}
+
+void setThreadWriter(NBLog::Writer *writer) {
+    tlNBLogWriter = writer;
+}
+
+} // namespace android::aflog
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/afutils/TypedLogger.h
similarity index 79%
rename from services/audioflinger/TypedLogger.h
rename to services/audioflinger/afutils/TypedLogger.h
index feb71e3..f34a50c 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/afutils/TypedLogger.h
@@ -85,56 +85,57 @@
 //      slower than nullptr check when logging is enabled at compile-time and disabled at runtime.
 
 // Write formatted entry to log
-#define LOGT(fmt, ...) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOGT(fmt, ...) do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
                                 x->logFormat((fmt), hash(__FILE__, __LINE__), ##__VA_ARGS__); } \
                                 while (0)
 
 // Write histogram timestamp entry
-#define LOG_HIST_TS() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_HIST_TS() do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->logEventHistTs(NBLog::EVENT_HISTOGRAM_ENTRY_TS, hash(__FILE__, __LINE__)); } while(0)
 
 // Record that audio was turned on/off
-#define LOG_AUDIO_STATE() do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_AUDIO_STATE() do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->logEventHistTs(NBLog::EVENT_AUDIO_STATE, hash(__FILE__, __LINE__)); } while(0)
 
 // Log the difference bewteen frames presented by HAL and frames written to HAL output sink,
 // divided by the sample rate. Parameter ms is of type double.
-#define LOG_LATENCY(ms) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_LATENCY(ms) do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->log<NBLog::EVENT_LATENCY>(ms); } while (0)
 
 // Record thread overrun event nanosecond timestamp. Parameter ns is an int64_t.
-#define LOG_OVERRUN(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_OVERRUN(ns) do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->log<NBLog::EVENT_OVERRUN>(ns); } while (0)
 
 // Record thread info. This currently includes type, frameCount, and sampleRate.
 // Parameter type is thread_info_t as defined in NBLog.h.
-#define LOG_THREAD_INFO(info) do { NBLog::Writer *x = tlNBLogWriter; \
+#define LOG_THREAD_INFO(info) do { NBLog::Writer *x = aflog::getThreadWriter(); \
         if (x != nullptr) x->log<NBLog::EVENT_THREAD_INFO>(info); } while (0)
 
-#define LOG_THREAD_PARAMS(params) do {NBLog::Writer *x = tlNBLogWriter; \
+#define LOG_THREAD_PARAMS(params) do {NBLog::Writer *x = aflog::getThreadWriter(); \
         if (x != nullptr) x->log<NBLog::EVENT_THREAD_PARAMS>(params); } while (0)
 
 // Record thread underrun event nanosecond timestamp. Parameter ns is an int64_t.
-#define LOG_UNDERRUN(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_UNDERRUN(ns) do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->log<NBLog::EVENT_UNDERRUN>(ns); } while (0)
 
 // Record thread warmup time in milliseconds. Parameter ms is of type double.
-#define LOG_WARMUP_TIME(ms) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_WARMUP_TIME(ms) do { \
+        NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->log<NBLog::EVENT_WARMUP_TIME>(ms); } while (0)
 
 // Record a typed entry that represents a thread's work time in nanoseconds.
 // Parameter ns should be of type uint32_t.
-#define LOG_WORK_TIME(ns) do { NBLog::Writer *x = tlNBLogWriter; if (x != nullptr) \
+#define LOG_WORK_TIME(ns) do { NBLog::Writer *x = aflog::getThreadWriter(); if (x != nullptr) \
         x->log<NBLog::EVENT_WORK_TIME>(ns); } while (0)
 
-namespace android {
-extern "C" {
+namespace android::aflog {
 // TODO consider adding a thread_local NBLog::Writer tlStubNBLogWriter and then
-// initialize below tlNBLogWriter to &tlStubNBLogWriter to remove the need to
+// initialize setThreadWriter() to &tlStubNBLogWriter to remove the need to
 // check for nullptr every time. Also reduces the need to add a new logging macro above
 // each time we want to log a new type.
-extern thread_local NBLog::Writer *tlNBLogWriter;
-}
-} // namespace android
+
+NBLog::Writer *getThreadWriter();
+void setThreadWriter(NBLog::Writer *writer);
+} // namespace android::aflog
 
 #endif // ANDROID_TYPED_LOGGER_H
diff --git a/services/audioflinger/fastpath/Android.bp b/services/audioflinger/fastpath/Android.bp
new file mode 100644
index 0000000..10f1af9
--- /dev/null
+++ b/services/audioflinger/fastpath/Android.bp
@@ -0,0 +1,161 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_services_audioflinger_license"],
+}
+
+fastpath_tidy_errors = [
+    // https://clang.llvm.org/extra/clang-tidy/checks/list.html
+    // For many categories, the checks are too many to specify individually.
+    // Feel free to disable as needed - as warnings are generally ignored,
+    // we treat warnings as errors.
+    "android-*",
+    "bugprone-*",
+    "cert-*",
+    "clang-analyzer-security*",
+    "google-*",
+    "misc-*",
+    //"modernize-*",  // explicitly list the modernize as they can be subjective.
+    "modernize-avoid-bind",
+    //"modernize-avoid-c-arrays", // std::array<> can be verbose
+    "modernize-concat-nested-namespaces",
+    //"modernize-deprecated-headers", // C headers still ok even if there is C++ equivalent.
+    "modernize-deprecated-ios-base-aliases",
+    "modernize-loop-convert",
+    "modernize-make-shared",
+    "modernize-make-unique",
+    // "modernize-pass-by-value",
+    "modernize-raw-string-literal",
+    "modernize-redundant-void-arg",
+    "modernize-replace-auto-ptr",
+    "modernize-replace-random-shuffle",
+    "modernize-return-braced-init-list",
+    "modernize-shrink-to-fit",
+    "modernize-unary-static-assert",
+    // "modernize-use-auto",  // found in MediaMetricsService.h, debatable - auto can obscure type
+    "modernize-use-bool-literals",
+    "modernize-use-default-member-init",
+    "modernize-use-emplace",
+    "modernize-use-equals-default",
+    "modernize-use-equals-delete",
+    // "modernize-use-nodiscard",
+    "modernize-use-noexcept",
+    "modernize-use-nullptr",
+    "modernize-use-override",
+    //"modernize-use-trailing-return-type", // not necessarily more readable
+    "modernize-use-transparent-functors",
+    "modernize-use-uncaught-exceptions",
+    "modernize-use-using",
+    "performance-*",
+
+    // Remove some pedantic stylistic requirements.
+    "-google-readability-casting", // C++ casts not always necessary and may be verbose
+    "-google-readability-todo",    // do not require TODO(info)
+
+    "-bugprone-unhandled-self-assignment",
+    "-bugprone-suspicious-string-compare",
+    "-cert-oop54-cpp", // found in TransactionLog.h
+    "-bugprone-narrowing-conversions", // b/182410845
+
+    // TODO(b/275642749) Reenable these warnings
+    "-bugprone-assignment-in-if-condition",
+    "-bugprone-forward-declaration-namespace",
+    "-bugprone-parent-virtual-call",
+    "-cert-dcl59-cpp",
+    "-cert-err34-c",
+    "-google-runtime-int",
+    "-misc-non-private-member-variables-in-classes",
+    "-modernize-concat-nested-namespaces",
+    "-modernize-loop-convert",
+    "-modernize-use-default-member-init",
+    "-performance-no-int-to-ptr",
+]
+
+// Eventually use common tidy defaults
+cc_defaults {
+    name: "fastpath_flags_defaults",
+    // https://clang.llvm.org/docs/UsersManual.html#command-line-options
+    // https://clang.llvm.org/docs/DiagnosticsReference.html
+    cflags: [
+        "-Wall",
+        "-Wdeprecated",
+        "-Werror",
+        "-Werror=implicit-fallthrough",
+        "-Werror=sometimes-uninitialized",
+        "-Werror=conditional-uninitialized",
+        "-Wextra",
+
+        // suppress some warning chatter.
+        "-Wno-deprecated-copy-with-dtor",
+        "-Wno-deprecated-copy-with-user-provided-dtor",
+
+        "-Wredundant-decls",
+        "-Wshadow",
+        "-Wstrict-aliasing",
+        "-fstrict-aliasing",
+        "-Wthread-safety",
+        //"-Wthread-safety-negative", // experimental - looks broken in R.
+        "-Wunreachable-code",
+        "-Wunreachable-code-break",
+        "-Wunreachable-code-return",
+        "-Wunused",
+        "-Wused-but-marked-unused",
+        "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
+    ],
+    // https://clang.llvm.org/extra/clang-tidy/
+    tidy: true,
+    tidy_checks: fastpath_tidy_errors,
+    tidy_checks_as_errors: fastpath_tidy_errors,
+    tidy_flags: [
+      "-format-style=file",
+    ],
+}
+
+cc_library_shared {
+    name: "libaudioflinger_fastpath",
+
+    defaults: [
+        "fastpath_flags_defaults",
+    ],
+
+    srcs: [
+        "FastCapture.cpp",
+        "FastCaptureDumpState.cpp",
+        "FastCaptureState.cpp",
+        "FastMixer.cpp",
+        "FastMixerDumpState.cpp",
+        "FastMixerState.cpp",
+        "FastThread.cpp",
+        "FastThreadDumpState.cpp",
+        "FastThreadState.cpp",
+        "StateQueue.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/audioflinger", // for Configuration
+    ],
+
+    shared_libs: [
+        "libaudioflinger_utils", // NBAIO_Tee
+        "libaudioprocessing",
+        "libaudioutils",
+        "libcutils",
+        "liblog",
+        "libnbaio",
+        "libnblog", // legacy NBLog that can be removed.
+        "libutils",
+    ],
+
+    header_libs: [
+        "libaudiohal_headers",
+        "libmedia_headers",
+    ],
+
+    sanitize: {
+        integer_overflow: true,
+    },
+
+}
diff --git a/services/audioflinger/AutoPark.h b/services/audioflinger/fastpath/AutoPark.h
similarity index 99%
rename from services/audioflinger/AutoPark.h
rename to services/audioflinger/fastpath/AutoPark.h
index 83f6b7d..6e68327 100644
--- a/services/audioflinger/AutoPark.h
+++ b/services/audioflinger/fastpath/AutoPark.h
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#pragma once
+
 namespace android {
 
 // T is FastMixer or FastCapture
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/fastpath/FastCapture.cpp
similarity index 86%
rename from services/audioflinger/FastCapture.cpp
rename to services/audioflinger/fastpath/FastCapture.cpp
index 2963202..5c76649 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/fastpath/FastCapture.cpp
@@ -33,8 +33,8 @@
 /*static*/ const FastCaptureState FastCapture::sInitial;
 
 FastCapture::FastCapture() : FastThread("cycleC_ms", "loadC_us"),
-    mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0),
-    mReadBuffer(NULL), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
+    mInputSource(nullptr), mInputSourceGen(0), mPipeSink(nullptr), mPipeSinkGen(0),
+    mReadBuffer(nullptr), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
     // mDummyDumpState
     mTotalNativeFramesRead(0)
 {
@@ -44,10 +44,6 @@
     mDummyDumpState = &mDummyFastCaptureDumpState;
 }
 
-FastCapture::~FastCapture()
-{
-}
-
 FastCaptureStateQueue* FastCapture::sq()
 {
     return &mSQ;
@@ -95,11 +91,11 @@
     bool eitherChanged = false;
 
     // check for change in input HAL configuration
-    NBAIO_Format previousFormat = mFormat;
+    const NBAIO_Format previousFormat = mFormat;
     if (current->mInputSourceGen != mInputSourceGen) {
         mInputSource = current->mInputSource;
         mInputSourceGen = current->mInputSourceGen;
-        if (mInputSource == NULL) {
+        if (mInputSource == nullptr) {
             mFormat = Format_Invalid;
             mSampleRate = 0;
         } else {
@@ -122,19 +118,19 @@
     }
 
     // input source and pipe sink must be compatible
-    if (eitherChanged && mInputSource != NULL && mPipeSink != NULL) {
+    if (eitherChanged && mInputSource != nullptr && mPipeSink != nullptr) {
         ALOG_ASSERT(Format_isEqual(mFormat, mPipeSink->format()));
     }
 
     if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
         // FIXME to avoid priority inversion, don't free here
         free(mReadBuffer);
-        mReadBuffer = NULL;
+        mReadBuffer = nullptr;
         if (frameCount > 0 && mSampleRate > 0) {
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal capture thread allocate for
             //       us to avoid blocking here and to prevent possible priority inversion
-            size_t bufferSize = frameCount * Format_frameSize(mFormat);
+            const size_t bufferSize = frameCount * Format_frameSize(mFormat);
             (void)posix_memalign(&mReadBuffer, 32, bufferSize);
             memset(mReadBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
             mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;      // 1.00
@@ -166,9 +162,9 @@
     AudioBufferProvider* fastPatchRecordBufferProvider = current->mFastPatchRecordBufferProvider;
     AudioBufferProvider::Buffer patchBuffer;
 
-    if (fastPatchRecordBufferProvider != 0) {
+    if (fastPatchRecordBufferProvider != nullptr) {
         patchBuffer.frameCount = ~0;
-        status_t status = fastPatchRecordBufferProvider->getNextBuffer(&patchBuffer);
+        const status_t status = fastPatchRecordBufferProvider->getNextBuffer(&patchBuffer);
         if (status != NO_ERROR) {
             frameCount = 0;
         } else if (patchBuffer.frameCount < frameCount) {
@@ -179,11 +175,11 @@
     }
 
     if ((command & FastCaptureState::READ) /*&& isWarm*/) {
-        ALOG_ASSERT(mInputSource != NULL);
-        ALOG_ASSERT(mReadBuffer != NULL);
+        ALOG_ASSERT(mInputSource != nullptr);
+        ALOG_ASSERT(mReadBuffer != nullptr);
         dumpState->mReadSequence++;
         ATRACE_BEGIN("read");
-        ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount);
+        const ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount);
         ATRACE_END();
         dumpState->mReadSequence++;
         if (framesRead >= 0) {
@@ -201,8 +197,8 @@
     }
 
     if (command & FastCaptureState::WRITE) {
-        ALOG_ASSERT(mPipeSink != NULL);
-        ALOG_ASSERT(mReadBuffer != NULL);
+        ALOG_ASSERT(mPipeSink != nullptr);
+        ALOG_ASSERT(mReadBuffer != nullptr);
         if (mReadBufferState < 0) {
             memset(mReadBuffer, 0, frameCount * Format_frameSize(mFormat));
             mReadBufferState = frameCount;
@@ -211,23 +207,23 @@
             if (current->mSilenceCapture) {
                 memset(mReadBuffer, 0, mReadBufferState * Format_frameSize(mFormat));
             }
-            ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
+            const ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
             audio_track_cblk_t* cblk = current->mCblk;
-            if (fastPatchRecordBufferProvider != 0) {
+            if (fastPatchRecordBufferProvider != nullptr) {
                 // This indicates the fast track is a patch record, update the cblk by
                 // calling releaseBuffer().
                 memcpy_by_audio_format(patchBuffer.raw, current->mFastPatchRecordFormat,
                         mReadBuffer, mFormat.mFormat, framesWritten * mFormat.mChannelCount);
                 patchBuffer.frameCount = framesWritten;
                 fastPatchRecordBufferProvider->releaseBuffer(&patchBuffer);
-            } else if (cblk != NULL && framesWritten > 0) {
+            } else if (cblk != nullptr && framesWritten > 0) {
                 // FIXME This supports at most one fast capture client.
                 //       To handle multiple clients this could be converted to an array,
                 //       or with a lot more work the control block could be shared by all clients.
-                int32_t rear = cblk->u.mStreaming.mRear;
+                const int32_t rear = cblk->u.mStreaming.mRear;
                 android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
                 cblk->mServer += framesWritten;
-                int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
+                const int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
                 if (!(old & CBLK_FUTEX_WAKE)) {
                     // client is never in server process, so don't use FUTEX_WAKE_PRIVATE
                     (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, 1);
diff --git a/services/audioflinger/FastCapture.h b/services/audioflinger/fastpath/FastCapture.h
similarity index 77%
rename from services/audioflinger/FastCapture.h
rename to services/audioflinger/fastpath/FastCapture.h
index c3817c0..657a324 100644
--- a/services/audioflinger/FastCapture.h
+++ b/services/audioflinger/fastpath/FastCapture.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_CAPTURE_H
-#define ANDROID_AUDIO_FAST_CAPTURE_H
+#pragma once
 
 #include "FastThread.h"
 #include "StateQueue.h"
@@ -24,13 +23,12 @@
 
 namespace android {
 
-typedef StateQueue<FastCaptureState> FastCaptureStateQueue;
+using FastCaptureStateQueue = StateQueue<FastCaptureState>;
 
 class FastCapture : public FastThread {
 
 public:
             FastCapture();
-    virtual ~FastCapture();
 
             FastCaptureStateQueue*  sq();
 
@@ -38,13 +36,13 @@
             FastCaptureStateQueue   mSQ;
 
     // callouts
-    virtual const FastThreadState *poll();
-    virtual void setNBLogWriter(NBLog::Writer *logWriter);
-    virtual void onIdle();
-    virtual void onExit();
-    virtual bool isSubClassCommand(FastThreadState::Command command);
-    virtual void onStateChange();
-    virtual void onWork();
+    const FastThreadState *poll() override;
+    void setNBLogWriter(NBLog::Writer *logWriter) override;
+    void onIdle() override;
+    void onExit() override;
+    bool isSubClassCommand(FastThreadState::Command command) override;
+    void onStateChange() override;
+    void onWork() override;
 
     static const FastCaptureState sInitial;
 
@@ -65,5 +63,3 @@
 };  // class FastCapture
 
 }   // namespace android
-
-#endif  // ANDROID_AUDIO_FAST_CAPTURE_H
diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/fastpath/FastCaptureDumpState.cpp
similarity index 90%
rename from services/audioflinger/FastCaptureDumpState.cpp
rename to services/audioflinger/fastpath/FastCaptureDumpState.cpp
index 243dfa5..e0ac9cc 100644
--- a/services/audioflinger/FastCaptureDumpState.cpp
+++ b/services/audioflinger/fastpath/FastCaptureDumpState.cpp
@@ -29,19 +29,15 @@
 {
 }
 
-FastCaptureDumpState::~FastCaptureDumpState()
-{
-}
-
 void FastCaptureDumpState::dump(int fd) const
 {
     if (mCommand == FastCaptureState::INITIAL) {
         dprintf(fd, "  FastCapture not initialized\n");
         return;
     }
-    double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
+    const double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
             (mMeasuredWarmupTs.tv_nsec / 1000000.0);
-    double periodSec = (double) mFrameCount / mSampleRate;
+    const double periodSec = (double) mFrameCount / mSampleRate;
     dprintf(fd, "  FastCapture command=%s readSequence=%u framesRead=%u\n"
                 "              readErrors=%u sampleRate=%u frameCount=%zu\n"
                 "              measuredWarmup=%.3g ms, warmupCycles=%u period=%.2f ms\n"
diff --git a/services/audioflinger/FastCaptureDumpState.h b/services/audioflinger/fastpath/FastCaptureDumpState.h
similarity index 87%
rename from services/audioflinger/FastCaptureDumpState.h
rename to services/audioflinger/fastpath/FastCaptureDumpState.h
index 34ce456..e205518 100644
--- a/services/audioflinger/FastCaptureDumpState.h
+++ b/services/audioflinger/fastpath/FastCaptureDumpState.h
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_CAPTURE_DUMP_STATE_H
-#define ANDROID_AUDIO_FAST_CAPTURE_DUMP_STATE_H
+#pragma once
 
 #include <stdint.h>
+#include <type_traits>
 #include "Configuration.h"
 #include "FastThreadDumpState.h"
 
@@ -25,7 +25,6 @@
 
 struct FastCaptureDumpState : FastThreadDumpState {
     FastCaptureDumpState();
-    /*virtual*/ ~FastCaptureDumpState();
 
     void dump(int fd) const;    // should only be called on a stable copy, not the original
 
@@ -38,6 +37,7 @@
     bool     mSilenced = false; // capture is silenced
 };
 
-}  // namespace android
+// No virtuals
+static_assert(!std::is_polymorphic_v<FastCaptureDumpState>);
 
-#endif  // ANDROID_AUDIO_FAST_CAPTURE_DUMP_STATE_H
+}  // namespace android
diff --git a/services/audioflinger/FastCaptureState.cpp b/services/audioflinger/fastpath/FastCaptureState.cpp
similarity index 87%
rename from services/audioflinger/FastCaptureState.cpp
rename to services/audioflinger/fastpath/FastCaptureState.cpp
index 918ba9c..d2df62a 100644
--- a/services/audioflinger/FastCaptureState.cpp
+++ b/services/audioflinger/fastpath/FastCaptureState.cpp
@@ -19,11 +19,7 @@
 namespace android {
 
 FastCaptureState::FastCaptureState() : FastThreadState(),
-    mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0), mFrameCount(0)
-{
-}
-
-FastCaptureState::~FastCaptureState()
+    mInputSource(nullptr), mInputSourceGen(0), mPipeSink(nullptr), mPipeSinkGen(0), mFrameCount(0)
 {
 }
 
@@ -31,7 +27,7 @@
 const char *FastCaptureState::commandToString(Command command)
 {
     const char *str = FastThreadState::commandToString(command);
-    if (str != NULL) {
+    if (str != nullptr) {
         return str;
     }
     switch (command) {
diff --git a/services/audioflinger/FastCaptureState.h b/services/audioflinger/fastpath/FastCaptureState.h
similarity index 93%
rename from services/audioflinger/FastCaptureState.h
rename to services/audioflinger/fastpath/FastCaptureState.h
index f949275..82ea0ed 100644
--- a/services/audioflinger/FastCaptureState.h
+++ b/services/audioflinger/fastpath/FastCaptureState.h
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_CAPTURE_STATE_H
-#define ANDROID_AUDIO_FAST_CAPTURE_STATE_H
+#pragma once
 
+#include <type_traits>
 #include <media/nbaio/NBAIO.h>
 #include <media/AudioBufferProvider.h>
 #include "FastThreadState.h"
@@ -27,7 +27,6 @@
 // Represent a single state of the fast capture
 struct FastCaptureState : FastThreadState {
                 FastCaptureState();
-    /*virtual*/ ~FastCaptureState();
 
     // all pointer fields use raw pointers; objects are owned and ref-counted by RecordThread
     NBAIO_Source*   mInputSource;       // HAL input device, must already be negotiated
@@ -55,6 +54,7 @@
     static const char *commandToString(Command command);
 };  // struct FastCaptureState
 
-}   // namespace android
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastCaptureState>);
 
-#endif  // ANDROID_AUDIO_FAST_CAPTURE_STATE_H
+}   // namespace android
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/fastpath/FastMixer.cpp
similarity index 94%
rename from services/audioflinger/FastMixer.cpp
rename to services/audioflinger/fastpath/FastMixer.cpp
index 61dd3f2..e13adab 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/fastpath/FastMixer.cpp
@@ -42,7 +42,7 @@
 #include <cutils/bitops.h>
 #include <media/AudioMixer.h>
 #include "FastMixer.h"
-#include "TypedLogger.h"
+#include <afutils/TypedLogger.h>
 
 namespace android {
 
@@ -61,13 +61,13 @@
     : FastThread("cycle_ms", "load_us"),
     // mFastTrackNames
     // mGenerations
-    mOutputSink(NULL),
+    mOutputSink(nullptr),
     mOutputSinkGen(0),
-    mMixer(NULL),
-    mSinkBuffer(NULL),
+    mMixer(nullptr),
+    mSinkBuffer(nullptr),
     mSinkBufferSize(0),
     mSinkChannelCount(FCC_2),
-    mMixerBuffer(NULL),
+    mMixerBuffer(nullptr),
     mMixerBufferSize(0),
     mMixerBufferState(UNDEFINED),
     mFormat(Format_Invalid),
@@ -99,10 +99,6 @@
 #endif
 }
 
-FastMixer::~FastMixer()
-{
-}
-
 FastMixerStateQueue* FastMixer::sq()
 {
     return &mSQ;
@@ -229,13 +225,13 @@
     unsigned previousTrackMask;
 
     // check for change in output HAL configuration
-    NBAIO_Format previousFormat = mFormat;
+    const NBAIO_Format previousFormat = mFormat;
     if (current->mOutputSinkGen != mOutputSinkGen) {
         mOutputSink = current->mOutputSink;
         mOutputSinkGen = current->mOutputSinkGen;
         mSinkChannelMask = current->mSinkChannelMask;
         mBalance.setChannelMask(mSinkChannelMask);
-        if (mOutputSink == NULL) {
+        if (mOutputSink == nullptr) {
             mFormat = Format_Invalid;
             mSampleRate = 0;
             mSinkChannelCount = 0;
@@ -259,11 +255,11 @@
     if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
         // FIXME to avoid priority inversion, don't delete here
         delete mMixer;
-        mMixer = NULL;
+        mMixer = nullptr;
         free(mMixerBuffer);
-        mMixerBuffer = NULL;
+        mMixerBuffer = nullptr;
         free(mSinkBuffer);
-        mSinkBuffer = NULL;
+        mSinkBuffer = nullptr;
         if (frameCount > 0 && mSampleRate > 0) {
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal mixer allocate for us
@@ -320,7 +316,7 @@
         // process removed tracks first to avoid running out of track names
         unsigned removedTracks = previousTrackMask & ~currentTrackMask;
         while (removedTracks != 0) {
-            int i = __builtin_ctz(removedTracks);
+            const int i = __builtin_ctz(removedTracks);
             removedTracks &= ~(1 << i);
             updateMixerTrack(i, REASON_REMOVE);
             // don't reset track dump state, since other side is ignoring it
@@ -329,7 +325,7 @@
         // now process added tracks
         unsigned addedTracks = currentTrackMask & ~previousTrackMask;
         while (addedTracks != 0) {
-            int i = __builtin_ctz(addedTracks);
+            const int i = __builtin_ctz(addedTracks);
             addedTracks &= ~(1 << i);
             updateMixerTrack(i, REASON_ADD);
         }
@@ -338,7 +334,7 @@
         // but may have a different buffer provider or volume provider
         unsigned modifiedTracks = currentTrackMask & previousTrackMask;
         while (modifiedTracks != 0) {
-            int i = __builtin_ctz(modifiedTracks);
+            const int i = __builtin_ctz(modifiedTracks);
             modifiedTracks &= ~(1 << i);
             updateMixerTrack(i, REASON_MODIFY);
         }
@@ -373,8 +369,8 @@
     const FastMixerState::Command command = mCommand;
     const size_t frameCount = current->mFrameCount;
 
-    if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
-        ALOG_ASSERT(mMixerBuffer != NULL);
+    if ((command & FastMixerState::MIX) && (mMixer != nullptr) && mIsWarm) {
+        ALOG_ASSERT(mMixerBuffer != nullptr);
 
         // AudioMixer::mState.enabledTracks is undefined if mState.hook == process__validate,
         // so we keep a side copy of enabledTracks
@@ -383,7 +379,7 @@
         // for each track, update volume and check for underrun
         unsigned currentTrackMask = current->mTrackMask;
         while (currentTrackMask != 0) {
-            int i = __builtin_ctz(currentTrackMask);
+            const int i = __builtin_ctz(currentTrackMask);
             currentTrackMask &= ~(1 << i);
             const FastTrack* fastTrack = &current->mFastTracks[i];
 
@@ -406,8 +402,8 @@
             fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
 
             const int name = i;
-            if (fastTrack->mVolumeProvider != NULL) {
-                gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
+            if (fastTrack->mVolumeProvider != nullptr) {
+                const gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
 
@@ -418,7 +414,7 @@
             // takes a tryLock, which can block
             // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
             // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
-            size_t framesReady = fastTrack->mBufferProvider->framesReady();
+            const size_t framesReady = fastTrack->mBufferProvider->framesReady();
             if (ATRACE_ENABLED()) {
                 // I wish we had formatted trace names
                 char traceName[16];
@@ -464,7 +460,8 @@
         mMixerBufferState = UNDEFINED;
     }
     //bool didFullWrite = false;    // dumpsys could display a count of partial writes
-    if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
+    if ((command & FastMixerState::WRITE)
+            && (mOutputSink != nullptr) && (mMixerBuffer != nullptr)) {
         if (mMixerBufferState == UNDEFINED) {
             memset(mMixerBuffer, 0, mMixerBufferSize);
             mMixerBufferState = ZEROED;
@@ -481,7 +478,7 @@
         mBalance.process((float *)mMixerBuffer, frameCount);
 
         // prepare the buffer used to write to sink
-        void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
+        void *buffer = mSinkBuffer != nullptr ? mSinkBuffer : mMixerBuffer;
         if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
             memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
                     frameCount * Format_channelCount(mFormat));
@@ -493,7 +490,7 @@
                     audio_bytes_per_sample(mFormat.mFormat),
                     frameCount * audio_bytes_per_frame(mAudioChannelCount, mFormat.mFormat));
         }
-        // if non-NULL, then duplicate write() to this non-blocking sink
+        // if non-nullptr, then duplicate write() to this non-blocking sink
 #ifdef TEE_SINK
         mTee.write(buffer, frameCount);
 #endif
@@ -501,7 +498,7 @@
         //       but this code should be modified to handle both non-blocking and blocking sinks
         dumpState->mWriteSequence++;
         ATRACE_BEGIN("write");
-        ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
+        const ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
         ATRACE_END();
         dumpState->mWriteSequence++;
         if (framesWritten >= 0) {
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/fastpath/FastMixer.h
similarity index 87%
rename from services/audioflinger/FastMixer.h
rename to services/audioflinger/fastpath/FastMixer.h
index d71519f..ab7bfe1 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/fastpath/FastMixer.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_MIXER_H
-#define ANDROID_AUDIO_FAST_MIXER_H
+#pragma once
 
 #include <atomic>
 #include <audio_utils/Balance.h>
@@ -23,13 +22,13 @@
 #include "StateQueue.h"
 #include "FastMixerState.h"
 #include "FastMixerDumpState.h"
-#include "NBAIO_Tee.h"
+#include <afutils/NBAIO_Tee.h>
 
 namespace android {
 
 class AudioMixer;
 
-typedef StateQueue<FastMixerState> FastMixerStateQueue;
+using FastMixerStateQueue = StateQueue<FastMixerState>;
 
 class FastMixer : public FastThread {
 
@@ -37,7 +36,6 @@
     /** FastMixer constructor takes as param the parent MixerThread's io handle (id)
         for purposes of identification. */
     explicit FastMixer(audio_io_handle_t threadIoHandle);
-    virtual ~FastMixer();
 
             FastMixerStateQueue* sq();
 
@@ -51,13 +49,13 @@
             FastMixerStateQueue mSQ;
 
     // callouts
-    virtual const FastThreadState *poll();
-    virtual void setNBLogWriter(NBLog::Writer *logWriter);
-    virtual void onIdle();
-    virtual void onExit();
-    virtual bool isSubClassCommand(FastThreadState::Command command);
-    virtual void onStateChange();
-    virtual void onWork();
+    const FastThreadState *poll() override;
+    void setNBLogWriter(NBLog::Writer *logWriter) override;
+    void onIdle() override;
+    void onExit() override;
+    bool isSubClassCommand(FastThreadState::Command command) override;
+    void onStateChange() override;
+    void onWork() override;
 
     enum Reason {
         REASON_REMOVE,
@@ -115,5 +113,3 @@
 };  // class FastMixer
 
 }   // namespace android
-
-#endif  // ANDROID_AUDIO_FAST_MIXER_H
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/fastpath/FastMixerDumpState.cpp
similarity index 92%
rename from services/audioflinger/FastMixerDumpState.cpp
rename to services/audioflinger/fastpath/FastMixerDumpState.cpp
index d041882..f48f539 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/fastpath/FastMixerDumpState.cpp
@@ -37,15 +37,11 @@
 {
 }
 
-FastMixerDumpState::~FastMixerDumpState()
-{
-}
-
 // helper function called by qsort()
 static int compare_uint32_t(const void *pa, const void *pb)
 {
-    uint32_t a = *(const uint32_t *)pa;
-    uint32_t b = *(const uint32_t *)pb;
+    const uint32_t a = *(const uint32_t *)pa;
+    const uint32_t b = *(const uint32_t *)pb;
     if (a < b) {
         return -1;
     } else if (a > b) {
@@ -61,9 +57,9 @@
         dprintf(fd, "  FastMixer not initialized\n");
         return;
     }
-    double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
+    const double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
             (mMeasuredWarmupTs.tv_nsec / 1000000.0);
-    double mixPeriodSec = (double) mFrameCount / mSampleRate;
+    const double mixPeriodSec = (double) mFrameCount / mSampleRate;
     dprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
                 "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
                 "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
@@ -99,16 +95,16 @@
     // the mean account for 99.73% of the population.  So if we take each tail to be 1/1000 of the
     // sample set, we get 99.8% combined, or close to three standard deviations.
     static const uint32_t kTailDenominator = 1000;
-    uint32_t *tail = n >= kTailDenominator ? new uint32_t[n] : NULL;
+    uint32_t *tail = n >= kTailDenominator ? new uint32_t[n] : nullptr;
     // loop over all the samples
     for (uint32_t j = 0; j < n; ++j) {
-        size_t i = oldestClosed++ & (mSamplingN - 1);
-        uint32_t wallNs = mMonotonicNs[i];
-        if (tail != NULL) {
+        const size_t i = oldestClosed++ & (mSamplingN - 1);
+        const uint32_t wallNs = mMonotonicNs[i];
+        if (tail != nullptr) {
             tail[j] = wallNs;
         }
         wall.add(wallNs);
-        uint32_t sampleLoadNs = mLoadNs[i];
+        const uint32_t sampleLoadNs = mLoadNs[i];
         loadNs.add(sampleLoadNs);
 #ifdef CPU_FREQUENCY_STATISTICS
         uint32_t sampleCpukHz = mCpukHz[i];
@@ -146,10 +142,10 @@
                 "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
                 loadMHz.getMean(), loadMHz.getMin(), loadMHz.getMax(), loadMHz.getStdDev());
 #endif
-    if (tail != NULL) {
+    if (tail != nullptr) {
         qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
         // assume same number of tail samples on each side, left and right
-        uint32_t count = n / kTailDenominator;
+        const uint32_t count = n / kTailDenominator;
         audio_utils::Statistics<double> left, right;
         for (uint32_t i = 0; i < count; ++i) {
             left.add(tail[i]);
@@ -175,7 +171,7 @@
             FastMixerState::sMaxFastTracks, trackMask);
     dprintf(fd, "  Index Active Full Partial Empty  Recent Ready    Written\n");
     for (uint32_t i = 0; i < FastMixerState::sMaxFastTracks; ++i, trackMask >>= 1) {
-        bool isActive = trackMask & 1;
+        const bool isActive = trackMask & 1;
         const FastTrackDump *ftDump = &mTracks[i];
         const FastTrackUnderruns& underruns = ftDump->mUnderruns;
         const char *mostRecent;
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/fastpath/FastMixerDumpState.h
similarity index 93%
rename from services/audioflinger/FastMixerDumpState.h
rename to services/audioflinger/fastpath/FastMixerDumpState.h
index 294ef78..91d85b1 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/fastpath/FastMixerDumpState.h
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
-#define ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
+#pragma once
 
 #include <stdint.h>
+#include <type_traits>
 #include <audio_utils/TimestampVerifier.h>
 #include "Configuration.h"
 #include "FastThreadDumpState.h"
@@ -55,15 +55,16 @@
 // Represents the dump state of a fast track
 struct FastTrackDump {
     FastTrackDump() : mFramesReady(0) { }
-    /*virtual*/ ~FastTrackDump() { }
     FastTrackUnderruns  mUnderruns;
     size_t              mFramesReady;        // most recent value only; no long-term statistics kept
     int64_t             mFramesWritten;      // last value from track
 };
 
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastTrackDump>);
+
 struct FastMixerDumpState : FastThreadDumpState {
     FastMixerDumpState();
-    /*virtual*/ ~FastMixerDumpState();
 
     void dump(int fd) const;    // should only be called on a stable copy, not the original
 
@@ -81,6 +82,7 @@
     TimestampVerifier<int64_t /* frame count */, int64_t /* time ns */> mTimestampVerifier;
 };
 
-}  // namespace android
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastMixerDumpState>);
 
-#endif  // ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
+}  // namespace android
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/fastpath/FastMixerState.cpp
similarity index 82%
rename from services/audioflinger/FastMixerState.cpp
rename to services/audioflinger/fastpath/FastMixerState.cpp
index b98842d..dbccb10 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/fastpath/FastMixerState.cpp
@@ -23,30 +23,22 @@
 namespace android {
 
 FastTrack::FastTrack() :
-    mBufferProvider(NULL), mVolumeProvider(NULL),
+    mBufferProvider(nullptr), mVolumeProvider(nullptr),
     mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mFormat(AUDIO_FORMAT_INVALID), mGeneration(0)
 {
 }
 
-FastTrack::~FastTrack()
-{
-}
-
 FastMixerState::FastMixerState() : FastThreadState(),
     // mFastTracks
-    mFastTracksGen(0), mTrackMask(0), mOutputSink(NULL), mOutputSinkGen(0),
+    mFastTracksGen(0), mTrackMask(0), mOutputSink(nullptr), mOutputSinkGen(0),
     mFrameCount(0)
 {
-    int ok = pthread_once(&sMaxFastTracksOnce, sMaxFastTracksInit);
+    const int ok = pthread_once(&sMaxFastTracksOnce, sMaxFastTracksInit);
     if (ok != 0) {
         ALOGE("%s pthread_once failed: %d", __func__, ok);
     }
 }
 
-FastMixerState::~FastMixerState()
-{
-}
-
 // static
 unsigned FastMixerState::sMaxFastTracks = kDefaultFastTracks;
 
@@ -57,7 +49,7 @@
 const char *FastMixerState::commandToString(Command command)
 {
     const char *str = FastThreadState::commandToString(command);
-    if (str != NULL) {
+    if (str != nullptr) {
         return str;
     }
     switch (command) {
@@ -72,9 +64,9 @@
 void FastMixerState::sMaxFastTracksInit()
 {
     char value[PROPERTY_VALUE_MAX];
-    if (property_get("ro.audio.max_fast_tracks", value, NULL) > 0) {
+    if (property_get("ro.audio.max_fast_tracks", value, nullptr /* default_value */) > 0) {
         char *endptr;
-        unsigned long ul = strtoul(value, &endptr, 0);
+        const unsigned long ul = strtoul(value, &endptr, 0);
         if (*endptr == '\0' && kMinFastTracks <= ul && ul <= kMaxFastTracks) {
             sMaxFastTracks = (unsigned) ul;
         }
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/fastpath/FastMixerState.h
similarity index 94%
rename from services/audioflinger/FastMixerState.h
rename to services/audioflinger/fastpath/FastMixerState.h
index ce3cc14..f40f612 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/fastpath/FastMixerState.h
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_MIXER_STATE_H
-#define ANDROID_AUDIO_FAST_MIXER_STATE_H
+#pragma once
 
 #include <math.h>
+#include <type_traits>
 
 #include <audio_utils/minifloat.h>
 #include <system/audio.h>
@@ -38,13 +38,12 @@
     virtual gain_minifloat_packed_t getVolumeLR() = 0;
 protected:
     VolumeProvider() { }
-    virtual ~VolumeProvider() { }
+    virtual ~VolumeProvider() = default;
 };
 
 // Represents the state of a fast track
 struct FastTrack {
     FastTrack();
-    /*virtual*/ ~FastTrack();
 
     ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active
     VolumeProvider*         mVolumeProvider; // optional; if NULL then full-scale
@@ -56,10 +55,12 @@
     float                   mHapticMaxAmplitude = NAN; // max amplitude allowed for haptic data
 };
 
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastTrack>);
+
 // Represents a single state of the fast mixer
 struct FastMixerState : FastThreadState {
                 FastMixerState();
-    /*virtual*/ ~FastMixerState();
 
     // These are the minimum, maximum, and default values for maximum number of fast tracks
     static const unsigned kMinFastTracks = 2;
@@ -95,6 +96,7 @@
 
 };  // struct FastMixerState
 
-}   // namespace android
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastMixerState>);
 
-#endif  // ANDROID_AUDIO_FAST_MIXER_STATE_H
+}   // namespace android
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/fastpath/FastThread.cpp
similarity index 93%
rename from services/audioflinger/FastThread.cpp
rename to services/audioflinger/fastpath/FastThread.cpp
index 47fe0b3..2ebdbc1 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/fastpath/FastThread.cpp
@@ -28,7 +28,7 @@
 #include <utils/Trace.h>
 #include "FastThread.h"
 #include "FastThreadDumpState.h"
-#include "TypedLogger.h"
+#include <afutils/TypedLogger.h>
 
 #define FAST_DEFAULT_NS    999999999L   // ~1 sec: default time to sleep
 #define FAST_HOT_IDLE_NS     1000000L   // 1 ms: time to sleep while hot idling
@@ -40,7 +40,7 @@
 
 FastThread::FastThread(const char *cycleMs, const char *loadUs) : Thread(false /*canCallJava*/),
     // re-initialized to &sInitial by subclass constructor
-    mPrevious(NULL), mCurrent(NULL),
+    mPrevious(nullptr), mCurrent(nullptr),
     /* mOldTs({0, 0}), */
     mOldTsValid(false),
     mSleepNs(-1),
@@ -51,8 +51,8 @@
     mWarmupNsMin(0),
     mWarmupNsMax(LONG_MAX),
     // re-initialized to &mDummySubclassDumpState by subclass constructor
-    mDummyDumpState(NULL),
-    mDumpState(NULL),
+    mDummyDumpState(nullptr),
+    mDumpState(nullptr),
     mIgnoreNextOverrun(true),
 #ifdef FAST_THREAD_STATISTICS
     // mOldLoad
@@ -84,15 +84,11 @@
     strlcpy(mLoadUs, loadUs, sizeof(mLoadUs));
 }
 
-FastThread::~FastThread()
-{
-}
-
 bool FastThread::threadLoop()
 {
     // LOGT now works even if tlNBLogWriter is nullptr, but we're considering changing that,
     // so this initialization permits a future change to remove the check for nullptr.
-    tlNBLogWriter = mDummyNBLogWriter.get();
+    aflog::setThreadWriter(mDummyNBLogWriter.get());
     for (;;) {
 
         // either nanosleep, sched_yield, or busy wait
@@ -100,7 +96,7 @@
             if (mSleepNs > 0) {
                 ALOG_ASSERT(mSleepNs < 1000000000);
                 const struct timespec req = {0, mSleepNs};
-                nanosleep(&req, NULL);
+                nanosleep(&req, nullptr);
             } else {
                 sched_yield();
             }
@@ -110,7 +106,7 @@
 
         // poll for state change
         const FastThreadState *next = poll();
-        if (next == NULL) {
+        if (next == nullptr) {
             // continue to use the default initial state until a real state is available
             // FIXME &sInitial not available, should save address earlier
             //ALOG_ASSERT(mCurrent == &sInitial && previous == &sInitial);
@@ -121,10 +117,11 @@
         if (next != mCurrent) {
 
             // As soon as possible of learning of a new dump area, start using it
-            mDumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
-            tlNBLogWriter = next->mNBLogWriter != NULL ?
+            mDumpState = next->mDumpState != nullptr ? next->mDumpState : mDummyDumpState;
+            NBLog::Writer * const writer = next->mNBLogWriter != nullptr ?
                     next->mNBLogWriter : mDummyNBLogWriter.get();
-            setNBLogWriter(tlNBLogWriter); // This is used for debugging only
+            aflog::setThreadWriter(writer);
+            setNBLogWriter(writer); // This is used for debugging only
 
             // We want to always have a valid reference to the previous (non-idle) state.
             // However, the state queue only guarantees access to current and previous states.
@@ -149,7 +146,7 @@
             mCurrent = next;
         }
 #if !LOG_NDEBUG
-        next = NULL;    // not referenced again
+        next = nullptr;    // not referenced again
 #endif
 
         mDumpState->mCommand = mCommand;
@@ -167,12 +164,12 @@
             // FIXME consider checking previous state and only perform if previous != COLD_IDLE
             if (mCurrent->mColdGen != mColdGen) {
                 int32_t *coldFutexAddr = mCurrent->mColdFutexAddr;
-                ALOG_ASSERT(coldFutexAddr != NULL);
-                int32_t old = android_atomic_dec(coldFutexAddr);
+                ALOG_ASSERT(coldFutexAddr != nullptr);
+                const int32_t old = android_atomic_dec(coldFutexAddr);
                 if (old <= 0) {
-                    syscall(__NR_futex, coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
+                    syscall(__NR_futex, coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, nullptr);
                 }
-                int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
+                const int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
                 if (!(policy == SCHED_FIFO || policy == SCHED_RR)) {
                     ALOGE("did not receive expected priority boost on time");
                 }
@@ -267,7 +264,7 @@
                 mSleepNs = -1;
                 if (mIsWarm) {
                     if (sec > 0 || nsec > mUnderrunNs) {
-                        ATRACE_NAME("underrun");
+                        ATRACE_NAME("underrun");   // NOLINT(misc-const-correctness)
                         // FIXME only log occasionally
                         ALOGV("underrun: time since last cycle %d.%03ld sec",
                                 (int) sec, nsec / 1000000L);
@@ -298,7 +295,7 @@
 #ifdef FAST_THREAD_STATISTICS
                 if (mIsWarm) {
                     // advance the FIFO queue bounds
-                    size_t i = mBounds & (mDumpState->mSamplingN - 1);
+                    const size_t i = mBounds & (mDumpState->mSamplingN - 1);
                     mBounds = (mBounds & 0xFFFF0000) | ((mBounds + 1) & 0xFFFF);
                     if (mFull) {
                         //mBounds += 0x10000;
diff --git a/services/audioflinger/FastThread.h b/services/audioflinger/fastpath/FastThread.h
similarity index 95%
rename from services/audioflinger/FastThread.h
rename to services/audioflinger/fastpath/FastThread.h
index 2f0f73f..84dc4d2 100644
--- a/services/audioflinger/FastThread.h
+++ b/services/audioflinger/fastpath/FastThread.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_THREAD_H
-#define ANDROID_AUDIO_FAST_THREAD_H
+#pragma once
 
 #include "Configuration.h"
 #ifdef CPU_FREQUENCY_STATISTICS
@@ -31,11 +30,10 @@
 
 public:
             FastThread(const char *cycleMs, const char *loadUs);
-    virtual ~FastThread();
 
 private:
     // implement Thread::threadLoop()
-    virtual bool threadLoop();
+    bool threadLoop() override;
 
 protected:
     // callouts to subclass in same lexical order as they were in original FastMixer.cpp
@@ -93,5 +91,3 @@
 };  // class FastThread
 
 }  // namespace android
-
-#endif  // ANDROID_AUDIO_FAST_THREAD_H
diff --git a/services/audioflinger/FastThreadDumpState.cpp b/services/audioflinger/fastpath/FastThreadDumpState.cpp
similarity index 94%
rename from services/audioflinger/FastThreadDumpState.cpp
rename to services/audioflinger/fastpath/FastThreadDumpState.cpp
index e91073f..09d4744 100644
--- a/services/audioflinger/FastThreadDumpState.cpp
+++ b/services/audioflinger/fastpath/FastThreadDumpState.cpp
@@ -34,17 +34,13 @@
 #endif
 }
 
-FastThreadDumpState::~FastThreadDumpState()
-{
-}
-
 #ifdef FAST_THREAD_STATISTICS
 void FastThreadDumpState::increaseSamplingN(uint32_t samplingN)
 {
     if (samplingN <= mSamplingN || samplingN > kSamplingN || roundup(samplingN) != samplingN) {
         return;
     }
-    uint32_t additional = samplingN - mSamplingN;
+    const uint32_t additional = samplingN - mSamplingN;
     // sample arrays aren't accessed atomically with respect to the bounds,
     // so clearing reduces chance for dumpsys to read random uninitialized samples
     memset(&mMonotonicNs[mSamplingN], 0, sizeof(mMonotonicNs[0]) * additional);
diff --git a/services/audioflinger/FastThreadDumpState.h b/services/audioflinger/fastpath/FastThreadDumpState.h
similarity index 94%
rename from services/audioflinger/FastThreadDumpState.h
rename to services/audioflinger/fastpath/FastThreadDumpState.h
index 0b20e55..63e81d3 100644
--- a/services/audioflinger/FastThreadDumpState.h
+++ b/services/audioflinger/fastpath/FastThreadDumpState.h
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_THREAD_DUMP_STATE_H
-#define ANDROID_AUDIO_FAST_THREAD_DUMP_STATE_H
+#pragma once
+
+#include <type_traits>
 
 #include "Configuration.h"
 #include "FastThreadState.h"
@@ -30,7 +31,6 @@
 // It has a different lifetime than the FastThread, and so it can't be a member of FastThread.
 struct FastThreadDumpState {
     FastThreadDumpState();
-    /*virtual*/ ~FastThreadDumpState();
 
     FastThreadState::Command mCommand;   // current command
     uint32_t mUnderruns;        // total number of underruns
@@ -67,6 +67,7 @@
 
 };  // struct FastThreadDumpState
 
-}  // namespace android
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastThreadDumpState>);
 
-#endif  // ANDROID_AUDIO_FAST_THREAD_DUMP_STATE_H
+}  // namespace android
diff --git a/services/audioflinger/FastThreadState.cpp b/services/audioflinger/fastpath/FastThreadState.cpp
similarity index 87%
rename from services/audioflinger/FastThreadState.cpp
rename to services/audioflinger/fastpath/FastThreadState.cpp
index ad5f31f..e6cb353 100644
--- a/services/audioflinger/FastThreadState.cpp
+++ b/services/audioflinger/fastpath/FastThreadState.cpp
@@ -20,12 +20,8 @@
 namespace android {
 
 FastThreadState::FastThreadState() :
-    mCommand(INITIAL), mColdFutexAddr(NULL), mColdGen(0), mDumpState(NULL), mNBLogWriter(NULL)
-
-{
-}
-
-FastThreadState::~FastThreadState()
+    mCommand(INITIAL), mColdFutexAddr(nullptr), mColdGen(0), mDumpState(nullptr)
+    , mNBLogWriter(nullptr)
 {
 }
 
@@ -38,7 +34,7 @@
     case FastThreadState::COLD_IDLE:    return "COLD_IDLE";
     case FastThreadState::EXIT:         return "EXIT";
     }
-    return NULL;
+    return nullptr;
 }
 
 }   // namespace android
diff --git a/services/audioflinger/FastThreadState.h b/services/audioflinger/fastpath/FastThreadState.h
similarity index 90%
rename from services/audioflinger/FastThreadState.h
rename to services/audioflinger/fastpath/FastThreadState.h
index 9fb4e06..2b8b079 100644
--- a/services/audioflinger/FastThreadState.h
+++ b/services/audioflinger/fastpath/FastThreadState.h
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_FAST_THREAD_STATE_H
-#define ANDROID_AUDIO_FAST_THREAD_STATE_H
+#pragma once
 
+#include <type_traits>
 #include "Configuration.h"
 #include <stdint.h>
 #include <media/nblog/NBLog.h>
@@ -28,9 +28,8 @@
 // Represents a single state of a FastThread
 struct FastThreadState {
                 FastThreadState();
-    /*virtual*/ ~FastThreadState();
 
-    typedef uint32_t Command;
+    using Command = uint32_t;
     static const Command
         INITIAL = 0,            // used only for the initial state
         HOT_IDLE = 1,           // do nothing
@@ -50,6 +49,7 @@
     static const char *commandToString(Command command);
 };  // struct FastThreadState
 
-}  // namespace android
+// No virtuals.
+static_assert(!std::is_polymorphic_v<FastThreadState>);
 
-#endif  // ANDROID_AUDIO_FAST_THREAD_STATE_H
+}  // namespace android
diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/fastpath/StateQueue.cpp
similarity index 87%
rename from services/audioflinger/StateQueue.cpp
rename to services/audioflinger/fastpath/StateQueue.cpp
index 38ce2c2..62c00be 100644
--- a/services/audioflinger/StateQueue.cpp
+++ b/services/audioflinger/fastpath/StateQueue.cpp
@@ -41,8 +41,8 @@
 // Constructor and destructor
 
 template<typename T> StateQueue<T>::StateQueue() :
-    mAck(NULL), mCurrent(NULL),
-    mMutating(&mStates[0]), mExpecting(NULL),
+    mAck(nullptr), mCurrent(nullptr),
+    mMutating(&mStates[0]), mExpecting(nullptr),
     mInMutation(false), mIsDirty(false), mIsInitialized(false)
 #ifdef STATE_QUEUE_DUMP
     , mObserverDump(&mObserverDummyDump), mMutatorDump(&mMutatorDummyDump)
@@ -51,10 +51,6 @@
     atomic_init(&mNext, static_cast<uintptr_t>(0));
 }
 
-template<typename T> StateQueue<T>::~StateQueue()
-{
-}
-
 // Observer APIs
 
 template<typename T> const T* StateQueue<T>::poll()
@@ -112,7 +108,7 @@
 #endif
 
         // wait for prior push to be acknowledged
-        if (mExpecting != NULL) {
+        if (mExpecting != nullptr) {
 #ifdef STATE_QUEUE_DUMP
             unsigned count = 0;
 #endif
@@ -120,7 +116,7 @@
                 const T *ack = (const T *) mAck;    // no additional barrier needed
                 if (ack == mExpecting) {
                     // unnecessary as we're about to rewrite
-                    //mExpecting = NULL;
+                    //mExpecting = nullptr;
                     break;
                 }
                 if (block == BLOCK_NEVER) {
@@ -132,7 +128,7 @@
                 }
                 ++count;
 #endif
-                nanosleep(&req, NULL);
+                nanosleep(&req, nullptr);
             }
 #ifdef STATE_QUEUE_DUMP
             if (count > 1) {
@@ -156,14 +152,14 @@
 
     // optionally wait for this push or a prior push to be acknowledged
     if (block == BLOCK_UNTIL_ACKED) {
-        if (mExpecting != NULL) {
+        if (mExpecting != nullptr) {
 #ifdef STATE_QUEUE_DUMP
             unsigned count = 0;
 #endif
             for (;;) {
                 const T *ack = (const T *) mAck;    // no additional barrier needed
                 if (ack == mExpecting) {
-                    mExpecting = NULL;
+                    mExpecting = nullptr;
                     break;
                 }
 #ifdef STATE_QUEUE_DUMP
@@ -172,7 +168,7 @@
                 }
                 ++count;
 #endif
-                nanosleep(&req, NULL);
+                nanosleep(&req, nullptr);
             }
 #ifdef STATE_QUEUE_DUMP
             if (count > 1) {
@@ -187,9 +183,14 @@
 
 }   // namespace android
 
-// Hack to avoid explicit template instantiation of
-// template class StateQueue<FastCaptureState>;
-// template class StateQueue<FastMixerState>;
-#ifdef STATE_QUEUE_INSTANTIATIONS
-#include STATE_QUEUE_INSTANTIATIONS  // NOLINT(bugprone-suspicious-include)
-#endif
+// Instantiate StateQueue template for the types we need.
+// This needs to be done in the same translation unit as the template
+// method definitions above.
+
+#include "FastCaptureState.h"
+#include "FastMixerState.h"
+
+namespace android {
+template class StateQueue<FastCaptureState>;
+template class StateQueue<FastMixerState>;
+}   // namespace android
diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/fastpath/StateQueue.h
similarity index 98%
rename from services/audioflinger/StateQueue.h
rename to services/audioflinger/fastpath/StateQueue.h
index 27f6a28..dff8f3f 100644
--- a/services/audioflinger/StateQueue.h
+++ b/services/audioflinger/fastpath/StateQueue.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIO_STATE_QUEUE_H
-#define ANDROID_AUDIO_STATE_QUEUE_H
+#pragma once
 
 #include <stdatomic.h>
 
@@ -128,7 +127,7 @@
 
 public:
             StateQueue();
-    virtual ~StateQueue();
+    virtual ~StateQueue() = default;  // why is this virtual?
 
     // Observer APIs
 
@@ -211,5 +210,3 @@
 };  // class StateQueue
 
 }   // namespace android
-
-#endif  // ANDROID_AUDIO_STATE_QUEUE_H
diff --git a/services/audioflinger/timing/Android.bp b/services/audioflinger/timing/Android.bp
index 17ce8bd..269f796 100644
--- a/services/audioflinger/timing/Android.bp
+++ b/services/audioflinger/timing/Android.bp
@@ -10,6 +10,10 @@
 cc_library {
     name: "libaudioflinger_timing",
 
+    defaults: [
+        "audioflinger_flags_defaults",
+    ],
+
     host_supported: true,
 
     srcs: [
diff --git a/services/audioflinger/timing/SyncEvent.h b/services/audioflinger/timing/SyncEvent.h
new file mode 100644
index 0000000..b5a3b40
--- /dev/null
+++ b/services/audioflinger/timing/SyncEvent.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <functional>
+#include <mutex>
+
+#include <media/AudioSystem.h>
+#include <utils/RefBase.h>
+
+namespace android::audioflinger {
+
+class SyncEvent;
+using SyncEventCallback = std::function<void(const wp<SyncEvent>& event)>;
+
+class SyncEvent : public RefBase {
+public:
+    SyncEvent(AudioSystem::sync_event_t type,
+              audio_session_t triggerSession,
+              audio_session_t listenerSession,
+              const SyncEventCallback& callBack,
+              const wp<RefBase>& cookie)
+    : mType(type), mTriggerSession(triggerSession), mListenerSession(listenerSession),
+      mCookie(cookie), mCallback(callBack)
+    {}
+
+    void trigger() {
+        std::lock_guard l(mLock);
+        if (mCallback) mCallback(wp<SyncEvent>::fromExisting(this));
+    }
+
+    bool isCancelled() const {
+        std::lock_guard l(mLock);
+        return mCallback == nullptr;
+    }
+
+    void cancel() {
+        std::lock_guard l(mLock);
+        mCallback = nullptr;
+    }
+
+    AudioSystem::sync_event_t type() const { return mType; }
+    audio_session_t triggerSession() const { return mTriggerSession; }
+    audio_session_t listenerSession() const { return mListenerSession; }
+    const wp<RefBase>& cookie() const { return mCookie; }
+
+private:
+      const AudioSystem::sync_event_t mType;
+      const audio_session_t mTriggerSession;
+      const audio_session_t mListenerSession;
+      const wp<RefBase> mCookie;
+      mutable std::mutex mLock;
+      SyncEventCallback mCallback GUARDED_BY(mLock);
+};
+
+} // namespace android::audioflinger
diff --git a/services/audioflinger/timing/SynchronizedRecordState.h b/services/audioflinger/timing/SynchronizedRecordState.h
new file mode 100644
index 0000000..f40d41b
--- /dev/null
+++ b/services/audioflinger/timing/SynchronizedRecordState.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include "SyncEvent.h"
+
+#pragma push_macro("LOG_TAG")
+#undef LOG_TAG
+#define LOG_TAG "SynchronizedRecordState"
+
+namespace android::audioflinger {
+
+class SynchronizedRecordState {
+public:
+    explicit SynchronizedRecordState(uint32_t sampleRate)
+        : mSampleRate(sampleRate)
+        {}
+
+    void clear() {
+        std::lock_guard lg(mLock);
+        clear_l();
+    }
+
+    // Called by the RecordThread when recording is starting.
+    void startRecording(const sp<SyncEvent>& event) {
+        std::lock_guard lg(mLock);
+        mSyncStartEvent = event;
+        // Sync event can be cancelled by the trigger session if the track is not in a
+        // compatible state in which case we start record immediately
+        if (mSyncStartEvent->isCancelled()) {
+            clear_l();
+        } else {
+            mFramesToDrop = -(ssize_t)
+                ((AudioSystem::kSyncRecordStartTimeOutMs * mSampleRate) / 1000);
+        }
+    }
+
+    // Invoked by SyncEvent callback.
+    void onPlaybackFinished(const sp<SyncEvent>& event, size_t framesToDrop = 1) {
+        std::lock_guard lg(mLock);
+        if (event == mSyncStartEvent) {
+            mFramesToDrop = framesToDrop;  // compute this
+            ALOGV("%s: framesToDrop:%zd", __func__, mFramesToDrop);
+        }
+    }
+
+    // Returns the current FramesToDrop counter
+    //
+    //   if <0 waiting (drop the frames)
+    //   if >0 draining (drop the frames)
+    //    else if ==0 proceed to record.
+    ssize_t updateRecordFrames(size_t frames) {
+        std::lock_guard lg(mLock);
+        if (mFramesToDrop > 0) {
+            // we've been triggered, we count down for start delay
+            ALOGV("%s: trigger countdown %zd by %zu frames", __func__, mFramesToDrop, frames);
+            mFramesToDrop -= (ssize_t)frames;
+            if (mFramesToDrop <= 0) clear_l();
+        } else if (mFramesToDrop < 0) {
+            // we're waiting to be triggered.
+            // ALOGD("%s: timeout countup %zd with %zu frames", __func__, mFramesToDrop, frames);
+            mFramesToDrop += (ssize_t)frames;
+            if (mFramesToDrop >= 0 || !mSyncStartEvent || mSyncStartEvent->isCancelled()) {
+                ALOGW("Synced record %s, trigger session %d",
+                        (mFramesToDrop >= 0) ? "timed out" : "cancelled",
+                        (mSyncStartEvent) ? mSyncStartEvent->triggerSession()
+                                          : AUDIO_SESSION_NONE);
+                 clear_l();
+            }
+        }
+        return mFramesToDrop;
+    }
+
+private:
+    const uint32_t mSampleRate;
+
+    std::mutex mLock;
+    // number of captured frames to drop after the start sync event has been received.
+    // when < 0, maximum frames to drop before starting capture even if sync event is
+    // not received
+    ssize_t mFramesToDrop GUARDED_BY(mLock) = 0;
+
+    // sync event triggering actual audio capture. Frames read before this event will
+    // be dropped and therefore not read by the application.
+    sp<SyncEvent> mSyncStartEvent GUARDED_BY(mLock);
+
+    void clear_l() REQUIRES(mLock) {
+        if (mSyncStartEvent) {
+            mSyncStartEvent->cancel();
+            mSyncStartEvent.clear();
+        }
+        mFramesToDrop = 0;
+    }
+};
+
+} // namespace android::audioflinger
+
+#pragma pop_macro("LOG_TAG")
diff --git a/services/audioflinger/timing/tests/Android.bp b/services/audioflinger/timing/tests/Android.bp
index 29267a6..d1e5563 100644
--- a/services/audioflinger/timing/tests/Android.bp
+++ b/services/audioflinger/timing/tests/Android.bp
@@ -8,6 +8,31 @@
 }
 
 cc_test {
+    name: "mediasyncevent_tests",
+
+    host_supported: true,
+
+    srcs: [
+        "mediasyncevent_tests.cpp"
+    ],
+
+    header_libs: [
+        "libaudioclient_headers",
+    ],
+
+    static_libs: [
+        "liblog",
+        "libutils", // RefBase
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+cc_test {
     name: "monotonicframecounter_tests",
 
     host_supported: true,
@@ -26,4 +51,29 @@
         "-Werror",
         "-Wextra",
     ],
-}
\ No newline at end of file
+}
+
+cc_test {
+     name: "synchronizedrecordstate_tests",
+
+     host_supported: true,
+
+     srcs: [
+         "synchronizedrecordstate_tests.cpp"
+     ],
+
+     header_libs: [
+         "libaudioclient_headers",
+     ],
+
+     static_libs: [
+         "liblog",
+         "libutils", // RefBase
+     ],
+
+     cflags: [
+         "-Wall",
+         "-Werror",
+         "-Wextra",
+     ],
+ }
\ No newline at end of file
diff --git a/services/audioflinger/timing/tests/mediasyncevent_tests.cpp b/services/audioflinger/timing/tests/mediasyncevent_tests.cpp
new file mode 100644
index 0000000..2922d90
--- /dev/null
+++ b/services/audioflinger/timing/tests/mediasyncevent_tests.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "mediasyncevent_tests"
+
+#include "../SyncEvent.h"
+
+#include <gtest/gtest.h>
+
+using namespace android;
+using namespace android::audioflinger;
+
+namespace {
+
+TEST(MediaSyncEventTests, Basic) {
+    struct Cookie : public RefBase {};
+
+    // These variables are set by trigger().
+    bool triggered = false;
+    wp<SyncEvent> param;
+
+    constexpr auto type = AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
+    constexpr auto triggerSession = audio_session_t(10);
+    constexpr auto listenerSession = audio_session_t(11);
+    const SyncEventCallback callback =
+            [&](const wp<SyncEvent>& event) {
+                triggered = true;
+                param = event;
+            };
+    const auto cookie = sp<Cookie>::make();
+
+    // Since the callback uses a weak pointer to this,
+    // don't allocate on the stack.
+    auto syncEvent = sp<SyncEvent>::make(
+            type,
+            triggerSession,
+            listenerSession,
+            callback,
+            cookie);
+
+    ASSERT_EQ(type, syncEvent->type());
+    ASSERT_EQ(triggerSession, syncEvent->triggerSession());
+    ASSERT_EQ(listenerSession, syncEvent->listenerSession());
+    ASSERT_EQ(cookie, syncEvent->cookie());
+    ASSERT_FALSE(triggered);
+
+    syncEvent->trigger();
+    ASSERT_TRUE(triggered);
+    ASSERT_EQ(param, syncEvent);
+
+    ASSERT_FALSE(syncEvent->isCancelled());
+    syncEvent->cancel();
+    ASSERT_TRUE(syncEvent->isCancelled());
+}
+
+} // namespace
diff --git a/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp b/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp
new file mode 100644
index 0000000..ee5d269
--- /dev/null
+++ b/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "synchronizedrecordstate_tests"
+
+#include "../SynchronizedRecordState.h"
+
+#include <gtest/gtest.h>
+
+using namespace android;
+using namespace android::audioflinger;
+
+namespace {
+
+TEST(SynchronizedRecordStateTests, Basic) {
+    struct Cookie : public RefBase {};
+
+    // These variables are set by trigger().
+    bool triggered = false;
+    wp<SyncEvent> param;
+
+    constexpr auto type = AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
+    constexpr auto triggerSession = audio_session_t(10);
+    constexpr auto listenerSession = audio_session_t(11);
+    const SyncEventCallback callback =
+            [&](const wp<SyncEvent>& event) {
+                triggered = true;
+                param = event;
+            };
+    const auto cookie = sp<Cookie>::make();
+
+    // Check timeout.
+    SynchronizedRecordState recordState(48000 /* sampleRate */);
+    auto syncEvent = sp<SyncEvent>::make(
+            type,
+            triggerSession,
+            listenerSession,
+            callback,
+            cookie);
+    recordState.startRecording(syncEvent);
+    recordState.updateRecordFrames(2);
+    ASSERT_FALSE(triggered);
+    ASSERT_EQ(0, recordState.updateRecordFrames(1'000'000'000));
+    ASSERT_FALSE(triggered);
+    ASSERT_TRUE(syncEvent->isCancelled());
+
+    // Check count down after track is complete.
+    syncEvent = sp<SyncEvent>::make(
+                type,
+                triggerSession,
+                listenerSession,
+                callback,
+                cookie);
+    recordState.startRecording(syncEvent);
+    recordState.onPlaybackFinished(syncEvent, 10);
+    ASSERT_EQ(1, recordState.updateRecordFrames(9));
+    ASSERT_FALSE(triggered);
+    ASSERT_EQ(0, recordState.updateRecordFrames(2));
+    ASSERT_FALSE(triggered);
+    ASSERT_TRUE(syncEvent->isCancelled());
+}
+
+}
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index 98d7d59..03ab3f8 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -75,7 +75,7 @@
             if (checkExactAudioProfile(&config) != NO_ERROR) {
                 return false;
             }
-        } else if (checkCompatibleAudioProfile(
+        } else if (checkExactAudioProfile(&config) != NO_ERROR && checkCompatibleAudioProfile(
                 myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) != NO_ERROR) {
             return false;
         }
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 6f4c04a..a4d74cb 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -2530,7 +2530,11 @@
         const CameraResourceCost& resourceCost,
         sp<ProviderInfo> parentProvider,
         const std::vector<std::string>& publicCameraIds) :
-        DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
+        DeviceInfo(name, tagId, id,
+                   hardware::hidl_version{
+                        static_cast<uint16_t >(
+                                parentProvider->getIPCTransport() == IPCTransport::HIDL ? 3 : 1),
+                                minorVersion},
                    publicCameraIds, resourceCost, parentProvider) { }
 
 void CameraProviderManager::ProviderInfo::DeviceInfo3::notifyDeviceStateChange(int64_t newState) {
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index b1bf41e..921ad7d 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -29,11 +29,8 @@
     ],
 }
 
-cc_fuzz {
-    name: "camera_service_fuzzer",
-    srcs: [
-        "camera_service_fuzzer.cpp",
-    ],
+cc_defaults {
+    name: "camera_service_fuzzer_defaults",
     header_libs: [
         "libmedia_headers",
     ],
@@ -74,3 +71,28 @@
 
     },
 }
+
+cc_fuzz {
+    name: "camera_service_fuzzer",
+    srcs: [
+        "camera_service_fuzzer.cpp",
+    ],
+    defaults: [
+        "camera_service_fuzzer_defaults"
+    ],
+}
+
+cc_fuzz {
+    name: "camera_service_aidl_fuzzer",
+    srcs: [
+        "camera_service_aidl_fuzzer.cpp",
+    ],
+    defaults: [
+        "camera_service_fuzzer_defaults",
+        "service_fuzzer_defaults",
+        "fuzzer_disable_leaks",
+    ],
+    fuzz_config: {
+        triage_assignee: "waghpawan@google.com",
+    },
+}
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_aidl_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_aidl_fuzzer.cpp
new file mode 100644
index 0000000..a0fb93c
--- /dev/null
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_aidl_fuzzer.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_driver.h>
+#include <CameraService.h>
+
+using android::fuzzService;
+using android::sp;
+using android::CameraService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto service = sp<CameraService>::make();
+    fuzzService(service, FuzzedDataProvider(data, size));
+    return 0;
+}
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index acafe56..e22d749 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -89,3 +89,25 @@
         "code_coverage.policy",
     ],
 }
+
+cc_fuzz {
+    name: "mediaextractor_service_fuzzer",
+    shared_libs: [
+        "libmedia",
+        "libmediaextractorservice",
+        "libmediautils",
+        "liblog",
+        "libavservices_minijail",
+    ],
+    defaults: [
+        "service_fuzzer_defaults",
+        "fuzzer_disable_leaks",
+    ],
+    srcs: ["fuzzers/MediaExtractorServiceFuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "android-media-playback+bugs@google.com",
+        ],
+        triage_assignee: "waghpawan@google.com",
+    },
+}
\ No newline at end of file
diff --git a/services/mediaextractor/fuzzers/MediaExtractorServiceFuzzer.cpp b/services/mediaextractor/fuzzers/MediaExtractorServiceFuzzer.cpp
new file mode 100644
index 0000000..d329e54
--- /dev/null
+++ b/services/mediaextractor/fuzzers/MediaExtractorServiceFuzzer.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_driver.h>
+
+#include "MediaExtractorService.h"
+
+using ::android::fuzzService;
+using ::android::sp;
+using ::android::MediaExtractorService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto service = sp<MediaExtractorService>::make();
+    fuzzService(service, FuzzedDataProvider(data, size));
+    return 0;
+}
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
index 20a6378..99703e3 100644
--- a/services/mediametrics/fuzzer/Android.bp
+++ b/services/mediametrics/fuzzer/Android.bp
@@ -27,13 +27,8 @@
     default_applicable_licenses: ["frameworks_av_license"],
 }
 
-cc_fuzz {
-    name: "mediametrics_service_fuzzer",
-
-    srcs: [
-        "mediametrics_service_fuzzer.cpp",
-    ],
-
+cc_defaults {
+    name: "mediametrics_service_fuzzer_defaults",
     static_libs: [
         "libmediametrics",
         "libmediametricsservice",
@@ -78,3 +73,26 @@
         fuzzed_code_usage: "shipped",
     },
 }
+
+cc_fuzz {
+    name: "mediametrics_service_fuzzer",
+
+    srcs: [
+        "mediametrics_service_fuzzer.cpp",
+    ],
+    defaults: [
+        "mediametrics_service_fuzzer_defaults",
+    ],
+}
+
+cc_fuzz {
+    name: "mediametrics_aidl_fuzzer",
+    srcs: [
+        "mediametrics_aidl_fuzzer.cpp",
+    ],
+    defaults: [
+        "service_fuzzer_defaults",
+        "fuzzer_disable_leaks",
+        "mediametrics_service_fuzzer_defaults",
+    ],
+}
diff --git a/services/mediametrics/fuzzer/mediametrics_aidl_fuzzer.cpp b/services/mediametrics/fuzzer/mediametrics_aidl_fuzzer.cpp
new file mode 100644
index 0000000..c7468c7
--- /dev/null
+++ b/services/mediametrics/fuzzer/mediametrics_aidl_fuzzer.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_driver.h>
+
+#include <mediametricsservice/MediaMetricsService.h>
+
+using ::android::fuzzService;
+using ::android::sp;
+using ::android::MediaMetricsService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto service = sp<MediaMetricsService>::make();
+    fuzzService(service, FuzzedDataProvider(data, size));
+    return 0;
+}