Merge "libstagefright/exports.lds: Use regex pattern for some functions"
diff --git a/OWNERS b/OWNERS
index 40c65e7..87bc809 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,7 +1,12 @@
-# Bug component: 1344
+## Media team top-level OWNERS, bug component: 1344
+## Only contact for camera changes as a fallback
 elaurent@google.com
-etalvala@google.com
 lajos@google.com
 
 # go/android-fwk-media-solutions for info on areas of ownership.
 include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
+
+## Camera team top-level OWNERS, bug component: 41727
+## Only contact for media changes as a fallback
+etalvala@google.com
+shuzhenwang@google.com
diff --git a/camera/OWNERS b/camera/OWNERS
index 385c163..b705548 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,7 +1,11 @@
 # Bug component: 41727
 etalvala@google.com
 arakesh@google.com
+borgera@google.com
+bkukreja@google.com
 epeev@google.com
 jchowdhary@google.com
-shuzhenwang@google.com
+rdhanjal@google.com
 ruchamk@google.com
+shuzhenwang@google.com
+
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index b277bed..79b1263 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -13,6 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <algorithm>
+#include <string_view>
+#include <type_traits>
 
 #include <assert.h>
 #include <ctype.h>
@@ -85,6 +88,7 @@
 using android::Vector;
 using android::sp;
 using android::status_t;
+using android::SurfaceControl;
 
 using android::INVALID_OPERATION;
 using android::NAME_NOT_FOUND;
@@ -100,7 +104,6 @@
 static const uint32_t kFallbackHeight = 720;
 static const char* kMimeTypeAvc = "video/avc";
 static const char* kMimeTypeApplicationOctetstream = "application/octet-stream";
-static const char* kWinscopeMagicString = "#VV1NSC0PET1ME!#";
 
 // Command-line parameters.
 static bool gVerbose = false;           // chatty on stdout
@@ -339,13 +342,20 @@
 static status_t prepareVirtualDisplay(
         const ui::DisplayState& displayState,
         const sp<IGraphicBufferProducer>& bufferProducer,
-        sp<IBinder>* pDisplayHandle) {
+        sp<IBinder>* pDisplayHandle, sp<SurfaceControl>* mirrorRoot) {
     sp<IBinder> dpy = SurfaceComposerClient::createDisplay(
             String8("ScreenRecorder"), false /*secure*/);
     SurfaceComposerClient::Transaction t;
     t.setDisplaySurface(dpy, bufferProducer);
     setDisplayProjection(t, dpy, displayState);
-    t.setDisplayLayerStack(dpy, displayState.layerStack);
+    ui::LayerStack layerStack = ui::LayerStack::fromValue(std::rand());
+    t.setDisplayLayerStack(dpy, layerStack);
+    *mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(gPhysicalDisplayId);
+    if (*mirrorRoot == nullptr) {
+        ALOGE("Failed to create a mirror for screenrecord");
+        return UNKNOWN_ERROR;
+    }
+    t.setLayerStack(*mirrorRoot, layerStack);
     t.apply();
 
     *pDisplayHandle = dpy;
@@ -354,14 +364,15 @@
 }
 
 /*
- * Writes an unsigned integer byte-by-byte in little endian order regardless
+ * Writes an unsigned/signed integer byte-by-byte in little endian order regardless
  * of the platform endianness.
  */
-template <typename UINT>
-static void writeValueLE(UINT value, uint8_t* buffer) {
-    for (int i = 0; i < sizeof(UINT); ++i) {
-        buffer[i] = static_cast<uint8_t>(value);
-        value >>= 8;
+template <typename T>
+static void writeValueLE(T value, uint8_t* buffer) {
+    std::remove_const_t<T> temp = value;
+    for (int i = 0; i < sizeof(T); ++i) {
+        buffer[i] = static_cast<std::uint8_t>(temp & 0xff);
+        temp >>= 8;
     }
 }
 
@@ -377,16 +388,18 @@
  * - for every frame its presentation time relative to the elapsed realtime clock in microseconds
  *   (as little endian uint64).
  */
-static status_t writeWinscopeMetadata(const Vector<int64_t>& timestamps,
+static status_t writeWinscopeMetadataLegacy(const Vector<int64_t>& timestamps,
         const ssize_t metaTrackIdx, AMediaMuxer *muxer) {
-    ALOGV("Writing metadata");
+    static constexpr auto kWinscopeMagicStringLegacy = "#VV1NSC0PET1ME!#";
+
+    ALOGV("Writing winscope metadata legacy");
     int64_t systemTimeToElapsedTimeOffsetMicros = (android::elapsedRealtimeNano()
         - systemTime(SYSTEM_TIME_MONOTONIC)) / 1000;
     sp<ABuffer> buffer = new ABuffer(timestamps.size() * sizeof(int64_t)
-        + sizeof(uint32_t) + strlen(kWinscopeMagicString));
+        + sizeof(uint32_t) + strlen(kWinscopeMagicStringLegacy));
     uint8_t* pos = buffer->data();
-    strcpy(reinterpret_cast<char*>(pos), kWinscopeMagicString);
-    pos += strlen(kWinscopeMagicString);
+    strcpy(reinterpret_cast<char*>(pos), kWinscopeMagicStringLegacy);
+    pos += strlen(kWinscopeMagicStringLegacy);
     writeValueLE<uint32_t>(timestamps.size(), pos);
     pos += sizeof(uint32_t);
     for (size_t idx = 0; idx < timestamps.size(); ++idx) {
@@ -395,10 +408,68 @@
         pos += sizeof(uint64_t);
     }
     AMediaCodecBufferInfo bufferInfo = {
-        0,
+        0 /* offset */,
         static_cast<int32_t>(buffer->size()),
-        timestamps[0],
-        0
+        timestamps[0] /* presentationTimeUs */,
+        0 /* flags */
+    };
+    return AMediaMuxer_writeSampleData(muxer, metaTrackIdx, buffer->data(), &bufferInfo);
+}
+
+/*
+ * Saves metadata needed by Winscope to synchronize the screen recording playback with other traces.
+ *
+ * The metadata (version 1) is written as a binary array with the following format:
+ * - winscope magic string (#VV1NSC0PET1ME2#, 16B).
+ * - the metadata version number (4B).
+ * - Realtime-to-monotonic time offset in nanoseconds (8B).
+ * - the recorded frames count (8B)
+ * - for each recorded frame:
+ *     - System time in monotonic clock timebase in nanoseconds (8B).
+ *
+ * All numbers are Little Endian encoded.
+ */
+static status_t writeWinscopeMetadata(const Vector<std::int64_t>& timestampsMonotonicUs,
+        const ssize_t metaTrackIdx, AMediaMuxer *muxer) {
+    ALOGV("Writing winscope metadata");
+
+    static constexpr auto kWinscopeMagicString = std::string_view {"#VV1NSC0PET1ME2#"};
+    static constexpr std::uint32_t metadataVersion = 1;
+    const std::int64_t realToMonotonicTimeOffsetNs =
+            systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC);
+    const std::uint32_t framesCount = static_cast<std::uint32_t>(timestampsMonotonicUs.size());
+
+    sp<ABuffer> buffer = new ABuffer(
+        kWinscopeMagicString.size() +
+        sizeof(decltype(metadataVersion)) +
+        sizeof(decltype(realToMonotonicTimeOffsetNs)) +
+        sizeof(decltype(framesCount)) +
+        framesCount * sizeof(std::uint64_t)
+    );
+    std::uint8_t* pos = buffer->data();
+
+    std::copy(kWinscopeMagicString.cbegin(), kWinscopeMagicString.cend(), pos);
+    pos += kWinscopeMagicString.size();
+
+    writeValueLE(metadataVersion, pos);
+    pos += sizeof(decltype(metadataVersion));
+
+    writeValueLE(realToMonotonicTimeOffsetNs, pos);
+    pos += sizeof(decltype(realToMonotonicTimeOffsetNs));
+
+    writeValueLE(framesCount, pos);
+    pos += sizeof(decltype(framesCount));
+
+    for (const auto timestampMonotonicUs : timestampsMonotonicUs) {
+        writeValueLE<std::uint64_t>(timestampMonotonicUs * 1000, pos);
+        pos += sizeof(std::uint64_t);
+    }
+
+    AMediaCodecBufferInfo bufferInfo = {
+        0 /* offset */,
+        static_cast<std::int32_t>(buffer->size()),
+        timestampsMonotonicUs[0] /* presentationTimeUs */,
+        0 /* flags */
     };
     return AMediaMuxer_writeSampleData(muxer, metaTrackIdx, buffer->data(), &bufferInfo);
 }
@@ -418,11 +489,12 @@
     static int kTimeout = 250000;   // be responsive on signal
     status_t err;
     ssize_t trackIdx = -1;
+    ssize_t metaLegacyTrackIdx = -1;
     ssize_t metaTrackIdx = -1;
     uint32_t debugNumFrames = 0;
     int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
     int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
-    Vector<int64_t> timestamps;
+    Vector<int64_t> timestampsMonotonicUs;
     bool firstFrame = true;
 
     assert((rawFp == NULL && muxer != NULL) || (rawFp != NULL && muxer == NULL));
@@ -520,9 +592,9 @@
                     sp<ABuffer> buffer = new ABuffer(
                             buffers[bufIndex]->data(), buffers[bufIndex]->size());
                     AMediaCodecBufferInfo bufferInfo = {
-                        0,
+                        0 /* offset */,
                         static_cast<int32_t>(buffer->size()),
-                        ptsUsec,
+                        ptsUsec /* presentationTimeUs */,
                         flags
                     };
                     err = AMediaMuxer_writeSampleData(muxer, trackIdx, buffer->data(), &bufferInfo);
@@ -532,7 +604,7 @@
                         return err;
                     }
                     if (gOutputFormat == FORMAT_MP4) {
-                        timestamps.add(ptsUsec);
+                        timestampsMonotonicUs.add(ptsUsec);
                     }
                 }
                 debugNumFrames++;
@@ -565,6 +637,7 @@
                     if (gOutputFormat == FORMAT_MP4) {
                         AMediaFormat *metaFormat = AMediaFormat_new();
                         AMediaFormat_setString(metaFormat, AMEDIAFORMAT_KEY_MIME, kMimeTypeApplicationOctetstream);
+                        metaLegacyTrackIdx = AMediaMuxer_addTrack(muxer, metaFormat);
                         metaTrackIdx = AMediaMuxer_addTrack(muxer, metaFormat);
                         AMediaFormat_delete(metaFormat);
                     }
@@ -604,10 +677,16 @@
                         systemTime(CLOCK_MONOTONIC) - startWhenNsec));
         fflush(stdout);
     }
-    if (metaTrackIdx >= 0 && !timestamps.isEmpty()) {
-        err = writeWinscopeMetadata(timestamps, metaTrackIdx, muxer);
+    if (metaLegacyTrackIdx >= 0 && metaTrackIdx >= 0 && !timestampsMonotonicUs.isEmpty()) {
+        err = writeWinscopeMetadataLegacy(timestampsMonotonicUs, metaLegacyTrackIdx, muxer);
         if (err != NO_ERROR) {
-            fprintf(stderr, "Failed writing metadata to muxer (err=%d)\n", err);
+            fprintf(stderr, "Failed writing legacy winscope metadata to muxer (err=%d)\n", err);
+            return err;
+        }
+
+        err = writeWinscopeMetadata(timestampsMonotonicUs, metaTrackIdx, muxer);
+        if (err != NO_ERROR) {
+            fprintf(stderr, "Failed writing winscope metadata to muxer (err=%d)\n", err);
             return err;
         }
     }
@@ -656,6 +735,23 @@
     return num & ~1;
 }
 
+struct RecordingData {
+    sp<MediaCodec> encoder;
+    // Configure virtual display.
+    sp<IBinder> dpy;
+
+    sp<Overlay> overlay;
+
+    ~RecordingData() {
+        if (dpy != nullptr) SurfaceComposerClient::destroyDisplay(dpy);
+        if (overlay != nullptr) overlay->stop();
+        if (encoder != nullptr) {
+            encoder->stop();
+            encoder->release();
+        }
+    }
+};
+
 /*
  * Main "do work" start point.
  *
@@ -713,12 +809,12 @@
         gVideoHeight = floorToEven(layerStackSpaceRect.getHeight());
     }
 
+    RecordingData recordingData = RecordingData();
     // Configure and start the encoder.
-    sp<MediaCodec> encoder;
     sp<FrameOutput> frameOutput;
     sp<IGraphicBufferProducer> encoderInputSurface;
     if (gOutputFormat != FORMAT_FRAMES && gOutputFormat != FORMAT_RAW_FRAMES) {
-        err = prepareEncoder(displayMode.refreshRate, &encoder, &encoderInputSurface);
+        err = prepareEncoder(displayMode.refreshRate, &recordingData.encoder, &encoderInputSurface);
 
         if (err != NO_ERROR && !gSizeSpecified) {
             // fallback is defined for landscape; swap if we're in portrait
@@ -731,7 +827,8 @@
                         gVideoWidth, gVideoHeight, newWidth, newHeight);
                 gVideoWidth = newWidth;
                 gVideoHeight = newHeight;
-                err = prepareEncoder(displayMode.refreshRate, &encoder, &encoderInputSurface);
+                err = prepareEncoder(displayMode.refreshRate, &recordingData.encoder,
+                                      &encoderInputSurface);
             }
         }
         if (err != NO_ERROR) return err;
@@ -758,13 +855,11 @@
 
     // Configure optional overlay.
     sp<IGraphicBufferProducer> bufferProducer;
-    sp<Overlay> overlay;
     if (gWantFrameTime) {
         // Send virtual display frames to an external texture.
-        overlay = new Overlay(gMonotonicTime);
-        err = overlay->start(encoderInputSurface, &bufferProducer);
+        recordingData.overlay = new Overlay(gMonotonicTime);
+        err = recordingData.overlay->start(encoderInputSurface, &bufferProducer);
         if (err != NO_ERROR) {
-            if (encoder != NULL) encoder->release();
             return err;
         }
         if (gVerbose) {
@@ -776,11 +871,13 @@
         bufferProducer = encoderInputSurface;
     }
 
+    // We need to hold a reference to mirrorRoot during the entire recording to ensure it's not
+    // cleaned up by SurfaceFlinger. When the reference is dropped, SurfaceFlinger will delete
+    // the resource.
+    sp<SurfaceControl> mirrorRoot;
     // Configure virtual display.
-    sp<IBinder> dpy;
-    err = prepareVirtualDisplay(displayState, bufferProducer, &dpy);
+    err = prepareVirtualDisplay(displayState, bufferProducer, &recordingData.dpy, &mirrorRoot);
     if (err != NO_ERROR) {
-        if (encoder != NULL) encoder->release();
         return err;
     }
 
@@ -820,7 +917,6 @@
         case FORMAT_RAW_FRAMES: {
             rawFp = prepareRawOutput(fileName);
             if (rawFp == NULL) {
-                if (encoder != NULL) encoder->release();
                 return -1;
             }
             break;
@@ -861,7 +957,8 @@
         }
     } else {
         // Main encoder loop.
-        err = runEncoder(encoder, muxer, rawFp, display, dpy, displayState.orientation);
+        err = runEncoder(recordingData.encoder, muxer, rawFp, display, recordingData.dpy,
+                         displayState.orientation);
         if (err != NO_ERROR) {
             fprintf(stderr, "Encoder failed (err=%d)\n", err);
             // fall through to cleanup
@@ -875,9 +972,6 @@
 
     // Shut everything down, starting with the producer side.
     encoderInputSurface = NULL;
-    SurfaceComposerClient::destroyDisplay(dpy);
-    if (overlay != NULL) overlay->stop();
-    if (encoder != NULL) encoder->stop();
     if (muxer != NULL) {
         // If we don't stop muxer explicitly, i.e. let the destructor run,
         // it may hang (b/11050628).
@@ -885,7 +979,6 @@
     } else if (rawFp != stdout) {
         fclose(rawFp);
     }
-    if (encoder != NULL) encoder->release();
 
     return err;
 }
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 0bd0d88..d62dd91 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -8,6 +8,7 @@
     task_profiles ProcessCapacityHigh HighPerformance
     onrestart restart vendor.audio-hal
     onrestart restart vendor.audio-hal-aidl
+    onrestart restart vendor.audio-effect-hal-aidl
     onrestart restart vendor.audio-hal-4-0-msd
     onrestart restart audio_proxy_service
 
@@ -19,6 +20,7 @@
 on property:init.svc.audioserver=stopped
     stop vendor.audio-hal
     stop vendor.audio-hal-aidl
+    stop vendor.audio-effect-hal-aidl
     stop vendor.audio-hal-4-0-msd
     stop audio_proxy_service
     # See b/155364397. Need to have HAL service running for VTS.
@@ -26,12 +28,14 @@
     # audioserver bringing it back into running state.
     start vendor.audio-hal
     start vendor.audio-hal-aidl
+    start vendor.audio-effect-hal-aidl
     start vendor.audio-hal-4-0-msd
     start audio_proxy_service
 
 on property:init.svc.audioserver=running
     start vendor.audio-hal
     start vendor.audio-hal-aidl
+    start vendor.audio-effect-hal-aidl
     start vendor.audio-hal-4-0-msd
     start audio_proxy_service
 
@@ -40,10 +44,12 @@
     # Keep the original service names for backward compatibility
     stop vendor.audio-hal
     stop vendor.audio-hal-aidl
+    stop vendor.audio-effect-hal-aidl
     stop vendor.audio-hal-4-0-msd
     stop audio_proxy_service
     start vendor.audio-hal
     start vendor.audio-hal-aidl
+    start vendor.audio-effect-hal-aidl
     start vendor.audio-hal-4-0-msd
     start audio_proxy_service
     # reset the property
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 4dec57f..d234f21 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -102,6 +102,29 @@
             .withSetter(Hdr10PlusInfoOutputSetter)
             .build());
 
+    // default static info
+    C2HdrStaticMetadataStruct defaultStaticInfo{};
+    helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
+    addParameter(
+        DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
+            .withDefault(new C2StreamHdrStaticInfo::output(0u, defaultStaticInfo))
+            .withFields({
+                C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.red.y).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.green.x).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.green.y).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.blue.x).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.blue.y).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+                C2F(mHdrStaticInfo, mastering.maxLuminance).inRange(0, 65535),
+                C2F(mHdrStaticInfo, mastering.minLuminance).inRange(0, 6.5535),
+                C2F(mHdrStaticInfo, maxCll).inRange(0, 0XFFFF),
+                C2F(mHdrStaticInfo, maxFall).inRange(0, 0XFFFF)
+            })
+            .withSetter(HdrStaticInfoSetter)
+            .build());
+
     addParameter(
         DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
             .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
@@ -331,6 +354,47 @@
   // unsafe getters
   std::shared_ptr<C2StreamPixelFormatInfo::output> getPixelFormat_l() const { return mPixelFormat; }
 
+  static C2R HdrStaticInfoSetter(bool mayBlock, C2P<C2StreamHdrStaticInfo::output> &me) {
+    (void)mayBlock;
+    if (me.v.mastering.red.x > 1) {
+      me.set().mastering.red.x = 1;
+    }
+    if (me.v.mastering.red.y > 1) {
+      me.set().mastering.red.y = 1;
+    }
+    if (me.v.mastering.green.x > 1) {
+      me.set().mastering.green.x = 1;
+    }
+    if (me.v.mastering.green.y > 1) {
+      me.set().mastering.green.y = 1;
+    }
+    if (me.v.mastering.blue.x > 1) {
+      me.set().mastering.blue.x = 1;
+    }
+    if (me.v.mastering.blue.y > 1) {
+      me.set().mastering.blue.y = 1;
+    }
+    if (me.v.mastering.white.x > 1) {
+      me.set().mastering.white.x = 1;
+    }
+    if (me.v.mastering.white.y > 1) {
+      me.set().mastering.white.y = 1;
+    }
+    if (me.v.mastering.maxLuminance > 65535.0) {
+      me.set().mastering.maxLuminance = 65535.0;
+    }
+    if (me.v.mastering.minLuminance > 6.5535) {
+      me.set().mastering.minLuminance = 6.5535;
+    }
+    if (me.v.maxCll > 65535.0) {
+      me.set().maxCll = 65535.0;
+    }
+    if (me.v.maxFall > 65535.0) {
+      me.set().maxFall = 65535.0;
+    }
+    return C2R::Ok();
+  }
+
  private:
   std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
   std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
@@ -343,6 +407,7 @@
   std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
   std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
   std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+  std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
 };
 
 C2SoftGav1Dec::C2SoftGav1Dec(const char *name, c2_node_id_t id,
@@ -558,6 +623,76 @@
   }
 }
 
+void C2SoftGav1Dec::getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+                                       const std::unique_ptr<C2Work> &work) {
+  C2StreamHdrStaticMetadataInfo::output hdrStaticMetadataInfo{};
+  bool infoPresent = false;
+  if (buffer->has_hdr_mdcv) {
+    // hdr_mdcv.primary_chromaticity_* values are in 0.16 fixed-point format.
+    hdrStaticMetadataInfo.mastering.red.x = buffer->hdr_mdcv.primary_chromaticity_x[0] / 65536.0;
+    hdrStaticMetadataInfo.mastering.red.y = buffer->hdr_mdcv.primary_chromaticity_y[0] / 65536.0;
+
+    hdrStaticMetadataInfo.mastering.green.x = buffer->hdr_mdcv.primary_chromaticity_x[1] / 65536.0;
+    hdrStaticMetadataInfo.mastering.green.y = buffer->hdr_mdcv.primary_chromaticity_y[1] / 65536.0;
+
+    hdrStaticMetadataInfo.mastering.blue.x = buffer->hdr_mdcv.primary_chromaticity_x[2] / 65536.0;
+    hdrStaticMetadataInfo.mastering.blue.y = buffer->hdr_mdcv.primary_chromaticity_y[2] / 65536.0;
+
+    // hdr_mdcv.white_point_chromaticity_* values are in 0.16 fixed-point format.
+    hdrStaticMetadataInfo.mastering.white.x = buffer->hdr_mdcv.white_point_chromaticity_x / 65536.0;
+    hdrStaticMetadataInfo.mastering.white.y = buffer->hdr_mdcv.white_point_chromaticity_y / 65536.0;
+
+    // hdr_mdcv.luminance_max is in 24.8 fixed-point format.
+    hdrStaticMetadataInfo.mastering.maxLuminance = buffer->hdr_mdcv.luminance_max / 256.0;
+    // hdr_mdcv.luminance_min is in 18.14 format.
+    hdrStaticMetadataInfo.mastering.minLuminance = buffer->hdr_mdcv.luminance_min / 16384.0;
+    infoPresent = true;
+  }
+
+  if (buffer->has_hdr_cll) {
+    hdrStaticMetadataInfo.maxCll = buffer->hdr_cll.max_cll;
+    hdrStaticMetadataInfo.maxFall = buffer->hdr_cll.max_fall;
+    infoPresent = true;
+  }
+  // config if static info has changed
+  if (infoPresent && !(hdrStaticMetadataInfo == mHdrStaticMetadataInfo)) {
+    mHdrStaticMetadataInfo = hdrStaticMetadataInfo;
+    work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(mHdrStaticMetadataInfo));
+  }
+}
+
+void C2SoftGav1Dec::getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+                                         const std::unique_ptr<C2Work> &work) {
+  if (buffer->has_itut_t35) {
+    std::vector<uint8_t> payload;
+    size_t payloadSize = buffer->itut_t35.payload_size;
+    if (payloadSize > 0) {
+      payload.push_back(buffer->itut_t35.country_code);
+      if (buffer->itut_t35.country_code == 0xFF) {
+        payload.push_back(buffer->itut_t35.country_code_extension_byte);
+      }
+      payload.insert(payload.end(), buffer->itut_t35.payload_bytes,
+                     buffer->itut_t35.payload_bytes + buffer->itut_t35.payload_size);
+    }
+
+    std::unique_ptr<C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
+            C2StreamHdr10PlusInfo::output::AllocUnique(payload.size());
+    if (!hdr10PlusInfo) {
+      ALOGE("Hdr10PlusInfo allocation failed");
+      mSignalledError = true;
+      work->result = C2_NO_MEMORY;
+      return;
+    }
+    memcpy(hdr10PlusInfo->m.value, payload.data(), payload.size());
+
+    // config if hdr10Plus info has changed
+    if (nullptr == mHdr10PlusInfo || !(*hdr10PlusInfo == *mHdr10PlusInfo)) {
+      mHdr10PlusInfo = std::move(hdr10PlusInfo);
+      work->worklets.front()->output.configUpdate.push_back(std::move(mHdr10PlusInfo));
+    }
+  }
+}
+
 void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
     VuiColorAspects vuiColorAspects;
     vuiColorAspects.primaries = buffer->color_primary;
@@ -633,6 +768,9 @@
   }
 
   getVuiParams(buffer);
+  getHDRStaticParams(buffer, work);
+  getHDR10PlusInfoData(buffer, work);
+
   if (!(buffer->image_format == libgav1::kImageFormatYuv420 ||
         buffer->image_format == libgav1::kImageFormatMonochrome400)) {
     ALOGE("image_format %d not supported", buffer->image_format);
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index 3d4db55..e51c511 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -61,6 +61,9 @@
   bool mSignalledOutputEos;
   bool mSignalledError;
 
+  C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
+  std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
+
   // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
   // converting them to C2 values for each frame
   struct VuiColorAspects {
@@ -86,6 +89,10 @@
   nsecs_t mTimeEnd = 0;    // Time at the end of decode()
 
   bool initDecoder();
+  void getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+                  const std::unique_ptr<C2Work> &work);
+  void getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+                  const std::unique_ptr<C2Work> &work);
   void getVuiParams(const libgav1::DecoderBuffer *buffer);
   void destroyDecoder();
   void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 5c24bd7..35a3b53 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -1447,6 +1447,10 @@
 bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
     switch (s.getDiscriminator()) {
     case BaseBlock::hidl_discriminator::nativeBlock: {
+            if (s.nativeBlock() == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
+                return false;
+            }
             native_handle_t* sHandle =
                     native_handle_clone(s.nativeBlock());
             if (sHandle == nullptr) {
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 5a652a3..ecd5463 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -44,7 +44,7 @@
     ],
 
     static_libs: [
-        "SurfaceFlingerProperties",
+        "libSurfaceFlingerProperties",
     ],
 
     shared_libs: [
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 34ecd25..2de878d 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -807,7 +807,6 @@
 
             if (wakeTimeNanos > deadlineNanos) {
                 // If we time out, just return the framesWritten so far.
-                // TODO remove after we fix the deadline bug
                 ALOGW("processData(): entered at %lld nanos, currently %lld",
                       (long long) entryTimeNanos, (long long) currentTimeNanos);
                 ALOGW("processData(): TIMEOUT after %lld nanos",
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 8dd5538..e36928d 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -410,7 +410,7 @@
      * This should only be called for client streams and not for streams
      * that run in the service.
      */
-    void registerPlayerBase() {
+    virtual void registerPlayerBase() {
         if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
             mPlayerBase->registerWithAudioManager(this);
         }
@@ -664,6 +664,8 @@
 
     std::mutex                 mStreamLock;
 
+    const android::sp<MyPlayerBase>   mPlayerBase;
+
 private:
 
     aaudio_result_t safeStop_l() REQUIRES(mStreamLock);
@@ -679,8 +681,6 @@
         close_l();
     }
 
-    const android::sp<MyPlayerBase>   mPlayerBase;
-
     std::atomic<aaudio_stream_state_t>          mState{AAUDIO_STREAM_STATE_UNINITIALIZED};
 
     // These do not change after open().
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 09caa5c..fb3fcc1 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -406,7 +406,6 @@
             if (err != OK) {
                 return AAudioConvert_androidToAAudioResult(err);
             } else if (position == 0) {
-                // TODO Advance frames read to match written.
                 setState(AAUDIO_STREAM_STATE_FLUSHED);
             }
         }
@@ -552,6 +551,16 @@
     return status;
 }
 
+void AudioStreamTrack::registerPlayerBase() {
+    AudioStream::registerPlayerBase();
+
+    if (mAudioTrack == nullptr) {
+        ALOGW("%s: cannot set piid, AudioTrack is null", __func__);
+        return;
+    }
+    mAudioTrack->setPlayerIId(mPlayerBase->getPlayerIId());
+}
+
 #if AAUDIO_USE_VOLUME_SHAPER
 
 using namespace android::media::VolumeShaper;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index 1f877b5..05609c4 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -87,6 +87,8 @@
 
     android::status_t doSetVolume() override;
 
+    void registerPlayerBase() override;
+
 #if AAUDIO_USE_VOLUME_SHAPER
     virtual android::binder::Status applyVolumeShaper(
             const android::media::VolumeShaper::Configuration& configuration,
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 965c40f..66bd1c1 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1015,7 +1015,7 @@
                                        audio_session_t session,
                                        audio_stream_type_t* stream,
                                        const AttributionSourceState& attributionSource,
-                                       const audio_config_t* config,
+                                       audio_config_t* config,
                                        audio_output_flags_t flags,
                                        audio_port_handle_t* selectedDeviceId,
                                        audio_port_handle_t* portId,
@@ -1057,9 +1057,18 @@
 
     media::GetOutputForAttrResponse responseAidl;
 
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+    status_t status = statusTFromBinderStatus(
             aps->getOutputForAttr(attrAidl, sessionAidl, attributionSource, configAidl, flagsAidl,
-                                  selectedDeviceIdAidl, &responseAidl)));
+                                  selectedDeviceIdAidl, &responseAidl));
+    if (status != NO_ERROR) {
+        config->format = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioFormatDescription_audio_format_t(responseAidl.configBase.format));
+        config->channel_mask = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+                    responseAidl.configBase.channelMask, false /*isInput*/));
+        config->sample_rate = responseAidl.configBase.sampleRate;
+        return status;
+    }
 
     *output = VALUE_OR_RETURN_STATUS(
             aidl2legacy_int32_t_audio_io_handle_t(responseAidl.output));
@@ -1114,7 +1123,7 @@
                                       audio_unique_id_t riid,
                                       audio_session_t session,
                                       const AttributionSourceState &attributionSource,
-                                      const audio_config_base_t* config,
+                                      audio_config_base_t* config,
                                       audio_input_flags_t flags,
                                       audio_port_handle_t* selectedDeviceId,
                                       audio_port_handle_t* portId) {
@@ -1151,9 +1160,14 @@
 
     media::GetInputForAttrResponse response;
 
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+    status_t status = statusTFromBinderStatus(
             aps->getInputForAttr(attrAidl, inputAidl, riidAidl, sessionAidl, attributionSource,
-                configAidl, flagsAidl, selectedDeviceIdAidl, &response)));
+                configAidl, flagsAidl, selectedDeviceIdAidl, &response));
+    if (status != NO_ERROR) {
+        *config = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_AudioConfigBase_audio_config_base_t(response.config, true /*isInput*/));
+        return status;
+    }
 
     *input = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_io_handle_t(response.input));
     *selectedDeviceId = VALUE_OR_RETURN_STATUS(
diff --git a/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
index 9696124..347bf79 100644
--- a/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetInputForAttrResponse.aidl
@@ -16,6 +16,8 @@
 
 package android.media;
 
+import android.media.audio.common.AudioConfigBase;
+
 /**
  * {@hide}
  */
@@ -26,4 +28,6 @@
     int selectedDeviceId;
     /** Interpreted as audio_port_handle_t. */
     int portId;
+    /** The suggested config if fails to get an input. **/
+    AudioConfigBase config;
 }
diff --git a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
index f1848b6..5b25d79 100644
--- a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.media.audio.common.AudioConfigBase;
 import android.media.audio.common.AudioStreamType;
 
 /**
@@ -33,4 +34,6 @@
     int[] secondaryOutputs;
     /** True if the track is connected to a spatializer mixer and actually spatialized */
     boolean isSpatialized;
+    /** The suggested audio config if fails to get an output. **/
+    AudioConfigBase configBase;
 }
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 9411f46..1c414ec 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -26,8 +26,11 @@
 #include <android/media/AudioVibratorInfo.h>
 #include <android/media/BnAudioFlingerClient.h>
 #include <android/media/BnAudioPolicyServiceClient.h>
+#include <android/media/EffectDescriptor.h>
 #include <android/media/INativeSpatializerCallback.h>
 #include <android/media/ISpatializer.h>
+#include <android/media/RecordClientInfo.h>
+#include <android/media/audio/common/AudioConfigBase.h>
 #include <android/media/audio/common/AudioMMapPolicyInfo.h>
 #include <android/media/audio/common/AudioMMapPolicyType.h>
 #include <android/media/audio/common/AudioPort.h>
@@ -279,12 +282,31 @@
     static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
     static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
 
+    /**
+     * Get output stream for given parameters.
+     *
+     * @param[in] attr the requested audio attributes
+     * @param[in|out] output the io handle of the output for the playback. It is specified when
+     *                       starting mmap thread.
+     * @param[in] session the session id for the client
+     * @param[in|out] stream the stream type used for the playback
+     * @param[in] attributionSource a source to which access to permission protected data
+     * @param[in|out] config the requested configuration client, the suggested configuration will
+     *                       be returned if no proper output is found for requested configuration
+     * @param[in] flags the requested output flag from client
+     * @param[in|out] selectedDeviceId the requested device id for playback, the actual device id
+     *                                 for playback will be returned
+     * @param[out] portId the generated port id to identify the client
+     * @param[out] secondaryOutputs collection of io handle for secondary outputs
+     * @param[out] isSpatialized true if the playback will be spatialized
+     * @return if the call is successful or not
+     */
     static status_t getOutputForAttr(audio_attributes_t *attr,
                                      audio_io_handle_t *output,
                                      audio_session_t session,
                                      audio_stream_type_t *stream,
                                      const AttributionSourceState& attributionSource,
-                                     const audio_config_t *config,
+                                     audio_config_t *config,
                                      audio_output_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId,
                                      audio_port_handle_t *portId,
@@ -294,14 +316,31 @@
     static status_t stopOutput(audio_port_handle_t portId);
     static void releaseOutput(audio_port_handle_t portId);
 
-    // Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
-    // or release it with releaseInput().
+    /**
+     * Get input stream for given parameters.
+     * Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
+     * or release it with releaseInput().
+     *
+     * @param[in] attr the requested audio attributes
+     * @param[in|out] input the io handle of the input for the capture. It is specified when
+     *                      starting mmap thread.
+     * @param[in] riid an unique id to identify the record client
+     * @param[in] session the session id for the client
+     * @param[in] attributionSource a source to which access to permission protected data
+     * @param[in|out] config the requested configuration client, the suggested configuration will
+     *                       be returned if no proper input is found for requested configuration
+     * @param[in] flags the requested input flag from client
+     * @param[in|out] selectedDeviceId the requested device id for playback, the actual device id
+     *                                 for playback will be returned
+     * @param[out] portId the generated port id to identify the client
+     * @return if the call is successful or not
+     */
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
                                     audio_unique_id_t riid,
                                     audio_session_t session,
-                                     const AttributionSourceState& attributionSource,
-                                    const audio_config_base_t *config,
+                                    const AttributionSourceState& attributionSource,
+                                    audio_config_base_t *config,
                                     audio_input_flags_t flags,
                                     audio_port_handle_t *selectedDeviceId,
                                     audio_port_handle_t *portId);
diff --git a/media/libheadtracking/Android.bp b/media/libheadtracking/Android.bp
index 9d63f9b..7e2c762 100644
--- a/media/libheadtracking/Android.bp
+++ b/media/libheadtracking/Android.bp
@@ -22,6 +22,10 @@
       "StillnessDetector.cpp",
       "Twist.cpp",
     ],
+    shared_libs: [
+        "libaudioutils",
+        "libbase",
+    ],
     export_include_dirs: [
         "include",
     ],
@@ -39,6 +43,7 @@
       "SensorPoseProvider.cpp",
     ],
     shared_libs: [
+        "libbase",
         "libheadtracking",
         "liblog",
         "libsensor",
diff --git a/media/libheadtracking/HeadTrackingProcessor.cpp b/media/libheadtracking/HeadTrackingProcessor.cpp
index 71fae8a..fb44567 100644
--- a/media/libheadtracking/HeadTrackingProcessor.cpp
+++ b/media/libheadtracking/HeadTrackingProcessor.cpp
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <inttypes.h>
 
+#include <android-base/stringprintf.h>
+#include <audio_utils/SimpleLog.h>
 #include "media/HeadTrackingProcessor.h"
 
 #include "ModeSelector.h"
@@ -26,6 +29,7 @@
 namespace media {
 namespace {
 
+using android::base::StringAppendF;
 using Eigen::Quaternionf;
 using Eigen::Vector3f;
 
@@ -136,10 +140,12 @@
         if (recenterHead) {
             mHeadPoseBias.recenter();
             mHeadStillnessDetector.reset();
+            mLocalLog.log("recenter Head");
         }
         if (recenterScreen) {
             mScreenPoseBias.recenter();
             mScreenStillnessDetector.reset();
+            mLocalLog.log("recenter Screen");
         }
 
         // If a sensor being recentered is included in the current mode, apply rate limiting to
@@ -152,6 +158,35 @@
         }
     }
 
+    std::string toString_l(unsigned level) const override {
+        std::string prefixSpace(level, ' ');
+        std::string ss = prefixSpace + "HeadTrackingProcessor:\n";
+        StringAppendF(&ss, "%smaxTranslationalVelocity: %f\n", prefixSpace.c_str(),
+                      mOptions.maxTranslationalVelocity);
+        StringAppendF(&ss, "%smaxRotationalVelocity: %f\n", prefixSpace.c_str(),
+                      mOptions.maxRotationalVelocity);
+        StringAppendF(&ss, "%sfreshnessTimeout: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.freshnessTimeout);
+        StringAppendF(&ss, "%spredictionDuration: %f\n", prefixSpace.c_str(),
+                      mOptions.predictionDuration);
+        StringAppendF(&ss, "%sautoRecenterWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterWindowDuration);
+        StringAppendF(&ss, "%sautoRecenterTranslationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterTranslationalThreshold);
+        StringAppendF(&ss, "%sautoRecenterRotationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterRotationalThreshold);
+        StringAppendF(&ss, "%sscreenStillnessWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessWindowDuration);
+        StringAppendF(&ss, "%sscreenStillnessTranslationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessTranslationalThreshold);
+        StringAppendF(&ss, "%sscreenStillnessRotationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessRotationalThreshold);
+        ss.append(prefixSpace + "ReCenterHistory:\n");
+        ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
+        // TODO: 233092747 add string from PoseRateLimiter/PoseRateLimiter etc...
+        return ss;
+    }
+
   private:
     const Options mOptions;
     float mPhysicalToLogicalAngle = 0;
@@ -168,6 +203,8 @@
     ScreenHeadFusion mScreenHeadFusion;
     ModeSelector mModeSelector;
     PoseRateLimiter mRateLimiter;
+    static constexpr std::size_t mMaxLocalLogLine = 10;
+    SimpleLog mLocalLog{mMaxLocalLogLine};
 };
 
 }  // namespace
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index e5e1521..6c0a96d 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -24,6 +24,7 @@
 #include <map>
 #include <thread>
 
+#include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 #include <log/log_main.h>
 #include <sensor/SensorEventQueue.h>
@@ -36,6 +37,8 @@
 namespace media {
 namespace {
 
+using android::base::StringAppendF;
+
 // Identifier to use for our event queue on the loop.
 // The number 19 is arbitrary, only useful if using multiple objects on the same looper.
 constexpr int kIdent = 19;
@@ -153,6 +156,38 @@
         mEnabledSensorsExtra.erase(handle);
     }
 
+    std::string toString(unsigned level) override {
+        std::string prefixSpace(level, ' ');
+        std::string ss = prefixSpace + "SensorPoseProvider:\n";
+        bool needUnlock = false;
+
+        prefixSpace += " ";
+        auto now = std::chrono::steady_clock::now();
+        if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
+            ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
+        } else {
+            needUnlock = true;
+        }
+
+        // Enabled sensor information
+        StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
+                      mEnabledSensorsExtra.size());
+        for (auto sensor : mEnabledSensorsExtra) {
+            StringAppendF(&ss, "%s[Handle: 0x%08x, Format %s", prefixSpace.c_str(), sensor.first,
+                          toString(sensor.second.format).c_str());
+            if (sensor.second.discontinuityCount.has_value()) {
+                StringAppendF(&ss, ", DiscontinuityCount: %d",
+                              sensor.second.discontinuityCount.value());
+            }
+            ss += "]\n";
+        }
+
+        if (needUnlock) {
+            mMutex.unlock();
+        }
+        return ss;
+    }
+
   private:
     enum DataFormat {
         kUnknown,
@@ -174,7 +209,7 @@
     sp<Looper> mLooper;
     Listener* const mListener;
     SensorManager* const mSensorManager;
-    std::mutex mMutex;
+    std::timed_mutex mMutex;
     std::map<int32_t, SensorEnableGuard> mEnabledSensors;
     std::map<int32_t, SensorExtra> mEnabledSensorsExtra GUARDED_BY(mMutex);
     sp<SensorEventQueue> mQueue;
@@ -193,7 +228,6 @@
           mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))) {
         mThread = std::thread([this] { threadFunc(); });
     }
-
     void initFinished(bool success) { mInitPromise.set_value(success); }
 
     bool waitInitFinished() { return mInitPromise.get_future().get(); }
@@ -346,6 +380,19 @@
                 LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
         }
     }
+
+    const std::string toString(DataFormat format) {
+        switch (format) {
+            case DataFormat::kUnknown:
+                return "kUnknown";
+            case DataFormat::kQuaternion:
+                return "kQuaternion";
+            case DataFormat::kRotationVectorsAndDiscontinuityCount:
+                return "kRotationVectorsAndDiscontinuityCount";
+            default:
+                return "NotImplemented";
+        }
+    }
 };
 
 }  // namespace
diff --git a/media/libheadtracking/include/media/HeadTrackingProcessor.h b/media/libheadtracking/include/media/HeadTrackingProcessor.h
index 1744be3..8ef8ab0 100644
--- a/media/libheadtracking/include/media/HeadTrackingProcessor.h
+++ b/media/libheadtracking/include/media/HeadTrackingProcessor.h
@@ -96,8 +96,12 @@
      * This causes the current poses for both the head and/or screen to be considered "center".
      */
     virtual void recenter(bool recenterHead = true, bool recenterScreen = true) = 0;
-};
 
+    /**
+     * Dump HeadTrackingProcessor parameters under caller lock.
+     */
+    virtual std::string toString_l(unsigned level) const = 0;
+};
 /**
  * Creates an instance featuring a default implementation of the HeadTrackingProcessor interface.
  */
diff --git a/media/libheadtracking/include/media/SensorPoseProvider.h b/media/libheadtracking/include/media/SensorPoseProvider.h
index 0f42074..4609e0c 100644
--- a/media/libheadtracking/include/media/SensorPoseProvider.h
+++ b/media/libheadtracking/include/media/SensorPoseProvider.h
@@ -28,6 +28,9 @@
 namespace android {
 namespace media {
 
+// Timeout for Spatializer dumpsys trylock, don't block for more than 3 seconds.
+constexpr auto kSpatializerDumpSysTimeOutInSecond = std::chrono::seconds(3);
+
 /**
  * A utility providing streaming of pose data from motion sensors provided by the Sensor Framework.
  *
@@ -100,6 +103,11 @@
      * discover properties of the sensor.
      */
     virtual std::optional<const Sensor> getSensorByHandle(int32_t handle) = 0;
+
+    /**
+     * Dump SensorPoseProvider parameters and history data.
+     */
+    virtual std::string toString(unsigned level) = 0;
 };
 
 }  // namespace media
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index 1c30510..49abdf0 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -57,6 +57,10 @@
 // The Audio Spatializer key appends the spatializerId (currently 0)
 #define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER AMEDIAMETRICS_KEY_PREFIX_AUDIO "spatializer."
 
+// The Audio Spatializer device key appends the device type.
+#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER_DEVICE \
+        AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "device."
+
 // The AudioStream key appends the "streamId" to the prefix.
 #define AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM  AMEDIAMETRICS_KEY_PREFIX_AUDIO "stream."
 
@@ -132,6 +136,7 @@
 
 #define AMEDIAMETRICS_PROP_DIRECTION      "direction"      // string AAudio input or output
 #define AMEDIAMETRICS_PROP_DURATIONNS     "durationNs"     // int64 duration time span
+#define AMEDIAMETRICS_PROP_ENABLED        "enabled"        // string true/false.
 #define AMEDIAMETRICS_PROP_ENCODING       "encoding"       // string value of format
 
 #define AMEDIAMETRICS_PROP_EVENT          "event#"         // string value (often func name)
@@ -141,6 +146,8 @@
 #define AMEDIAMETRICS_PROP_FLAGS          "flags"
 
 #define AMEDIAMETRICS_PROP_FRAMECOUNT     "frameCount"     // int32
+#define AMEDIAMETRICS_PROP_HASHEADTRACKER  "hasHeadTracker" // string true/false
+#define AMEDIAMETRICS_PROP_HEADTRACKERENABLED "headTrackerEnabled" // string true/false
 #define AMEDIAMETRICS_PROP_HEADTRACKINGMODES "headTrackingModes" // string |, like modes.
 #define AMEDIAMETRICS_PROP_INPUTDEVICES   "inputDevices"   // string value
 #define AMEDIAMETRICS_PROP_INTERNALTRACKID "internalTrackId" // int32
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index ea1fdf4..a0bc8ca 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1966,6 +1966,10 @@
             format->setString("mime", MEDIA_MIMETYPE_VIDEO_HEVC);
             break;
 
+        case VIDEO_ENCODER_DOLBY_VISION:
+            format->setString("mime", MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
+            break;
+
         default:
             CHECK(!"Should not be here, unsupported video encoding.");
             break;
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index fb4f9a0..d667685 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -73,7 +73,7 @@
         <MediaCodec name="c2.android.raw.decoder" type="audio/raw">
             <Alias name="OMX.google.raw.decoder" />
             <Limit name="channel-count" max="8" />
-            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="sample-rate" ranges="8000-192000" />
             <Limit name="bitrate" range="1-10000000" />
         </MediaCodec>
         <MediaCodec name="c2.android.flac.decoder" type="audio/flac">
diff --git a/media/libstagefright/omx/OMXStore.cpp b/media/libstagefright/omx/OMXStore.cpp
index 4827d9e..0906433 100644
--- a/media/libstagefright/omx/OMXStore.cpp
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -140,7 +140,8 @@
 
         Vector<String8> roles;
         OMX_ERRORTYPE err = plugin->getRolesOfComponent(name, &roles);
-        if (err == OMX_ErrorNone) {
+        static_assert(std::string_view("OMX.google.").size() == 11);
+        if (err == OMX_ErrorNone && strncmp(name, "OMX.google.", 11) == 0) {
             bool skip = false;
             for (String8 role : roles) {
                 if (role.find("video_decoder") != -1 || role.find("video_encoder") != -1) {
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 97e2a22..719d05a 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -31,8 +31,8 @@
     ],
 }
 
-cc_library_shared {
-    name: "libmtp",
+cc_defaults {
+    name: "libmtp_defaults",
     srcs: [
         "MtpDataPacket.cpp",
         "MtpDebug.cpp",
@@ -71,3 +71,14 @@
     ],
     header_libs: ["libcutils_headers"],
 }
+
+cc_library_shared {
+    name: "libmtp",
+    defaults: ["libmtp_defaults"],
+}
+
+cc_library_shared {
+    name: "libmtp_fuzz",
+    defaults: ["libmtp_defaults"],
+    cflags: ["-DMTP_FUZZER"],
+}
diff --git a/media/mtp/MtpDescriptors.h b/media/mtp/MtpDescriptors.h
index d600a24..9b98a71 100644
--- a/media/mtp/MtpDescriptors.h
+++ b/media/mtp/MtpDescriptors.h
@@ -23,6 +23,17 @@
 
 namespace android {
 
+#ifdef MTP_FUZZER
+constexpr char FFS_MTP_EP0[] = "/data/local/tmp/usb-ffs/mtp/ep0";
+constexpr char FFS_MTP_EP_IN[] = "/data/local/tmp/usb-ffs/mtp/ep1";
+constexpr char FFS_MTP_EP_OUT[] = "/data/local/tmp/usb-ffs/mtp/ep2";
+constexpr char FFS_MTP_EP_INTR[] = "/data/local/tmp/usb-ffs/mtp/ep3";
+
+constexpr char FFS_PTP_EP0[] = "/data/local/tmp/usb-ffs/ptp/ep0";
+constexpr char FFS_PTP_EP_IN[] = "/data/local/tmp/usb-ffs/ptp/ep1";
+constexpr char FFS_PTP_EP_OUT[] = "/data/local/tmp/usb-ffs/ptp/ep2";
+constexpr char FFS_PTP_EP_INTR[] = "/data/local/tmp/usb-ffs/ptp/ep3";
+#else
 constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
 constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
 constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
@@ -32,6 +43,7 @@
 constexpr char FFS_PTP_EP_IN[] = "/dev/usb-ffs/ptp/ep1";
 constexpr char FFS_PTP_EP_OUT[] = "/dev/usb-ffs/ptp/ep2";
 constexpr char FFS_PTP_EP_INTR[] = "/dev/usb-ffs/ptp/ep3";
+#endif
 
 constexpr int MAX_PACKET_SIZE_FS = 64;
 constexpr int MAX_PACKET_SIZE_HS = 512;
diff --git a/media/mtp/tests/MtpFuzzer/Android.bp b/media/mtp/tests/MtpFuzzer/Android.bp
index 289b3ba..9e41680 100644
--- a/media/mtp/tests/MtpFuzzer/Android.bp
+++ b/media/mtp/tests/MtpFuzzer/Android.bp
@@ -57,3 +57,95 @@
     dictionary: "mtp_fuzzer.dict",
     corpus: ["corpus/*"],
 }
+
+cc_defaults {
+    name: "mtp_property_fuzzer_defaults",
+    srcs: ["mtp_property_fuzzer.cpp"],
+    shared_libs: [
+        "libmtp",
+        "libasyncio",
+        "libusbhost",
+    ],
+    defaults: ["mtp_fuzzer_defaults"],
+}
+
+cc_fuzz {
+     name: "mtp_device_property_fuzzer",
+     defaults: ["mtp_property_fuzzer_defaults"],
+     cflags: [
+         "-DMTP_DEVICE",
+     ],
+}
+
+cc_fuzz {
+     name: "mtp_host_property_fuzzer",
+     defaults: ["mtp_property_fuzzer_defaults"],
+     cflags: [
+         "-DMTP_HOST",
+     ],
+}
+
+cc_fuzz {
+    name: "mtp_handle_fuzzer",
+    srcs: ["mtp_handle_fuzzer.cpp"],
+    shared_libs: ["libmtp_fuzz"],
+    defaults: ["mtp_fuzzer_defaults"],
+    cflags: ["-DMTP_FUZZER"],
+}
+
+cc_defaults  {
+     name: "mtp_packet_defaults",
+     shared_libs: [
+        "libmtp",
+        "libasyncio",
+        "libusbhost",
+     ],
+     defaults: ["mtp_fuzzer_defaults"],
+     cflags: [
+         "-DMTP_HOST",
+         "-DMTP_DEVICE",
+     ],
+}
+
+cc_fuzz {
+     name: "mtp_packet_fuzzer",
+     srcs: ["mtp_packet_fuzzer.cpp"],
+     defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+     name: "mtp_device_fuzzer",
+     srcs: ["mtp_device_fuzzer.cpp"],
+     shared_libs: [
+        "libmtp",
+        "libusbhost",
+     ],
+     defaults: ["mtp_fuzzer_defaults"],
+     cflags: [
+         "-DMTP_DEVICE",
+     ],
+}
+
+cc_fuzz {
+     name: "mtp_request_packet_fuzzer",
+     srcs: ["mtp_request_packet_fuzzer.cpp"],
+     defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+     name: "mtp_event_packet_fuzzer",
+     srcs: ["mtp_event_packet_fuzzer.cpp"],
+     defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+     name: "mtp_response_packet_fuzzer",
+     srcs: ["mtp_response_packet_fuzzer.cpp"],
+     defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+     name: "mtp_data_packet_fuzzer",
+     srcs: ["mtp_data_packet_fuzzer.cpp"],
+     defaults: ["mtp_packet_defaults"],
+}
diff --git a/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
new file mode 100644
index 0000000..87fea9f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 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 <MtpStringBuffer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usbdevice_fs.h>
+#include <sys/mman.h>
+#include <usbhost/usbhost.h>
+#include <MtpTypes.h>
+
+using namespace android;
+constexpr UrbPacketDivisionMode kUrbPacketDivisionModes[] = {FIRST_PACKET_ONLY_HEADER,
+                                                             FIRST_PACKET_HAS_PAYLOAD};
+
+constexpr size_t kMinSize = 0;
+constexpr size_t kMaxSize = 1000;
+constexpr size_t kMaxLength = 1000;
+
+class MtpPacketFuzzerUtils {
+  protected:
+    struct usb_request mUsbRequest;
+    struct usbdevfs_urb* mUsbDevFsUrb;
+    std::string mPath;
+
+    void fillFd(int32_t& fd, FuzzedDataProvider* fdp) {
+        if (fdp->ConsumeBool()) {
+            std::string text = fdp->ConsumeRandomLengthString(kMaxLength);
+            write(fd, text.c_str(), text.length());
+        }
+    };
+
+    void fillFilePath(FuzzedDataProvider* fdp) {
+       mPath= fdp->ConsumeRandomLengthString(kMaxLength);
+    };
+
+    void fillUsbDevFsUrb(FuzzedDataProvider* fdp) {
+        mUsbDevFsUrb->type = fdp->ConsumeIntegral<unsigned char>();
+        mUsbDevFsUrb->endpoint = fdp->ConsumeIntegral<unsigned char>();
+        mUsbDevFsUrb->flags = fdp->ConsumeIntegral<uint32_t>();
+        std::vector<uint8_t> buffer =
+                fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+        mUsbDevFsUrb->buffer = static_cast<void*>(buffer.data());
+        mUsbDevFsUrb->buffer_length = buffer.size();
+        mUsbDevFsUrb->actual_length = fdp->ConsumeIntegral<uint32_t>();
+        mUsbDevFsUrb->start_frame = fdp->ConsumeIntegral<uint32_t>();
+        mUsbDevFsUrb->number_of_packets = fdp->ConsumeIntegral<uint32_t>();
+        mUsbDevFsUrb->stream_id = fdp->ConsumeIntegral<uint32_t>();
+        mUsbDevFsUrb->error_count = fdp->ConsumeIntegral<size_t>();
+        mUsbDevFsUrb->signr = fdp->ConsumeIntegral<uint32_t>();
+        std::vector<uint8_t> userBuffer = (fdp->ConsumeBytes<uint8_t>(
+                fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+        mUsbDevFsUrb->usercontext = static_cast<void*>(userBuffer.data());
+        mUsbDevFsUrb->iso_frame_desc[0].length = fdp->ConsumeIntegral<uint32_t>();
+        mUsbDevFsUrb->iso_frame_desc[0].actual_length = fdp->ConsumeIntegral<uint32_t>();
+    };
+
+    void fillUsbRequest(int32_t& fd, FuzzedDataProvider* fdp) {
+        fillUsbDevFsUrb(fdp);
+        fillFd(fd, fdp);
+        std::vector<uint8_t> buffer =
+                fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+        mUsbRequest.buffer = static_cast<void*>(buffer.data());
+        mUsbRequest.buffer_length = buffer.size();
+        mUsbRequest.actual_length = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+        mUsbRequest.max_packet_size = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+        mUsbRequest.private_data = static_cast<void*>(mUsbDevFsUrb);
+        mUsbRequest.endpoint = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+        std::vector<uint8_t> clientBuffer = (fdp->ConsumeBytes<uint8_t>(
+                fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+        mUsbRequest.client_data = static_cast<void*>(clientBuffer.data());
+    };
+
+    template <typename Object>
+    void writeHandle(Object obj, FuzzedDataProvider* fdp) {
+        MtpDevHandle handle;
+        std::vector<uint8_t> initData =
+                fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+        handle.write(initData.data(), initData.size());
+        obj->write(&handle);
+    };
+};
diff --git a/media/mtp/tests/MtpFuzzer/README.md b/media/mtp/tests/MtpFuzzer/README.md
index 7c6ff7a..7efaf67 100644
--- a/media/mtp/tests/MtpFuzzer/README.md
+++ b/media/mtp/tests/MtpFuzzer/README.md
@@ -2,6 +2,15 @@
 
 ## Table of contents
 + [mtp_fuzzer](#MtpServer)
++ [mtp_host_property_fuzzer](#MtpHostProperty)
++ [mtp_device_property_fuzzer](#MtpDeviceProperty)
++ [mtp_handle_fuzzer](#MtpHandle)
++ [mtp_packet_fuzzer](#MtpPacket)
+ + [mtp_device_fuzzer](#MtpDevice)
++ [mtp_request_packet_fuzzer](#MtpRequestPacket)
++ [mtp_event_packet_fuzzer](#MtpEventPacket)
++ [mtp_response_packet_fuzzer](#MtpResponsePacket)
++ [mtp_data_packet_fuzzer](#MtpDataPacket)
 
 # <a name="MtpServer"></a> Fuzzer for MtpServer
 
@@ -22,3 +31,180 @@
   $ adb sync data
   $ adb shell /data/fuzz/arm64/mtp_fuzzer/mtp_fuzzer corpus/ -dict=mtp_fuzzer.dict
 ```
+
+# <a name="MtpHostProperty"></a> Fuzzer for MtpHostProperty
+
+MtpHostProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleTypes")
+2. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_host_property_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_host_property_fuzzer/mtp_host_property_fuzzer
+```
+
+# <a name="MtpDeviceProperty"></a> Fuzzer for MtpDeviceProperty
+
+MtpDeviceProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleType")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_device_property_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_device_property_fuzzer/mtp_device_property_fuzzer
+```
+
+# <a name="MtpHandle"></a>Fuzzer for MtpHandle
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_handle_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_handle_fuzzer/mtp_handle_fuzzer
+```
+
+# <a name="MtpPacket"></a> Fuzzer for MtpPacket
+
+MtpPacket supports the following parameters:
+1. bufferSize (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`bufferSize`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_packet_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_packet_fuzzer/mtp_packet_fuzzer
+```
+
+# <a name="MtpDevice"></a> Fuzzer for MtpDevice
+
+MtpDevice supports the following parameters:
+1. Device Name (parameter name: "deviceName")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`deviceName`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_device_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_device_fuzzer/mtp_device_fuzzer
+```
+
+# <a name="MtpRequestPacket"></a> Fuzzer for MtpRequestPacket
+
+MtpRequestPacket supports the following parameters:
+1. Data (parameter name: "data")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`data`| Vector of positive Integer |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_request_packet_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_request_packet_fuzzer/mtp_request_packet_fuzzer
+```
+
+# <a name="MtpEventPacket"></a> Fuzzer for MtpEventPacket
+
+MtpEventPacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_event_packet_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_event_packet_fuzzer/mtp_event_packet_fuzzer
+```
+
+# <a name="MtpResponsePacket"></a> Fuzzer for MtpResponsePacket
+
+MtpResponsePacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_response_packet_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_response_packet_fuzzer/mtp_response_packet_fuzzer
+```
+
+# <a name="MtpDataPacket"></a> Fuzzer for MtpDataPacket
+
+MtpDataPacket supports the following parameters:
+1. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+2. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) mtp_data_packet_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mtp_data_packet_fuzzer/mtp_data_packet_fuzzer
+```
diff --git a/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
new file mode 100644
index 0000000..f5faf77
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2022 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 <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+class MtpDataPacketFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpDataPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+                                                   sizeof(struct usbdevfs_iso_packet_desc));
+    };
+    ~MtpDataPacketFuzzer() { free(mUsbDevFsUrb); };
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void MtpDataPacketFuzzer::process() {
+    MtpDataPacket mtpDataPacket;
+    while (mFdp.remaining_bytes() > 0) {
+        auto mtpDataAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() { mtpDataPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+                [&]() { mtpDataPacket.reset(); },
+                [&]() {
+                    mtpDataPacket.setOperationCode(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    mtpDataPacket.setTransactionID(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    Int8List* result = mtpDataPacket.getAInt8();
+                    delete result;
+                },
+                [&]() {
+                    Int16List* result = mtpDataPacket.getAInt16();
+                    delete result;
+                },
+                [&]() {
+                    Int32List* result = mtpDataPacket.getAInt32();
+                    delete result;
+                },
+                [&]() {
+                    Int64List* result = mtpDataPacket.getAInt64();
+                    delete result;
+                },
+                [&]() {
+                    UInt8List* result = mtpDataPacket.getAUInt8();
+                    delete result;
+                },
+                [&]() {
+                    UInt16List* result = mtpDataPacket.getAUInt16();
+                    delete result;
+                },
+                [&]() {
+                    UInt32List* result = mtpDataPacket.getAUInt32();
+                    delete result;
+                },
+                [&]() {
+                    UInt64List* result = mtpDataPacket.getAUInt64();
+                    delete result;
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<uint8_t> initData =
+                                mFdp.ConsumeBytes<uint8_t>(mFdp.ConsumeIntegral<uint8_t>());
+                        mtpDataPacket.putAUInt8(initData.data(), initData.size());
+                    } else {
+                        mtpDataPacket.putAUInt8(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        uint16_t arr[size];
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr[idx] = mFdp.ConsumeIntegral<uint16_t>();
+                        }
+                        mtpDataPacket.putAUInt16(arr, size);
+                    } else {
+                        mtpDataPacket.putAUInt16(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        uint32_t arr[size];
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+                        }
+                        mtpDataPacket.putAUInt32(arr, size);
+                    } else {
+                        mtpDataPacket.putAUInt32(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        uint64_t arr[size];
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr[idx] = mFdp.ConsumeIntegral<uint64_t>();
+                        }
+                        mtpDataPacket.putAUInt64(arr, size);
+                    } else {
+                        mtpDataPacket.putAUInt64(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        int64_t arr[size];
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr[idx] = mFdp.ConsumeIntegral<int64_t>();
+                        }
+                        mtpDataPacket.putAInt64(arr, size);
+                    } else {
+                        mtpDataPacket.putAInt64(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<uint16_t> arr;
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr.push_back(mFdp.ConsumeIntegral<uint16_t>());
+                        }
+                        mtpDataPacket.putAUInt16(&arr);
+                    } else {
+                        mtpDataPacket.putAUInt16(nullptr);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<uint32_t> arr;
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr.push_back(mFdp.ConsumeIntegral<uint32_t>());
+                        }
+                        mtpDataPacket.putAUInt32(&arr);
+                    } else {
+                        mtpDataPacket.putAUInt32(nullptr);
+                    }
+                },
+
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+                        int32_t arr[size];
+                        for (size_t idx = 0; idx < size; ++idx) {
+                            arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+                        }
+                        mtpDataPacket.putAInt32(arr, size);
+                    } else {
+                        mtpDataPacket.putAInt32(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        mtpDataPacket.putString(
+                                (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+                    } else {
+                        mtpDataPacket.putString(static_cast<char*>(nullptr));
+                    }
+                },
+                [&]() {
+                    android::MtpStringBuffer sBuffer(
+                            (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+                    if (mFdp.ConsumeBool()) {
+                        mtpDataPacket.getString(sBuffer);
+                    } else {
+                        mtpDataPacket.putString(sBuffer);
+                    }
+                },
+                [&]() {
+                    MtpDevHandle handle;
+                    handle.start(mFdp.ConsumeBool());
+                    std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+                    char* data = const_cast<char*>(text.c_str());
+                    handle.read(static_cast<void*>(data), text.length());
+                    if (mFdp.ConsumeBool()) {
+                        mtpDataPacket.read(&handle);
+                    } else if (mFdp.ConsumeBool()) {
+                        mtpDataPacket.write(&handle);
+                    } else {
+                        std::string textData = mFdp.ConsumeRandomLengthString(kMaxLength);
+                        char* Data = const_cast<char*>(textData.c_str());
+                        mtpDataPacket.writeData(&handle, static_cast<void*>(Data),
+                                                textData.length());
+                    }
+                    handle.close();
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+                        android::String16 s(str.c_str());
+                        char16_t* data = const_cast<char16_t*>(s.string());
+                        mtpDataPacket.putString(reinterpret_cast<uint16_t*>(data));
+                    } else {
+                        mtpDataPacket.putString(static_cast<uint16_t*>(nullptr));
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+                                mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+                        mtpDataPacket.putAInt8(data.data(), data.size());
+                    } else {
+                        mtpDataPacket.putAInt8(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+                                mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+                        mtpDataPacket.putAUInt8(data.data(), data.size());
+                    } else {
+                        mtpDataPacket.putAUInt8(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+                            mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+                    mtpDataPacket.readData(&mUsbRequest, data.data(), data.size());
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.write(
+                            &mUsbRequest,
+                            mFdp.PickValueInArray<UrbPacketDivisionMode>(kUrbPacketDivisionModes),
+                            fd, mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.read(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.write(&mUsbRequest, mFdp.PickValueInArray<UrbPacketDivisionMode>(
+                                                             kUrbPacketDivisionModes));
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.readDataHeader(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.readDataAsync(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpDataPacket.readDataWait(mUsbRequest.dev);
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    if (mFdp.ConsumeBool()) {
+                        std::vector<int16_t> data;
+                        for (size_t idx = 0;
+                             idx < mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); ++idx) {
+                            data.push_back(mFdp.ConsumeIntegral<int16_t>());
+                        }
+                        mtpDataPacket.putAInt16(data.data(), data.size());
+                    } else {
+                        mtpDataPacket.putAInt16(nullptr, 0);
+                    }
+                },
+                [&]() {
+                    int32_t arr[4];
+                    for (size_t idx = 0; idx < 4; ++idx) {
+                        arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+                    }
+                    mtpDataPacket.putInt128(arr);
+                },
+                [&]() { mtpDataPacket.putInt64(mFdp.ConsumeIntegral<int64_t>()); },
+                [&]() {
+                    int16_t out;
+                    mtpDataPacket.getInt16(out);
+                },
+                [&]() {
+                    int32_t out;
+                    mtpDataPacket.getInt32(out);
+                },
+                [&]() {
+                    int8_t out;
+                    mtpDataPacket.getInt8(out);
+                },
+                [&]() {
+                    uint32_t arr[4];
+                    for (size_t idx = 0; idx < 4; ++idx) {
+                        arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        mtpDataPacket.putUInt128(arr);
+                    } else {
+                        mtpDataPacket.getUInt128(arr);
+                    }
+                },
+                [&]() { mtpDataPacket.putUInt64(mFdp.ConsumeIntegral<uint64_t>()); },
+                [&]() {
+                    uint64_t out;
+                    mtpDataPacket.getUInt64(out);
+                },
+                [&]() { mtpDataPacket.putInt128(mFdp.ConsumeIntegral<int64_t>()); },
+                [&]() { mtpDataPacket.putUInt128(mFdp.ConsumeIntegral<uint64_t>()); },
+                [&]() {
+                    int32_t length;
+                    void* data = mtpDataPacket.getData(&length);
+                    free(data);
+                },
+        });
+        mtpDataAPI();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpDataPacketFuzzer mtpDataPacketFuzzer(data, size);
+    mtpDataPacketFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
new file mode 100644
index 0000000..c4dd564
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpDevice.h>
+#include <MtpDeviceInfo.h>
+#include <MtpObjectInfo.h>
+#include <MtpProperty.h>
+#include <MtpStorageInfo.h>
+#include <MtpStringBuffer.h>
+#include <android-base/unique_fd.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usb/ch9.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <usbhost/usbhost.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 20;
+constexpr int32_t kMaxBytes = 200;
+constexpr int32_t kMaxDataSize = 20;
+constexpr uint16_t kWMaxPacketSize = 64;
+constexpr uint16_t kEndpointsCount = 3;
+const std::string kInputFile = "/dev/null";
+const std::string kConfigFilePath = "/data/local/tmp/config";
+
+static bool readCallback(void* data, uint32_t offset, uint32_t length, void* clientData) {
+    return true;
+}
+
+struct fdDescriptors {
+    struct usb_interface_descriptor interface;
+    struct usb_endpoint_descriptor ep[kEndpointsCount];
+};
+
+fdDescriptors writeDescriptorsToFd(int32_t fd, FuzzedDataProvider& fdp) {
+    fdDescriptors desc;
+    desc.interface.bLength = sizeof(desc.interface);
+    desc.interface.bDescriptorType = USB_DT_INTERFACE;
+    desc.interface.bInterfaceNumber = fdp.ConsumeIntegral<uint8_t>();
+    desc.interface.bNumEndpoints = kEndpointsCount;
+    desc.interface.bInterfaceClass =
+            fdp.ConsumeBool() ? USB_CLASS_STILL_IMAGE : USB_CLASS_VENDOR_SPEC;
+    desc.interface.bInterfaceSubClass = fdp.ConsumeBool() ? 1 : 0xFF;
+    desc.interface.bInterfaceProtocol = fdp.ConsumeBool() ? 1 : 0;
+    desc.interface.iInterface = fdp.ConsumeIntegral<uint8_t>();
+    for (uint16_t idx = 0; idx < kEndpointsCount; ++idx) {
+        desc.ep[idx].bLength = sizeof(desc.ep[idx]);
+        desc.ep[idx].bDescriptorType = USB_DT_ENDPOINT;
+        desc.ep[idx].bEndpointAddress = idx | (fdp.ConsumeBool() ? USB_DIR_OUT : USB_DIR_IN);
+        desc.ep[idx].bmAttributes =
+                fdp.ConsumeBool() ? USB_ENDPOINT_XFER_BULK : USB_ENDPOINT_XFER_INT;
+        desc.ep[idx].wMaxPacketSize = kWMaxPacketSize;
+    }
+    write(fd, &desc, sizeof(fdDescriptors));
+    return desc;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+    int32_t fd = memfd_create(kConfigFilePath.c_str(), MFD_ALLOW_SEALING);
+    fdDescriptors descriptor = writeDescriptorsToFd(fd, fdp);
+    std::string deviceName = fdp.ConsumeRandomLengthString(kMaxStringLength);
+    usb_device* device = usb_device_new(deviceName.c_str(), fd);
+    MtpDevice mtpDevice(device, fdp.ConsumeIntegral<int32_t>(), &descriptor.ep[0],
+                        &descriptor.ep[1], &descriptor.ep[2]);
+    MtpObjectInfo objectinfo(fdp.ConsumeIntegral<uint32_t>());
+    MtpStorageInfo storageInfo(fdp.ConsumeIntegral<uint32_t>());
+    while (fdp.remaining_bytes()) {
+        auto mtpDeviceFunction = fdp.PickValueInArray<const std::function<void()>>(
+                {[&]() { mtpDevice.getStorageIDs(); },
+                 [&]() {
+                     mtpDevice.getStorageInfo(fdp.ConsumeIntegral<int32_t>() /* storageID */);
+                 },
+                 [&]() {
+                     mtpDevice.getObjectHandles(fdp.ConsumeIntegral<uint32_t>() /* storageID */,
+                                                fdp.ConsumeIntegral<uint16_t>() /* format */,
+                                                fdp.ConsumeIntegral<uint32_t>() /* parent */);
+                 },
+                 [&]() { mtpDevice.initialize(); },
+                 [&]() {
+                     int32_t outLength = 0;
+                     mtpDevice.getThumbnail(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+                                            outLength);
+                 },
+                 [&]() {
+                     MtpObjectInfo mtpObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */);
+                     std::string name = fdp.ConsumeRandomLengthString(kMaxStringLength);
+                     std::string keywords = fdp.ConsumeRandomLengthString(kMaxStringLength);
+                     mtpObjectInfo.mName = strdup(name.c_str());
+                     mtpObjectInfo.mKeywords = strdup(keywords.c_str());
+                     mtpDevice.sendObjectInfo(&mtpObjectInfo);
+                 },
+                 [&]() {
+                     mtpDevice.sendObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+                                          fdp.ConsumeIntegral<uint32_t>() /* size */, fd);
+                 },
+                 [&]() { mtpDevice.deleteObject(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+                 [&]() {
+                     mtpDevice.getObjectPropsSupported(
+                             fdp.ConsumeIntegral<uint16_t>() /* format */);
+                 },
+                 [&]() {
+                     MtpDataType dataType = fdp.ConsumeIntegral<int16_t>();
+                     MtpProperty mtpProperty(fdp.ConsumeIntegral<int16_t>() /* propCode */,
+                                             dataType, fdp.ConsumeBool() /* writeable */,
+                                             fdp.ConsumeIntegral<int32_t>() /* defaultValue */);
+                     if (dataType == MTP_TYPE_STR) {
+                         mtpProperty.setCurrentValue(
+                                 fdp.ConsumeRandomLengthString(kMaxStringLength).c_str());
+                     }
+                     mtpDevice.setDevicePropValueStr(&mtpProperty);
+                 },
+                 [&]() {
+                     mtpDevice.getObjectPropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */,
+                                                 fdp.ConsumeIntegral<uint16_t>() /* format */);
+                 },
+                 [&]() {
+                     MtpProperty property;
+                     mtpDevice.getObjectPropValue(fdp.ConsumeIntegral<uint16_t>() /* handle */,
+                                                  &property);
+                 },
+                 [&]() {
+                     std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+                     mtpDevice.readObject(
+                             fdp.ConsumeIntegral<uint32_t>() /* handle */, readCallback,
+                             fdp.ConsumeIntegral<uint32_t>() /* objectSize */, &clientData);
+                 },
+                 [&]() {
+                     std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+                     uint32_t writtenSize = 0;
+                     mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+                                                 fdp.ConsumeIntegral<uint32_t>() /* offset */,
+                                                 fdp.ConsumeIntegral<uint32_t>() /* size */,
+                                                 &writtenSize, readCallback, &clientData);
+                 },
+                 [&]() {
+                     std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+                     uint32_t writtenSize = 0;
+                     mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+                                                 fdp.ConsumeIntegral<uint64_t>() /* offset */,
+                                                 fdp.ConsumeIntegral<uint32_t>() /* size */,
+                                                 &writtenSize, readCallback, &clientData);
+                 },
+                 [&]() {
+                     if (mtpDevice.submitEventRequest() != -1) {
+                         uint32_t parameters[3];
+                         mtpDevice.reapEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */,
+                                                    &parameters);
+                     }
+                 },
+                 [&]() {
+                     mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /*handle*/);
+                 },
+                 [&]() {
+                     mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */);
+                 },
+                 [&]() { mtpDevice.print(); },
+                 [&]() { mtpDevice.getDeviceName(); },
+                 [&]() { mtpDevice.getObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+                 [&]() { mtpDevice.getParent(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+                 [&]() { mtpDevice.getStorageID(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+                 [&]() { mtpDevice.getDevicePropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */); },
+                 [&]() {
+                     mtpDevice.readObject(
+                             fdp.ConsumeIntegral<uint32_t>() /* handle */,
+                             fdp.ConsumeRandomLengthString(kMaxStringLength).c_str() /* destPath */,
+                             fdp.ConsumeIntegral<int32_t>() /* group */,
+                             fdp.ConsumeIntegral<int32_t>() /* perm */);
+                 },
+                 [&]() {
+                     int32_t filefd = open(kConfigFilePath.c_str(), O_CREAT | O_RDWR);
+                     mtpDevice.readObject(fdp.ConsumeIntegral<uint16_t>() /* handle */, filefd);
+                     close(filefd);
+                 },
+                 [&]() { MtpDevice::open(deviceName.c_str(), fd); },
+                 [&]() {
+                     MtpDataPacket mtpDataPacket;
+                     MtpDevHandle devHandle;
+                     std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+                     mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+                     objectinfo.read(mtpDataPacket);
+                     objectinfo.print();
+                 },
+                 [&]() {
+                     MtpDataPacket mtpDataPacket;
+                     MtpDevHandle devHandle;
+                     std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+                     mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+                     storageInfo.read(mtpDataPacket);
+                     storageInfo.print();
+                 }});
+        mtpDeviceFunction();
+    }
+    close(fd);
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
new file mode 100644
index 0000000..3bd3be2
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpEventPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpEventPacketFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpEventPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+                                                   sizeof(struct usbdevfs_iso_packet_desc));
+    };
+    ~MtpEventPacketFuzzer() { free(mUsbDevFsUrb); };
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void MtpEventPacketFuzzer::process() {
+    MtpEventPacket mtpEventPacket;
+    while (mFdp.remaining_bytes() > 0) {
+        auto mtpEventAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() { mtpEventPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+                [&]() { mtpEventPacket.reset(); },
+                [&]() { writeHandle(&mtpEventPacket, &mFdp); },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpEventPacket.sendRequest(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillFd(fd, &mFdp);
+                    struct usb_device* device = usb_device_new(mPath.c_str(), fd);
+                    mtpEventPacket.readResponse(device);
+                    usb_device_close(device);
+                },
+        });
+        mtpEventAPI();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpEventPacketFuzzer mtpEventPacketFuzzer(data, size);
+    mtpEventPacketFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
new file mode 100644
index 0000000..676345a
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 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 <MtpDescriptors.h>
+#include <MtpFfsCompatHandle.h>
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <mtp.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 64;
+constexpr int32_t kMinAPICase = 0;
+constexpr int32_t kMaxMtpHandleAPI = 5;
+constexpr int32_t kMinBufferSize = 0;
+constexpr uint32_t kMaxMtpFileSize = 0xFFFFFFFF;
+constexpr float kDataSizeFactor = 0.1;
+
+const std::string kTempPath = "/data/local/tmp/";
+const std::string kFuzzerUsbDirPath = kTempPath + "usb-ffs";
+const std::string kFuzzerMtpPath = kFuzzerUsbDirPath + "/mtp";
+const std::string kFuzzerPtpPath = kFuzzerUsbDirPath + "/ptp";
+const std::string kFuzzerTestFile = kTempPath + "FuzzerTestDescriptorFile";
+const std::string kFuzzerMtpInputFile = kTempPath + "FuzzerMtpInputFile";
+const std::string kFuzzerMtpOutputFile = kTempPath + "FuzzerMtpOutputFile";
+
+const std::string kDeviceFilePaths[] = {FFS_MTP_EP0,    FFS_MTP_EP_IN, FFS_MTP_EP_INTR,
+                                        FFS_PTP_EP0,    FFS_PTP_EP_IN, FFS_PTP_EP_INTR,
+                                        FFS_MTP_EP_OUT, FFS_PTP_EP_OUT};
+
+class MtpFfsHandleFuzzer {
+  public:
+    MtpFfsHandleFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mDataSize = kDataSizeFactor * size;
+        createFiles();
+    };
+    void process();
+
+    ~MtpFfsHandleFuzzer() { removeFiles(); };
+
+  private:
+    FuzzedDataProvider mFdp;
+    void invokeWriteDescriptor();
+    void invokeMtpFfsHandle();
+    void createFiles();
+    void removeFiles();
+    void createDeviceFile(const char* file);
+    void writeDeviceFile(const char* file);
+    int32_t writeInputFile(int32_t fd);
+    uint32_t mDataSize = 0;
+};
+
+int32_t MtpFfsHandleFuzzer::writeInputFile(int32_t fd) {
+    uint32_t minFileSize = std::min((uint32_t)MTP_BUFFER_SIZE, mDataSize);
+    uint32_t maxFileSize = std::min(mDataSize, kMaxMtpFileSize);
+    std::vector<char> dataBuffer = mFdp.ConsumeBytes<char>(
+            mFdp.ConsumeIntegralInRange<uint32_t>(minFileSize, maxFileSize));
+    write(fd, dataBuffer.data(), dataBuffer.size());
+    lseek(fd, 0, SEEK_SET);
+    return dataBuffer.size();
+}
+
+void MtpFfsHandleFuzzer::createDeviceFile(const char* file) {
+    int32_t fd = open(file, O_CREAT | O_RDWR | O_NONBLOCK);
+    close(fd);
+}
+
+void MtpFfsHandleFuzzer::writeDeviceFile(const char* file) {
+    int32_t fd = open(file, O_RDWR | O_NONBLOCK);
+    writeInputFile(fd);
+    close(fd);
+}
+
+void MtpFfsHandleFuzzer::createFiles() {
+    mkdir(kFuzzerUsbDirPath.c_str(), 0755);
+    mkdir(kFuzzerMtpPath.c_str(), 0755);
+    mkdir(kFuzzerPtpPath.c_str(), 0755);
+
+    for (auto path : kDeviceFilePaths) {
+        createDeviceFile(path.c_str());
+    }
+
+    writeDeviceFile(FFS_MTP_EP_OUT);
+    writeDeviceFile(FFS_PTP_EP_OUT);
+}
+
+void MtpFfsHandleFuzzer::removeFiles() {
+    for (auto path : kDeviceFilePaths) {
+        remove(path.c_str());
+    }
+
+    rmdir(kFuzzerMtpPath.c_str());
+    rmdir(kFuzzerPtpPath.c_str());
+    rmdir(kFuzzerUsbDirPath.c_str());
+}
+
+void MtpFfsHandleFuzzer::invokeWriteDescriptor() {
+    while (mFdp.remaining_bytes() > 0) {
+        int32_t controlFd = mFdp.ConsumeBool()
+                                    ? -1 /* Invalid fd*/
+                                    : open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+        std::unique_ptr<MtpFfsHandle> handle(new MtpFfsHandle(controlFd));
+        handle->writeDescriptors(mFdp.ConsumeBool());
+        handle->close();
+        close(controlFd);
+        remove(kFuzzerTestFile.c_str());
+    }
+}
+
+void MtpFfsHandleFuzzer::invokeMtpFfsHandle() {
+    while (mFdp.remaining_bytes() > 0) {
+        int32_t controlFd = open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+        writeInputFile(controlFd);
+
+        std::unique_ptr<IMtpHandle> handle;
+        if (mFdp.ConsumeBool()) {
+            std::unique_ptr<IMtpHandle> mtpCompactHandle(new MtpFfsCompatHandle(controlFd));
+            handle = move(mtpCompactHandle);
+        } else {
+            std::unique_ptr<IMtpHandle> mtpHandle(new MtpFfsHandle(controlFd));
+            handle = move(mtpHandle);
+        }
+
+        int32_t mtpHandle = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxMtpHandleAPI);
+        switch (mtpHandle) {
+            case 0: {
+                handle->start(mFdp.ConsumeBool());
+                break;
+            }
+            case 1: {
+                std::string data = mFdp.ConsumeRandomLengthString(MTP_BUFFER_SIZE);
+                handle->write(data.c_str(), data.length());
+                break;
+            }
+            case 2: {
+                int32_t bufferSize =
+                        mFdp.ConsumeIntegralInRange<size_t>(kMinBufferSize, MTP_BUFFER_SIZE);
+                uint8_t buffer[bufferSize + 1];
+                handle->read(buffer, bufferSize);
+                break;
+            }
+            case 3: {
+                mtp_file_range mfr;
+                mfr.fd = open(kFuzzerMtpInputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+                mfr.length = writeInputFile(mfr.fd);
+                mfr.offset = 0; /* Offset point to the start of the file */
+                mfr.command = mFdp.ConsumeIntegral<uint16_t>();
+                mfr.transaction_id = mFdp.ConsumeIntegral<uint32_t>();
+                handle->sendFile(mfr);
+                close(mfr.fd);
+                remove(kFuzzerMtpInputFile.c_str());
+                break;
+            }
+            case 4: {
+                struct mtp_event event;
+                std::string dataValue = mFdp.ConsumeRandomLengthString(kMaxStringLength);
+                event.data = const_cast<char*>(dataValue.c_str());
+                event.length = dataValue.length();
+                handle->sendEvent(event);
+                break;
+            }
+            case 5:
+            default: {
+                mtp_file_range mfr;
+                mfr.fd = open(kFuzzerMtpOutputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+                mfr.offset = 0; /* Offset point to the start of the file */
+                mfr.length = kMaxMtpFileSize;
+                handle->receiveFile(mfr, mFdp.ConsumeBool());
+                close(mfr.fd);
+                remove(kFuzzerMtpOutputFile.c_str());
+                break;
+            }
+        }
+        handle->close();
+        close(controlFd);
+        remove(kFuzzerTestFile.c_str());
+    }
+}
+
+void MtpFfsHandleFuzzer::process() {
+    if (mFdp.ConsumeBool()) {
+        invokeMtpFfsHandle();
+    } else {
+        invokeWriteDescriptor();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpFfsHandleFuzzer mtpFfsHandleFuzzer(data, size);
+    mtpFfsHandleFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
new file mode 100644
index 0000000..6fc2a96
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpPacketFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+                                                   sizeof(struct usbdevfs_iso_packet_desc));
+    };
+    ~MtpPacketFuzzer() { free(mUsbDevFsUrb); };
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void MtpPacketFuzzer::process() {
+    MtpPacket mtpPacket(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); /*bufferSize*/
+    while (mFdp.remaining_bytes() > 0) {
+        auto mtpPacketAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    mtpPacket.allocate(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+                },
+                [&]() { mtpPacket.reset(); },
+                [&]() { mtpPacket.getContainerType(); },
+                [&]() { mtpPacket.getContainerCode(); },
+                [&]() { mtpPacket.dump(); },
+                [&]() { mtpPacket.getTransactionID(); },
+                [&]() {
+                    mtpPacket.setContainerCode(
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    mtpPacket.setTransactionID(
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    mtpPacket.getParameter(
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    mtpPacket.setParameter(
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize),
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+                },
+                [&]() {
+                    MtpPacket testMtpPacket(
+                            mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+                    testMtpPacket.copyFrom(mtpPacket);
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpPacket.transfer(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+        });
+        mtpPacketAPI();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpPacketFuzzer mtpPacketFuzzer(data, size);
+    mtpPacketFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
new file mode 100644
index 0000000..8577e62
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 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 <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpProperty.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+constexpr uint16_t kFeasibleTypes[] = {
+        MTP_TYPE_UNDEFINED, MTP_TYPE_INT8,    MTP_TYPE_UINT8,  MTP_TYPE_INT16,   MTP_TYPE_UINT16,
+        MTP_TYPE_INT32,     MTP_TYPE_UINT32,  MTP_TYPE_INT64,  MTP_TYPE_UINT64,  MTP_TYPE_INT128,
+        MTP_TYPE_UINT128,   MTP_TYPE_AINT8,   MTP_TYPE_AUINT8, MTP_TYPE_AINT16,  MTP_TYPE_AUINT16,
+        MTP_TYPE_AINT32,    MTP_TYPE_AUINT32, MTP_TYPE_AINT64, MTP_TYPE_AUINT64, MTP_TYPE_AINT128,
+        MTP_TYPE_AUINT128,  MTP_TYPE_STR,
+};
+
+class MtpPropertyFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpPropertyFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void MtpPropertyFuzzer::process() {
+    MtpProperty* mtpProperty;
+    if (mFdp.ConsumeBool()) {
+        mtpProperty = new MtpProperty();
+    } else {
+        uint16_t type = mFdp.ConsumeBool() ? mFdp.ConsumeIntegral<uint16_t>()
+                                           : mFdp.PickValueInArray<uint16_t>(kFeasibleTypes);
+        mtpProperty = new MtpProperty(mFdp.ConsumeIntegral<uint16_t>(), type, mFdp.ConsumeBool(),
+                                      mFdp.ConsumeIntegral<uint16_t>());
+    }
+
+    while (mFdp.remaining_bytes() > 0) {
+        auto invokeMtpPropertyFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    MtpDataPacket mtpDataPacket;
+                    if (mFdp.ConsumeBool()) {
+                        mtpProperty->read(mtpDataPacket);
+
+                    } else {
+                        if (mFdp.ConsumeBool()) {
+#ifdef MTP_DEVICE
+                            android::IMtpHandle* h = new MtpDevHandle();
+                            h->start(mFdp.ConsumeBool());
+                            std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+                            char* data = const_cast<char*>(text.c_str());
+                            h->read(static_cast<void*>(data), text.length());
+                            mtpDataPacket.write(h);
+                            h->close();
+                            delete h;
+#endif
+
+#ifdef MTP_HOST
+                            fillFilePath(&mFdp);
+                            int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                            fillUsbRequest(fd, &mFdp);
+                            mtpDataPacket.write(&mUsbRequest,
+                                                mFdp.PickValueInArray<UrbPacketDivisionMode>(
+                                                        kUrbPacketDivisionModes),
+                                                fd,
+                                                mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+                            usb_device_close(mUsbRequest.dev);
+#endif
+                        }
+
+                        if (mFdp.ConsumeBool()) {
+                            mtpProperty->write(mtpDataPacket);
+                        } else {
+                            mtpProperty->setCurrentValue(mtpDataPacket);
+                        }
+                    }
+                },
+                [&]() {
+                    char16_t* data = nullptr;
+                    std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+                    android::String16 s(str.c_str());
+                    if (mFdp.ConsumeBool()) {
+                        data = const_cast<char16_t*>(s.string());
+                    }
+
+                    if (mFdp.ConsumeBool()) {
+                        mtpProperty->setDefaultValue(reinterpret_cast<uint16_t*>(data));
+                    } else if (mFdp.ConsumeBool()) {
+                        mtpProperty->setCurrentValue(reinterpret_cast<uint16_t*>(data));
+                    } else {
+                        mtpProperty->setCurrentValue(str.c_str());
+                    }
+                },
+                [&]() {
+                    mtpProperty->setFormRange(mFdp.ConsumeIntegral<int32_t>(),
+                                              mFdp.ConsumeIntegral<int32_t>(),
+                                              mFdp.ConsumeIntegral<int32_t>());
+                },
+                [&]() {
+                    std::vector<int32_t> init;
+                    for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize);
+                         ++idx) {
+                        init.push_back(mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    mtpProperty->setFormEnum(init.data(), init.size());
+                },
+        });
+        invokeMtpPropertyFuzzer();
+    }
+
+    delete (mtpProperty);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpPropertyFuzzer mtpPropertyFuzzer(data, size);
+    mtpPropertyFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
new file mode 100644
index 0000000..19fbc5b
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpRequestPacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <fstream>
+
+using namespace android;
+
+std::string kMtpDevPath = "/dev/mtp_usb";
+constexpr int32_t kMaxBytes = 100000;
+
+class MtpRequestPacketFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpRequestPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+                                                   sizeof(struct usbdevfs_iso_packet_desc));
+    };
+    ~MtpRequestPacketFuzzer() { free(mUsbDevFsUrb); };
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+    void makeFile(std::string s);
+};
+
+void MtpRequestPacketFuzzer::process() {
+    MtpRequestPacket mtpRequestPacket;
+    while (mFdp.remaining_bytes() > 0) {
+        auto mtpRequestAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    mtpRequestPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+                },
+                [&]() { mtpRequestPacket.reset(); },
+                [&]() {
+                    MtpDevHandle handle;
+                    makeFile(kMtpDevPath);
+                    handle.start(mFdp.ConsumeBool());
+                    std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+                            mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+                    handle.write(data.data(), data.size());
+                    mtpRequestPacket.read(&handle);
+                    handle.close();
+                    remove(kMtpDevPath.c_str());
+                },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpRequestPacket.write(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+        });
+        mtpRequestAPI();
+    }
+}
+
+void MtpRequestPacketFuzzer::makeFile(std::string s) {
+    std::ofstream out;
+    out.open(s, std::ios::binary | std::ofstream::trunc);
+    for (int32_t idx = 0; idx < mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); ++idx) {
+        out << mFdp.ConsumeRandomLengthString(kMaxBytes) << "\n";
+    }
+    out.close();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpRequestPacketFuzzer mtpRequestPacketFuzzer(data, size);
+    mtpRequestPacketFuzzer.process();
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
new file mode 100644
index 0000000..697785f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 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 <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpResponsePacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpResponsePacketFuzzer : MtpPacketFuzzerUtils {
+  public:
+    MtpResponsePacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+                                                   sizeof(struct usbdevfs_iso_packet_desc));
+    };
+    ~MtpResponsePacketFuzzer() { free(mUsbDevFsUrb); };
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+};
+
+void MtpResponsePacketFuzzer::process() {
+    MtpResponsePacket mtpResponsePacket;
+    while (mFdp.remaining_bytes() > 0) {
+        auto mtpResponseAPI = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    mtpResponsePacket.allocate(
+                            mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); /*size*/
+                },
+                [&]() { mtpResponsePacket.reset(); },
+                [&]() { writeHandle(&mtpResponsePacket, &mFdp); },
+                [&]() {
+                    fillFilePath(&mFdp);
+                    int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+                    fillUsbRequest(fd, &mFdp);
+                    mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+                    mtpResponsePacket.read(&mUsbRequest);
+                    usb_device_close(mUsbRequest.dev);
+                },
+        });
+        mtpResponseAPI();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MtpResponsePacketFuzzer mtpResponsePacketFuzzer(data, size);
+    mtpResponsePacketFuzzer.process();
+    return 0;
+}
diff --git a/media/ndk/fuzzer/Android.bp b/media/ndk/fuzzer/Android.bp
index b2ae220..a3d6a96 100644
--- a/media/ndk/fuzzer/Android.bp
+++ b/media/ndk/fuzzer/Android.bp
@@ -64,3 +64,55 @@
     srcs: ["ndk_crypto_fuzzer.cpp"],
     defaults: ["libmediandk_fuzzer_defaults"],
 }
+
+cc_fuzz {
+     name: "ndk_image_reader_fuzzer",
+     srcs: [
+        "ndk_image_reader_fuzzer.cpp",
+     ],
+     shared_libs: [
+        "android.hidl.token@1.0-utils",
+        "android.hardware.graphics.bufferqueue@1.0",
+     ],
+     cflags: [
+        "-D__ANDROID_VNDK__",
+     ],
+     defaults: ["libmediandk_fuzzer_defaults"],
+}
+
+cc_fuzz {
+    name: "ndk_extractor_fuzzer",
+    srcs: ["ndk_extractor_fuzzer.cpp"],
+    defaults: ["libmediandk_fuzzer_defaults"],
+    shared_libs: ["libbinder_ndk",],
+    corpus: ["corpus/*"],
+}
+
+cc_fuzz {
+    name: "ndk_mediaformat_fuzzer",
+    srcs: ["ndk_mediaformat_fuzzer.cpp"],
+    defaults: ["libmediandk_fuzzer_defaults",],
+}
+
+cc_fuzz {
+    name: "ndk_drm_fuzzer",
+    srcs: ["ndk_drm_fuzzer.cpp"],
+    defaults: ["libmediandk_fuzzer_defaults",],
+}
+
+cc_fuzz {
+    name: "ndk_mediamuxer_fuzzer",
+    srcs: ["ndk_mediamuxer_fuzzer.cpp"],
+    defaults: ["libmediandk_fuzzer_defaults"],
+    shared_libs: ["libbinder_ndk",],
+}
+
+cc_fuzz {
+    name: "ndk_sync_codec_fuzzer",
+    srcs: [
+            "ndk_sync_codec_fuzzer.cpp",
+             "NdkMediaCodecFuzzerBase.cpp",
+          ],
+    header_libs: ["libnativewindow_headers",],
+    defaults: ["libmediandk_fuzzer_defaults",],
+}
diff --git a/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp
new file mode 100644
index 0000000..c7ce950
--- /dev/null
+++ b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2022 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 <NdkMediaCodecFuzzerBase.h>
+
+static const std::string kMimeTypes[] = {
+        MIMETYPE_AUDIO_AMR_NB, MIMETYPE_AUDIO_AMR_WB,    MIMETYPE_AUDIO_MPEG,
+        MIMETYPE_AUDIO_AAC,    MIMETYPE_AUDIO_FLAC,      MIMETYPE_AUDIO_VORBIS,
+        MIMETYPE_AUDIO_OPUS,   MIMETYPE_AUDIO_RAW,       MIMETYPE_AUDIO_MSGSM,
+        MIMETYPE_AUDIO_EAC3,   MIMETYPE_AUDIO_SCRAMBLED, MIMETYPE_VIDEO_VP8,
+        MIMETYPE_VIDEO_VP9,    MIMETYPE_VIDEO_AV1,       MIMETYPE_VIDEO_AVC,
+        MIMETYPE_VIDEO_HEVC,   MIMETYPE_VIDEO_MPEG4,     MIMETYPE_VIDEO_H263,
+        MIMETYPE_VIDEO_MPEG2,  MIMETYPE_VIDEO_RAW,       MIMETYPE_VIDEO_SCRAMBLED};
+
+static const std::string kEncoderNames[] = {
+        "c2.android.avc.encoder",    "c2.android.vp8.encoder",   "c2.android.vp9.encoder",
+        "c2.android.hevc.encoder",   "c2.android.mpeg2.encoder", "c2.android.mpeg4.encoder",
+        "c2.android.opus.encoder",   "c2.android.amrnb.encoder", "c2.android.flac.encoder",
+        "c2.android.av1-aom.encoder"};
+
+static const std::string kDecoderNames[] = {"c2.android.avc.decoder",
+                                            "c2.android.vp8.decoder",
+                                            "c2.android.vp9.decoder"
+                                            "c2.android.hevc.decoder",
+                                            "c2.android.mpeg2.decoder",
+                                            "c2.android.mpeg4.decoder",
+                                            "c2.android.opus.decoder",
+                                            "c2.android.amrnb.decoder",
+                                            "c2.android.flac.decoder",
+                                            "c2.android.av1-aom.decoder"};
+
+static const std::string kFormatIntKeys[] = {AMEDIAFORMAT_KEY_BIT_RATE,
+                                             AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                             AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
+                                             AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                             AMEDIAFORMAT_KEY_WIDTH,
+                                             AMEDIAFORMAT_KEY_HEIGHT,
+                                             AMEDIAFORMAT_KEY_FRAME_RATE,
+                                             AMEDIAFORMAT_KEY_COLOR_FORMAT,
+                                             AMEDIAFORMAT_VIDEO_QP_P_MIN,
+                                             AMEDIAFORMAT_VIDEO_QP_P_MAX,
+                                             AMEDIAFORMAT_VIDEO_QP_MIN,
+                                             AMEDIAFORMAT_VIDEO_QP_MAX,
+                                             AMEDIAFORMAT_VIDEO_QP_I_MIN,
+                                             AMEDIAFORMAT_VIDEO_QP_I_MAX,
+                                             AMEDIAFORMAT_VIDEO_QP_B_MIN,
+                                             AMEDIAFORMAT_VIDEO_QP_B_MAX,
+                                             AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE,
+                                             AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL,
+                                             AMEDIAFORMAT_KEY_VALID_SAMPLES,
+                                             AMEDIAFORMAT_KEY_TRACK_INDEX,
+                                             AMEDIAFORMAT_KEY_TRACK_ID,
+                                             AMEDIAFORMAT_KEY_TILE_WIDTH,
+                                             AMEDIAFORMAT_KEY_TILE_HEIGHT,
+                                             AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH,
+                                             AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT,
+                                             AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
+                                             AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT,
+                                             AMEDIAFORMAT_KEY_STRIDE,
+                                             AMEDIAFORMAT_KEY_SLICE_HEIGHT,
+                                             AMEDIAFORMAT_KEY_SAR_WIDTH,
+                                             AMEDIAFORMAT_KEY_SAR_HEIGHT,
+                                             AMEDIAFORMAT_KEY_ROTATION,
+                                             AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN,
+                                             AMEDIAFORMAT_KEY_PROFILE,
+                                             AMEDIAFORMAT_KEY_PRIORITY,
+                                             AMEDIAFORMAT_KEY_PICTURE_TYPE,
+                                             AMEDIAFORMAT_KEY_PCM_ENCODING,
+                                             AMEDIAFORMAT_KEY_OPERATING_RATE,
+                                             AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
+                                             AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
+                                             AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
+                                             AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
+                                             AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
+                                             AMEDIAFORMAT_KEY_LOW_LATENCY,
+                                             AMEDIAFORMAT_KEY_LOOP,
+                                             AMEDIAFORMAT_KEY_LEVEL,
+                                             AMEDIAFORMAT_KEY_LATENCY,
+                                             AMEDIAFORMAT_KEY_IS_SYNC_FRAME,
+                                             AMEDIAFORMAT_KEY_IS_DEFAULT,
+                                             AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
+                                             AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
+                                             AMEDIAFORMAT_KEY_GRID_ROWS,
+                                             AMEDIAFORMAT_KEY_GRID_COLUMNS,
+                                             AMEDIAFORMAT_KEY_FRAME_COUNT,
+                                             AMEDIAFORMAT_KEY_ENCODER_PADDING,
+                                             AMEDIAFORMAT_KEY_ENCODER_DELAY,
+                                             AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
+                                             AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
+                                             AMEDIAFORMAT_KEY_DISPLAY_CROP,
+                                             AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
+                                             AMEDIAFORMAT_KEY_CRYPTO_MODE,
+                                             AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+                                             AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+                                             AMEDIAFORMAT_KEY_COLOR_TRANSFER,
+                                             AMEDIAFORMAT_KEY_COLOR_STANDARD,
+                                             AMEDIAFORMAT_KEY_COLOR_RANGE,
+                                             AMEDIAFORMAT_KEY_CHANNEL_MASK,
+                                             AMEDIAFORMAT_KEY_BITS_PER_SAMPLE,
+                                             AMEDIAFORMAT_KEY_BITRATE_MODE,
+                                             AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
+                                             AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID,
+                                             AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID,
+                                             AMEDIAFORMAT_KEY_AAC_SBR_MODE,
+                                             AMEDIAFORMAT_KEY_AAC_PROFILE,
+                                             AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
+                                             AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
+                                             AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+                                             AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
+                                             AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
+                                             AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
+                                             AMEDIAFORMAT_KEY_XMP_SIZE,
+                                             AMEDIAFORMAT_KEY_XMP_OFFSET,
+                                             AMEDIAFORMAT_KEY_TIME_US,
+                                             AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
+                                             AMEDIAFORMAT_KEY_TARGET_TIME,
+                                             AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND,
+                                             AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET,
+                                             AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK,
+                                             AMEDIAFORMAT_KEY_EXIF_SIZE,
+                                             AMEDIAFORMAT_KEY_EXIF_OFFSET,
+                                             AMEDIAFORMAT_KEY_DURATION};
+
+static const std::string kFormatBufferKeys[] = {
+        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C,
+        AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+        AMEDIAFORMAT_KEY_SEI,
+        AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
+        AMEDIAFORMAT_KEY_PSSH,
+        AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
+        AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER,
+        AMEDIAFORMAT_KEY_MPEG_USER_DATA,
+        AMEDIAFORMAT_KEY_ICC_PROFILE,
+        AMEDIAFORMAT_KEY_HDR10_PLUS_INFO,
+        AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
+        AMEDIAFORMAT_KEY_ESDS,
+        AMEDIAFORMAT_KEY_D263,
+        AMEDIAFORMAT_KEY_CSD_HEVC,
+        AMEDIAFORMAT_KEY_CSD_AVC,
+        AMEDIAFORMAT_KEY_CSD_2,
+        AMEDIAFORMAT_KEY_CSD_1,
+        AMEDIAFORMAT_KEY_CSD_0,
+        AMEDIAFORMAT_KEY_CSD,
+        AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+        AMEDIAFORMAT_KEY_CRYPTO_KEY,
+        AMEDIAFORMAT_KEY_CRYPTO_IV,
+        AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+        AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+        AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+        AMEDIAFORMAT_KEY_ALBUMART,
+};
+
+static const std::string kFormatFloatKeys[] = {AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+                                               AMEDIAFORMAT_KEY_CAPTURE_RATE};
+
+static const std::string kFormatStringKeys[] = {AMEDIAFORMAT_KEY_YEAR,
+                                                AMEDIAFORMAT_KEY_TITLE,
+                                                AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
+                                                AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS,
+                                                AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
+                                                AMEDIAFORMAT_KEY_MANUFACTURER,
+                                                AMEDIAFORMAT_KEY_LYRICIST,
+                                                AMEDIAFORMAT_KEY_LOCATION,
+                                                AMEDIAFORMAT_KEY_LANGUAGE,
+                                                AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
+                                                AMEDIAFORMAT_KEY_IS_AUTOSELECT,
+                                                AMEDIAFORMAT_KEY_IS_ADTS,
+                                                AMEDIAFORMAT_KEY_GENRE,
+                                                AMEDIAFORMAT_KEY_DISCNUMBER,
+                                                AMEDIAFORMAT_KEY_DATE,
+                                                AMEDIAFORMAT_KEY_COMPOSER,
+                                                AMEDIAFORMAT_KEY_COMPILATION,
+                                                AMEDIAFORMAT_KEY_COMPLEXITY,
+                                                AMEDIAFORMAT_KEY_CDTRACKNUMBER,
+                                                AMEDIAFORMAT_KEY_AUTHOR,
+                                                AMEDIAFORMAT_KEY_ARTIST,
+                                                AMEDIAFORMAT_KEY_ALBUMARTIST,
+                                                AMEDIAFORMAT_KEY_ALBUM};
+
+void formatSetString(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+    if (fdp->ConsumeBool()) {
+        std::string keyValue = fdp->ConsumeRandomLengthString(kMaxBytes);
+        AMediaFormat_setString(format, AMEDIAFORMAT_KEY, keyValue.c_str());
+    }
+}
+
+void formatSetInt(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+    if (fdp->ConsumeBool()) {
+        int32_t keyValue = fdp->ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue);
+        AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY, keyValue);
+    }
+}
+
+void formatSetFloat(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+    if (fdp->ConsumeBool()) {
+        float keyValue =
+                fdp->ConsumeFloatingPointInRange<float>(kMinFloatKeyValue, kMaxFloatKeyValue);
+        AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY, keyValue);
+    }
+}
+
+void formatSetBuffer(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) {
+    if (fdp->ConsumeBool()) {
+        std::vector<uint8_t> buffer = fdp->ConsumeBytes<uint8_t>(
+                fdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+        AMediaFormat_setBuffer(format, AMEDIAFORMAT_KEY, buffer.data(), buffer.size());
+    }
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByname(bool isEncoder,
+                                                              bool isCodecForClient) {
+    std::string name;
+    if (isEncoder) {
+        name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kEncoderNames)
+                                   : mFdp->ConsumeRandomLengthString(kMaxBytes);
+    } else {
+        name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kDecoderNames)
+                                   : mFdp->ConsumeRandomLengthString(kMaxBytes);
+    }
+
+    if (isCodecForClient) {
+        pid_t pid = mFdp->ConsumeIntegral<pid_t>();
+        uid_t uid = mFdp->ConsumeIntegral<uid_t>();
+        return AMediaCodec_createCodecByNameForClient(name.c_str(), pid, uid);
+
+    } else {
+        return AMediaCodec_createCodecByName(name.c_str());
+    }
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByType(bool isEncoder,
+                                                              bool isCodecForClient) {
+    std::string mimeType;
+    const char* mime = nullptr;
+
+    if (mFdp->ConsumeBool()) {
+        mimeType = mFdp->ConsumeRandomLengthString(kMaxBytes);
+        mime = mimeType.c_str();
+    } else {
+        AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+    }
+
+    if (isCodecForClient) {
+        pid_t pid = mFdp->ConsumeIntegral<pid_t>();
+        uid_t uid = mFdp->ConsumeIntegral<uid_t>();
+        return isEncoder ? AMediaCodec_createEncoderByTypeForClient(mime, pid, uid)
+                         : AMediaCodec_createDecoderByTypeForClient(mime, pid, uid);
+    } else {
+        return isEncoder ? AMediaCodec_createEncoderByType(mime)
+                         : AMediaCodec_createDecoderByType(mime);
+    }
+}
+
+AMediaFormat* NdkMediaCodecFuzzerBase::getSampleCodecFormat() {
+    AMediaFormat* format = AMediaFormat_new();
+    std::string value;
+    int32_t count = 0;
+    int32_t maxFormatKeys = 0;
+
+    /*set mimeType*/
+    if (mFdp->ConsumeBool()) {
+        value = mFdp->ConsumeRandomLengthString(kMaxBytes);
+    } else {
+        value = mFdp->PickValueInArray(kMimeTypes);
+    }
+    if (mFdp->ConsumeBool()) {
+        AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, value.c_str());
+    }
+
+    maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatStringKeys));
+    for (count = 0; count < maxFormatKeys; ++count) {
+        std::string formatKey = mFdp->PickValueInArray(kFormatStringKeys);
+        formatSetString(format, formatKey.c_str(), mFdp);
+    }
+
+    maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatIntKeys));
+    for (count = 0; count < maxFormatKeys; ++count) {
+        std::string formatKey = mFdp->PickValueInArray(kFormatIntKeys);
+        formatSetInt(format, formatKey.c_str(), mFdp);
+    }
+
+    maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatFloatKeys));
+    for (count = 0; count < maxFormatKeys; ++count) {
+        std::string formatKey = mFdp->PickValueInArray(kFormatFloatKeys);
+        formatSetFloat(format, formatKey.c_str(), mFdp);
+    }
+
+    maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatBufferKeys));
+    for (count = 0; count < maxFormatKeys; ++count) {
+        std::string formatKey = mFdp->PickValueInArray(kFormatBufferKeys);
+        formatSetBuffer(format, formatKey.c_str(), mFdp);
+    }
+    return format;
+}
+
+AMediaCodec* NdkMediaCodecFuzzerBase::createCodec(bool isEncoder, bool isCodecForClient) {
+    mFormat = getSampleCodecFormat();
+    return (mFdp->ConsumeBool() ? createAMediaCodecByname(isEncoder, isCodecForClient)
+                                : createAMediaCodecByType(isEncoder, isCodecForClient));
+}
+
+void NdkMediaCodecFuzzerBase::invokeCodecFormatAPI(AMediaCodec* codec) {
+    AMediaFormat* codecFormat = nullptr;
+    size_t codecFormatAPI = mFdp->ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxCodecFormatAPIs);
+    switch (codecFormatAPI) {
+        case 0: {
+            codecFormat = AMediaCodec_getInputFormat(codec);
+            break;
+        }
+        case 1: {
+            codecFormat = AMediaCodec_getOutputFormat(codec);
+            break;
+        }
+        case 2:
+        default: {
+            AMediaCodecBufferInfo info;
+            int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+            ssize_t bufferIndex = 0;
+            if (mFdp->ConsumeBool()) {
+                bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs);
+            } else {
+                bufferIndex =
+                        mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+            }
+            codecFormat = AMediaCodec_getBufferFormat(codec, bufferIndex);
+            break;
+        }
+    }
+    if (codecFormat) {
+        AMediaFormat_delete(codecFormat);
+    }
+}
+
+void NdkMediaCodecFuzzerBase::invokeInputBufferOperationAPI(AMediaCodec* codec) {
+    size_t bufferSize = 0;
+    ssize_t bufferIndex = 0;
+    int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+    if (mFdp->ConsumeBool()) {
+        bufferIndex = AMediaCodec_dequeueInputBuffer(codec, timeOutUs);
+    } else {
+        bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+    }
+
+    uint8_t* buffer = AMediaCodec_getInputBuffer(codec, bufferIndex, &bufferSize);
+    if (buffer) {
+        std::vector<uint8_t> bytesRead = mFdp->ConsumeBytes<uint8_t>(
+                std::min(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes), bufferSize));
+        memcpy(buffer, bytesRead.data(), bytesRead.size());
+        bufferSize = bytesRead.size();
+    }
+
+    int32_t flag = mFdp->ConsumeIntegralInRange<size_t>(AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG,
+                                                        AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME);
+    if (mFdp->ConsumeBool()) {
+        AMediaCodec_queueInputBuffer(codec, bufferIndex, 0 /* offset */, bufferSize, 0 /* time */,
+                                     flag);
+    } else {
+        AMediaCodecCryptoInfo* cryptoInfo = getAMediaCodecCryptoInfo();
+        AMediaCodec_queueSecureInputBuffer(codec, bufferIndex, 0 /* offset */, cryptoInfo,
+                                           0 /* time */, flag);
+        AMediaCodecCryptoInfo_delete(cryptoInfo);
+    }
+}
+
+void NdkMediaCodecFuzzerBase::invokeOutputBufferOperationAPI(AMediaCodec* codec) {
+    ssize_t bufferIndex = 0;
+    int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs);
+    if (mFdp->ConsumeBool()) {
+        AMediaCodecBufferInfo info;
+        bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs);
+    } else {
+        bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex);
+    }
+
+    if (mFdp->ConsumeBool()) {
+        size_t bufferSize = 0;
+        (void)AMediaCodec_getOutputBuffer(codec, bufferIndex, &bufferSize);
+    }
+
+    if (mFdp->ConsumeBool()) {
+        AMediaCodec_releaseOutputBuffer(codec, bufferIndex, mFdp->ConsumeBool());
+    } else {
+        AMediaCodec_releaseOutputBufferAtTime(codec, bufferIndex, timeOutUs);
+    }
+}
+
+AMediaCodecCryptoInfo* NdkMediaCodecFuzzerBase::getAMediaCodecCryptoInfo() {
+    uint8_t key[kMaxCryptoKey];
+    uint8_t iv[kMaxCryptoKey];
+    size_t clearBytes[kMaxCryptoKey];
+    size_t encryptedBytes[kMaxCryptoKey];
+
+    for (int32_t i = 0; i < kMaxCryptoKey; ++i) {
+        key[i] = mFdp->ConsumeIntegral<uint8_t>();
+        iv[i] = mFdp->ConsumeIntegral<uint8_t>();
+        clearBytes[i] = mFdp->ConsumeIntegral<size_t>();
+        encryptedBytes[i] = mFdp->ConsumeIntegral<size_t>();
+    }
+
+    return AMediaCodecCryptoInfo_new(kMaxCryptoKey, key, iv, AMEDIACODECRYPTOINFO_MODE_CLEAR,
+                                     clearBytes, encryptedBytes);
+}
diff --git a/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h
new file mode 100644
index 0000000..42ef6ea
--- /dev/null
+++ b/media/ndk/fuzzer/NdkMediaCodecFuzzerBase.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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 <android/native_window.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaCodecPlatform.h>
+#include <media/NdkMediaFormat.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+constexpr int32_t kMinBytes = 1;
+constexpr int32_t kMaxBytes = 256;
+constexpr int32_t kMinIntKeyValue = 0;
+constexpr int32_t kMaxIntKeyValue = 6000000;
+constexpr int32_t kMinFloatKeyValue = 1.0f;
+constexpr int32_t kMaxFloatKeyValue = 500.f;
+constexpr int32_t kMinTimeOutUs = 0;
+constexpr int32_t kMaxTimeOutUs = 5000;
+constexpr int32_t kMinAPICase = 0;
+constexpr int32_t kMaxCodecFormatAPIs = 2;
+constexpr int32_t kMaxCryptoKey = 16;
+constexpr int32_t kMinIterations = 10;
+constexpr int32_t kMaxIterations = 100;
+constexpr size_t kMinBufferIndex = 1;
+constexpr size_t kMaxBufferIndex = 128;
+
+class NdkMediaCodecFuzzerBase {
+  public:
+    void invokeCodecFormatAPI(AMediaCodec* codec);
+    void invokeInputBufferOperationAPI(AMediaCodec* codec);
+    void invokeOutputBufferOperationAPI(AMediaCodec* codec);
+    AMediaCodecCryptoInfo* getAMediaCodecCryptoInfo();
+    AMediaCodec* createCodec(bool isEncoder, bool isCodecForClient);
+    AMediaFormat* getCodecFormat() { return mFormat; };
+    void setFdp(FuzzedDataProvider* fdp) { mFdp = fdp; }
+
+  private:
+    AMediaCodec* createAMediaCodecByname(bool isEncoder, bool isCodecForClient);
+    AMediaCodec* createAMediaCodecByType(bool isEncoder, bool isCodecForClient);
+    AMediaFormat* getSampleAudioFormat();
+    AMediaFormat* getSampleVideoFormat();
+    AMediaFormat* getSampleCodecFormat();
+    AMediaFormat* mFormat = nullptr;
+    FuzzedDataProvider* mFdp = nullptr;
+};
diff --git a/media/ndk/fuzzer/README.md b/media/ndk/fuzzer/README.md
index 4f78e4a..0fd08b0 100644
--- a/media/ndk/fuzzer/README.md
+++ b/media/ndk/fuzzer/README.md
@@ -2,6 +2,12 @@
 
 ## Table of contents
 + [ndk_crypto_fuzzer](#NdkCrypto)
++ [ndk_image_reader_fuzzer](#NdkImageReader)
++ [ndk_extractor_fuzzer](#NdkExtractor)
++ [ndk_mediaformat_fuzzer](#NdkMediaFormat)
++ [ndk_drm_fuzzer](#NdkDrm)
++ [ndk_mediamuxer_fuzzer](#NdkMediaMuxer)
++ [ndk_sync_codec_fuzzer](#NdkSyncCodec)
 
 # <a name="NdkCrypto"></a> Fuzzer for NdkCrypto
 
@@ -22,3 +28,131 @@
   $ adb sync data
   $ adb shell /data/fuzz/arm64/ndk_crypto_fuzzer/ndk_crypto_fuzzer
 ```
+
+# <a name="NdkImageReader"></a> Fuzzer for NdkImageReader
+
+NdkImageReader supports the following parameters:
+1. Width (parameter name: "imageWidth")
+2. Height (parameter name: "imageHeight")
+3. Format (parameter name: "imageFormat")
+4. Usage (parameter name: "imageUsage")
+5. Max images (parameter name: "imageMaxCount")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `width`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `height`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `format`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `usage`| `1 to INT_MAX`| Value obtained from FuzzedDataProvider|
+| `maxImages`| `1 to android::BufferQueue::MAX_MAX_ACQUIRED_BUFFERS`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_image_reader_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_image_reader_fuzzer/ndk_image_reader_fuzzer
+```
+
+# <a name="NdkExtractor"></a>Fuzzer for NdkExtractor
+
+NdkExtractor supports the following parameters:
+1. SeekMode (parameter name: "mode")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`mode`|0.`AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC`,<br/>1.`AMEDIAEXTRACTOR_SEEK_NEXT_SYNC`,<br/>2.`AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_extractor_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_extractor_fuzzer/ndk_extractor_fuzzer /data/fuzz/${TARGET_ARCH}/ndk_extractor_fuzzer/corpus
+```
+
+
+# <a name="NdkMediaFormat"></a>Fuzzer for NdkMediaFormat
+
+NdkMediaFormat supports the following parameters:
+1. Name (parameter name: "name")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`name`|1.`AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR`, 2.`AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR`, 3.`AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION`, 4.`AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL`, 5.`AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL`, 6.`AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT`, 7.`AMEDIAFORMAT_KEY_AAC_PROFILE`, 8.`AMEDIAFORMAT_KEY_AAC_SBR_MODE`, 9.`AMEDIAFORMAT_KEY_ALBUM`, 10.`AMEDIAFORMAT_KEY_ALBUMART`, 11.`AMEDIAFORMAT_KEY_ALBUMARTIST`, 12.`AMEDIAFORMAT_KEY_ARTIST`, 13.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO`, 14.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID`, 15.`AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID`, 16.`AMEDIAFORMAT_KEY_AUDIO_SESSION_ID`, 17.`AMEDIAFORMAT_KEY_AUTHOR`, 18.`AMEDIAFORMAT_KEY_BITRATE_MODE`, 19.`AMEDIAFORMAT_KEY_BIT_RATE`, 20.`AMEDIAFORMAT_KEY_BITS_PER_SAMPLE`, 21.`AMEDIAFORMAT_KEY_CAPTURE_RATE`, 22.`AMEDIAFORMAT_KEY_CDTRACKNUMBER`, 23.`AMEDIAFORMAT_KEY_CHANNEL_COUNT`, 24.`AMEDIAFORMAT_KEY_CHANNEL_MASK`, 25.`AMEDIAFORMAT_KEY_COLOR_FORMAT`, 26.`AMEDIAFORMAT_KEY_COLOR_RANGE`, 27.`AMEDIAFORMAT_KEY_COLOR_STANDARD`, 28.`AMEDIAFORMAT_KEY_COLOR_TRANSFER`, 29.`AMEDIAFORMAT_KEY_COMPILATION`, 30.`AMEDIAFORMAT_KEY_COMPLEXITY`, 31.`AMEDIAFORMAT_KEY_COMPOSER`, 32.`AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED`, 33.`AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE`, 34.`AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK`, 35.`AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES`, 36.`AMEDIAFORMAT_KEY_CRYPTO_IV`, 37.`AMEDIAFORMAT_KEY_CRYPTO_KEY`, 38.`AMEDIAFORMAT_KEY_CRYPTO_MODE`, 39.`AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES`, 40.`AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK`, 41.`AMEDIAFORMAT_KEY_CSD`, 42.`AMEDIAFORMAT_KEY_CSD_0`, 43.`AMEDIAFORMAT_KEY_CSD_1`, 44.`AMEDIAFORMAT_KEY_CSD_2`, 45.`AMEDIAFORMAT_KEY_CSD_AVC`, 46.`AMEDIAFORMAT_KEY_CSD_HEVC`, 47.`AMEDIAFORMAT_KEY_D263`, 48.`AMEDIAFORMAT_KEY_DATE`, 49.`AMEDIAFORMAT_KEY_DISCNUMBER`, 50.`AMEDIAFORMAT_KEY_DISPLAY_CROP`, 51.`AMEDIAFORMAT_KEY_DISPLAY_HEIGHT`, 52.`AMEDIAFORMAT_KEY_DISPLAY_WIDTH`, 53.`AMEDIAFORMAT_KEY_DURATION`, 54.`AMEDIAFORMAT_KEY_ENCODER_DELAY`, 55.`AMEDIAFORMAT_KEY_ENCODER_PADDING`, 56.`AMEDIAFORMAT_KEY_ESDS`, 57.`AMEDIAFORMAT_KEY_EXIF_OFFSET`, 58.`AMEDIAFORMAT_KEY_EXIF_SIZE`, 59.`AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL`, 60.`AMEDIAFORMAT_KEY_FRAME_COUNT`, 61.`AMEDIAFORMAT_KEY_FRAME_RATE`, 62.`AMEDIAFORMAT_KEY_GENRE`, 63.`AMEDIAFORMAT_KEY_GRID_COLUMNS`, 64.`AMEDIAFORMAT_KEY_GRID_ROWS`, 65.`AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT`, 66.`AMEDIAFORMAT_KEY_HDR_STATIC_INFO`, 67.`AMEDIAFORMAT_KEY_HDR10_PLUS_INFO`, 68.`AMEDIAFORMAT_KEY_HEIGHT`, 69.`AMEDIAFORMAT_KEY_ICC_PROFILE`, 70.`AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD`, 71.`AMEDIAFORMAT_KEY_IS_ADTS`, 72.`AMEDIAFORMAT_KEY_IS_AUTOSELECT`, 73.`AMEDIAFORMAT_KEY_IS_DEFAULT`, 74.`AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE`, 75.`AMEDIAFORMAT_KEY_IS_SYNC_FRAME`, 76.`AMEDIAFORMAT_KEY_I_FRAME_INTERVAL`, 77.`AMEDIAFORMAT_KEY_LANGUAGE`, 78.`AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK`, 79.`AMEDIAFORMAT_KEY_LATENCY`, 80.`AMEDIAFORMAT_KEY_LEVEL`, 81.`AMEDIAFORMAT_KEY_LOCATION`, 82.`AMEDIAFORMAT_KEY_LOOP`, 83.`AMEDIAFORMAT_KEY_LOW_LATENCY`, 84.`AMEDIAFORMAT_KEY_LYRICIST`, 85.`AMEDIAFORMAT_KEY_MANUFACTURER`, 86.`AMEDIAFORMAT_KEY_MAX_BIT_RATE`, 87.`AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER`, 88.`AMEDIAFORMAT_KEY_MAX_HEIGHT`, 89.`AMEDIAFORMAT_KEY_MAX_INPUT_SIZE`, 90.`AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER`, 91.`AMEDIAFORMAT_KEY_MAX_WIDTH`, 92.`AMEDIAFORMAT_KEY_MIME`, 93.`AMEDIAFORMAT_KEY_MPEG_USER_DATA`, 94.`AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER`, 95.`AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS`, 96.`AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION`, 97.`AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT`, 98.`AMEDIAFORMAT_KEY_OPERATING_RATE`, 99.`AMEDIAFORMAT_KEY_PCM_ENCODING`, 100.`AMEDIAFORMAT_KEY_PICTURE_TYPE`, 101.`AMEDIAFORMAT_KEY_PRIORITY`, 102.`AMEDIAFORMAT_KEY_PROFILE`, 103.`AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN`, 104.`AMEDIAFORMAT_KEY_PSSH`, 105.`AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP`, 106.`AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER`, 107.`AMEDIAFORMAT_KEY_ROTATION`, 108.`AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET`, 109.`AMEDIAFORMAT_KEY_SAMPLE_RATE`, 110.`AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND`, 111.`AMEDIAFORMAT_KEY_SAR_HEIGHT`, 112.`AMEDIAFORMAT_KEY_SAR_WIDTH`, 113.`AMEDIAFORMAT_KEY_SEI`, 114.`AMEDIAFORMAT_KEY_SLICE_HEIGHT`, 115.`AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS`, 116.`AMEDIAFORMAT_KEY_STRIDE`, 117.`AMEDIAFORMAT_KEY_TARGET_TIME`, 118.`AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT`, 119.`AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID`, 120.`AMEDIAFORMAT_KEY_TEMPORAL_LAYERING`, 121.`AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA`, 122.`AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C`, 123.`AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC`, 124.`AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT`, 125.`AMEDIAFORMAT_KEY_THUMBNAIL_TIME`, 126.`AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH`, 127.`AMEDIAFORMAT_KEY_TILE_HEIGHT`, 128.`AMEDIAFORMAT_KEY_TILE_WIDTH`, 129.`AMEDIAFORMAT_KEY_TIME_US`, 130.`AMEDIAFORMAT_KEY_TITLE`, 131.`AMEDIAFORMAT_KEY_TRACK_ID`, 132.`AMEDIAFORMAT_KEY_TRACK_INDEX`, 133.`AMEDIAFORMAT_KEY_VALID_SAMPLES`, 134.`AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL`, 135.`AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE`, 136.`AMEDIAFORMAT_VIDEO_QP_B_MAX`, 137.`AMEDIAFORMAT_VIDEO_QP_B_MIN`, 138.`AMEDIAFORMAT_VIDEO_QP_I_MAX`, 139.`AMEDIAFORMAT_VIDEO_QP_I_MIN`, 140.`AMEDIAFORMAT_VIDEO_QP_MAX`, 141.`AMEDIAFORMAT_VIDEO_QP_MIN`, 142.`AMEDIAFORMAT_VIDEO_QP_P_MAX`, 143.`AMEDIAFORMAT_VIDEO_QP_P_MIN`, 144.`AMEDIAFORMAT_KEY_WIDTH`, 145.`AMEDIAFORMAT_KEY_XMP_OFFSET`, 146.`AMEDIAFORMAT_KEY_XMP_SIZE`, 147.`AMEDIAFORMAT_KEY_YEAR`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_mediaformat_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/ndk_mediaformat_fuzzer/ndk_mediaformat_fuzzer /data/fuzz/${TARGET_ARCH}/ndk_mediaformat_fuzzer/corpus
+```
+
+# <a name="NdkDrm"></a> Fuzzer for NdkDrm
+
+NdkDrm supports the following parameters:
+1. ValidUUID(parameter name: "kCommonPsshBoxUUID" and "kClearKeyUUID")
+2. MimeType(parameter name: "kMimeType")
+3. MediaUUID(parameter name: "MediaUUID")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`ValidUUID`| 0.`kCommonPsshBoxUUID`,<br/> 1.`kClearKeyUUID`,<br/> 2.`kInvalidUUID`|Value obtained from FuzzedDataProvider|
+|`kMimeType`| 0.`video/mp4`,<br/> 1.`audio/mp4`|Value obtained from FuzzedDataProvider|
+|`MediaUUID`| 0.`INVALID_UUID`,<br/> 1.`PSSH_BOX_UUID`,<br/> 2.`CLEARKEY_UUID`|Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_drm_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_drm_fuzzer/ndk_drm_fuzzer
+```
+
+# <a name="NdkMediaMuxer"></a>Fuzzer for NdkMediaMuxer
+
+NdkMediaMuxer supports the following parameters:
+1. OutputFormat (parameter name: "outputFormat")
+2. AppendMode (parameter name: "appendMode")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`outputFormat`|0.`AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4`,<br/>1.`AMEDIAMUXER_OUTPUT_FORMAT_WEBM`,<br/>2.`AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP`| Value obtained from FuzzedDataProvider|
+|`appendMode`|0.`AMEDIAMUXER_APPEND_IGNORE_LAST_VIDEO_GOP`,<br/>1.`AMEDIAMUXER_APPEND_TO_EXISTING_DATA`| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_mediamuxer_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_mediamuxer_fuzzer/ndk_mediamuxer_fuzzer
+```
+
+# <a name="NdkSyncCodec"></a>Fuzzer for NdkSyncCodec
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_sync_codec_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_sync_codec_fuzzer/ndk_sync_codec_fuzzer
+```
diff --git a/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738 b/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738
new file mode 100755
index 0000000..47d79c8
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/2822a2c3bcf57f46cb2bf142448d5baeead4d738
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6 b/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6
new file mode 100755
index 0000000..17c934c
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/58833c3691292c199fa601fd51339d85c1f11ca6
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce b/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce
new file mode 100755
index 0000000..00a32e2
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/8556a97764e65bf337b5593058fa92adb68074ce
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950 b/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950
new file mode 100755
index 0000000..86d4001
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/8f76e2e87f79fe213f5cc8c71e5f91d1dcfc5950
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d b/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d
new file mode 100755
index 0000000..496c7f3
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/d702878cb53fb474230fb7b1a5c035bbb7c21c8d
Binary files differ
diff --git a/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a b/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a
new file mode 100755
index 0000000..55437ac
--- /dev/null
+++ b/media/ndk/fuzzer/corpus/edc2485f3927e07d7ab705337f16f0b978c57d0a
Binary files differ
diff --git a/media/ndk/fuzzer/ndk_drm_fuzzer.cpp b/media/ndk/fuzzer/ndk_drm_fuzzer.cpp
new file mode 100644
index 0000000..8c11c9d
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_drm_fuzzer.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2022 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 <media/NdkMediaCrypto.h>
+#include <media/NdkMediaDrm.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+constexpr int32_t kMinBytes = 1;
+constexpr int32_t kMaxBytes = 256;
+constexpr int32_t kMinParamVal = 0;
+constexpr int32_t kMaxParamVal = 3;
+constexpr int32_t kMediaUUIdSize = sizeof(AMediaUUID);
+constexpr int32_t kMinProvisionResponseSize = 0;
+constexpr int32_t kMaxProvisionResponseSize = 16;
+constexpr int32_t kMessageSize = 16;
+constexpr int32_t kMinAPIcase = 0;
+constexpr int32_t kMaxdecryptEncryptAPIs = 10;
+constexpr int32_t kMaxpropertyAPIs = 3;
+constexpr int32_t kMaxsetListenerAPIs = 2;
+constexpr int32_t kMaxndkDrmAPIs = 3;
+uint8_t signature[kMessageSize];
+
+enum MediaUUID { INVALID_UUID = 0, PSSH_BOX_UUID, CLEARKEY_UUID, kMaxValue = CLEARKEY_UUID };
+
+constexpr uint8_t kCommonPsshBoxUUID[] = {0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
+                                          0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B};
+
+constexpr uint8_t kClearKeyUUID[] = {0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
+                                     0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E};
+
+constexpr uint8_t kInvalidUUID[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
+                                    0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
+
+uint8_t kClearkeyPssh[] = {
+        // BMFF box header (4 bytes size + 'pssh')
+        0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
+        // full box header (version = 1 flags = 0)
+        0x01, 0x00, 0x00, 0x00,
+        // system id
+        0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
+        0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
+        // number of key ids
+        0x00, 0x00, 0x00, 0x01,
+        // key id
+        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+        // size of data, must be zero
+        0x00, 0x00, 0x00, 0x00};
+
+std::string kPropertyName = "clientId";
+std::string kMimeType[] = {"video/mp4", "audio/mp4"};
+std::string kCipherAlgorithm[] = {"AES/CBC/NoPadding", ""};
+std::string kMacAlgorithm[] = {"HmacSHA256", ""};
+
+class NdkMediaDrmFuzzer {
+  public:
+    NdkMediaDrmFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void invokeNdkDrm();
+    static void KeysChangeListener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+                                   const AMediaDrmKeyStatus* keysStatus, size_t numKeys,
+                                   bool hasNewUsableKey) {
+        (void)drm;
+        (void)sessionId;
+        (void)keysStatus;
+        (void)numKeys;
+        (void)hasNewUsableKey;
+    };
+
+    static void ExpirationUpdateListener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+                                         int64_t expiryTimeInMS) {
+        (void)drm;
+        (void)sessionId;
+        (void)expiryTimeInMS;
+    };
+
+    static void listener(AMediaDrm* drm, const AMediaDrmSessionId* sessionId,
+                         AMediaDrmEventType eventType, int extra, const uint8_t* data,
+                         size_t dataSize) {
+        (void)drm;
+        (void)sessionId;
+        (void)eventType;
+        (void)extra;
+        (void)data;
+        (void)dataSize;
+    }
+
+  private:
+    FuzzedDataProvider mFdp;
+    void invokeDrmCreatePlugin();
+    void invokeDrmSetListener();
+    void invokeDrmPropertyAPI();
+    void invokeDrmDecryptEncryptAPI();
+    void invokeDrmSecureStopAPI();
+    AMediaDrmSessionId mSessionId = {};
+    AMediaDrm* mDrm = nullptr;
+};
+
+void NdkMediaDrmFuzzer::invokeDrmCreatePlugin() {
+    const uint8_t* mediaUUID = nullptr;
+    uint32_t uuidEnum = mFdp.ConsumeEnum<MediaUUID>();
+    switch (uuidEnum) {
+        case INVALID_UUID: {
+            mediaUUID = kInvalidUUID;
+            break;
+        }
+        case PSSH_BOX_UUID: {
+            mediaUUID = kCommonPsshBoxUUID;
+            break;
+        }
+        case CLEARKEY_UUID:
+        default: {
+            mediaUUID = kClearKeyUUID;
+            break;
+        }
+    }
+    mDrm = AMediaDrm_createByUUID(mediaUUID);
+}
+
+void NdkMediaDrmFuzzer::invokeDrmSecureStopAPI() {
+    // get maximum number of secure stops
+    AMediaDrmSecureStop secureStops;
+    size_t numSecureStops = kMaxParamVal;
+    // The API behavior could change based on the drm object (clearkey or
+    // psshbox) This API detects secure stops msg and release them.
+    AMediaDrm_getSecureStops(mDrm, &secureStops, &numSecureStops);
+    AMediaDrm_releaseSecureStops(mDrm, &secureStops);
+}
+
+void NdkMediaDrmFuzzer::invokeDrmSetListener() {
+    int32_t setListenerAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxsetListenerAPIs);
+    switch (setListenerAPI) {
+        case 0: {  // set on key change listener
+            AMediaDrm_setOnKeysChangeListener(mDrm, KeysChangeListener);
+            break;
+        }
+        case 1: {  // set on expiration on update listener
+            AMediaDrm_setOnExpirationUpdateListener(mDrm, ExpirationUpdateListener);
+            break;
+        }
+        case 2:
+        default: {  // set on event listener
+            AMediaDrm_setOnEventListener(mDrm, listener);
+            break;
+        }
+    }
+}
+
+void NdkMediaDrmFuzzer::invokeDrmPropertyAPI() {
+    int32_t propertyAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxpropertyAPIs);
+    switch (propertyAPI) {
+        case 0: {  // set property byte array
+            uint8_t value[kMediaUUIdSize];
+            std::string name =
+                    mFdp.ConsumeBool() ? kPropertyName : mFdp.ConsumeRandomLengthString(kMaxBytes);
+            const char* propertyName = name.c_str();
+            AMediaDrm_setPropertyByteArray(mDrm, propertyName, value, sizeof(value));
+            break;
+        }
+        case 1: {  // get property in byte array
+            AMediaDrmByteArray array;
+            std::string name =
+                    mFdp.ConsumeBool() ? kPropertyName : mFdp.ConsumeRandomLengthString(kMaxBytes);
+            const char* propertyName = name.c_str();
+            AMediaDrm_getPropertyByteArray(mDrm, propertyName, &array);
+            break;
+        }
+        case 2: {  // set string type property
+            std::string propertyName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+            std::string value = mFdp.ConsumeRandomLengthString(kMaxBytes);
+            AMediaDrm_setPropertyString(mDrm, propertyName.c_str(), value.c_str());
+            break;
+        }
+        case 3:
+        default: {  //  get property in string
+            const char* stringValue = nullptr;
+            std::string propertyName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+            AMediaDrm_getPropertyString(mDrm, propertyName.c_str(), &stringValue);
+            break;
+        }
+    }
+}
+
+void NdkMediaDrmFuzzer::invokeDrmDecryptEncryptAPI() {
+    int32_t decryptEncryptAPI =
+            mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxdecryptEncryptAPIs);
+    switch (decryptEncryptAPI) {
+        case 0: {  // Check if crypto scheme is supported
+            std::string mimeType = mFdp.ConsumeBool() ? mFdp.PickValueInArray(kMimeType)
+                                                      : mFdp.ConsumeRandomLengthString(kMaxBytes);
+            AMediaDrm_isCryptoSchemeSupported(kClearKeyUUID, mimeType.c_str());
+            break;
+        }
+        case 1: {  // get a provision request byte array
+            const uint8_t* legacyRequest;
+            size_t legacyRequestSize = 1;
+            const char* legacyDefaultUrl;
+            AMediaDrm_getProvisionRequest(mDrm, &legacyRequest, &legacyRequestSize,
+                                          &legacyDefaultUrl);
+            break;
+        }
+        case 2: {  // provide a response to the DRM engine plugin
+            const int32_t provisionresponseSize = mFdp.ConsumeIntegralInRange<size_t>(
+                    kMinProvisionResponseSize, kMaxProvisionResponseSize);
+            uint8_t provisionResponse[provisionresponseSize];
+            AMediaDrm_provideProvisionResponse(mDrm, provisionResponse, sizeof(provisionResponse));
+            break;
+        }
+        case 3: {  // get key request
+            const uint8_t* keyRequest = nullptr;
+            size_t keyRequestSize = 0;
+            std::string mimeType = mFdp.ConsumeBool() ? mFdp.PickValueInArray(kMimeType)
+                                                      : mFdp.ConsumeRandomLengthString(kMaxBytes);
+            size_t numOptionalParameters =
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinParamVal, kMaxParamVal);
+            AMediaDrmKeyValue optionalParameters[numOptionalParameters];
+            std::string keys[numOptionalParameters];
+            std::string values[numOptionalParameters];
+            for (int i = 0; i < numOptionalParameters; ++i) {
+                keys[i] = mFdp.ConsumeRandomLengthString(kMaxBytes);
+                values[i] = mFdp.ConsumeRandomLengthString(kMaxBytes);
+                optionalParameters[i].mKey = keys[i].c_str();
+                optionalParameters[i].mValue = values[i].c_str();
+            }
+            AMediaDrmKeyType keyType = (AMediaDrmKeyType)mFdp.ConsumeIntegralInRange<int>(
+                    KEY_TYPE_STREAMING, KEY_TYPE_RELEASE);
+            AMediaDrm_getKeyRequest(mDrm, &mSessionId, kClearkeyPssh, sizeof(kClearkeyPssh),
+                                    mimeType.c_str(), keyType, optionalParameters,
+                                    numOptionalParameters, &keyRequest, &keyRequestSize);
+            break;
+        }
+        case 4: {  // query key status
+            size_t numPairs = mFdp.ConsumeIntegralInRange<size_t>(kMinParamVal, kMaxParamVal);
+            AMediaDrmKeyValue keyStatus[numPairs];
+            AMediaDrm_queryKeyStatus(mDrm, &mSessionId, keyStatus, &numPairs);
+            break;
+        }
+        case 5: {  // provide key response
+            std::string key = mFdp.ConsumeRandomLengthString(kMaxBytes);
+            const char* keyResponse = key.c_str();
+            AMediaDrmKeySetId keySetId;
+            AMediaDrm_provideKeyResponse(mDrm, &mSessionId,
+                                         reinterpret_cast<const uint8_t*>(keyResponse),
+                                         sizeof(keyResponse), &keySetId);
+            break;
+        }
+        case 6: {  // restore key
+            AMediaDrmKeySetId keySetId;
+            AMediaDrm_restoreKeys(mDrm, &mSessionId, &keySetId);
+            break;
+        }
+
+        case 7: {  // Check signature verification using the specified Algorithm
+            std::string algorithm = kMacAlgorithm[mFdp.ConsumeBool()];
+            std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> message = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            AMediaDrm_verify(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), message.data(),
+                             message.size(), signature, sizeof(signature));
+            break;
+        }
+        case 8: {  // Generate a signature using the specified Algorithm
+            std::string algorithm = kMacAlgorithm[mFdp.ConsumeBool()];
+            std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> message = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            size_t signatureSize = sizeof(signature);
+            AMediaDrm_sign(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), message.data(),
+                           message.size(), signature, &signatureSize);
+            break;
+        }
+        case 9: {  // Decrypt the data using algorithm
+            std::string algorithm = kCipherAlgorithm[mFdp.ConsumeBool()];
+            std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> iv = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> input = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            uint8_t output[kMessageSize];
+            AMediaDrm_decrypt(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), iv.data(),
+                              input.data(), output, input.size());
+            break;
+        }
+        case 10:
+        default: {  // Encrypt the data using algorithm
+            std::string algorithm = kCipherAlgorithm[mFdp.ConsumeBool()];
+            std::vector<uint8_t> keyId = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> iv = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            std::vector<uint8_t> input = mFdp.ConsumeBytes<uint8_t>(
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            uint8_t output[kMessageSize];
+            AMediaDrm_encrypt(mDrm, &mSessionId, algorithm.c_str(), keyId.data(), iv.data(),
+                              input.data(), output, input.size());
+            break;
+        }
+    }
+    AMediaDrm_removeKeys(mDrm, &mSessionId);
+}
+
+void NdkMediaDrmFuzzer::invokeNdkDrm() {
+    while (mFdp.remaining_bytes() > 0) {
+        // The API is called at start as it creates a AMediaDrm Object.
+        // mDrm AMediaDrm object is used in the below APIs.
+        invokeDrmCreatePlugin();
+        if (mDrm) {
+            // The API opens session and returns "mSessionId" session Id.
+            // "mSessionId" is required in the below APIs.
+            AMediaDrm_openSession(mDrm, &mSessionId);
+            int32_t ndkDrmAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPIcase, kMaxndkDrmAPIs);
+            switch (ndkDrmAPI) {
+                case 0: {
+                    invokeDrmDecryptEncryptAPI();
+                    break;
+                }
+                case 1: {
+                    invokeDrmPropertyAPI();
+                    break;
+                }
+                case 2: {
+                    invokeDrmSetListener();
+                    break;
+                }
+                case 3:
+                default: {
+                    invokeDrmSecureStopAPI();
+                    break;
+                }
+            }
+            AMediaDrm_closeSession(mDrm, &mSessionId);
+            AMediaDrm_release(mDrm);
+        }
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    NdkMediaDrmFuzzer ndkMediaDrmFuzzer(data, size);
+    ndkMediaDrmFuzzer.invokeNdkDrm();
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp b/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp
new file mode 100644
index 0000000..9bbb79c
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_extractor_fuzzer.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_process.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaExtractor.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+constexpr int32_t kCaseStart = 0;
+constexpr int32_t kCaseEnd = 8;
+constexpr float kMinDataSizeFactor = 0.5;
+constexpr int32_t kMaxIterations = 1000;
+const std::string kPathPrefix = "file://";
+
+constexpr SeekMode kSeekMode[] = {AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC,
+                                  AMEDIAEXTRACTOR_SEEK_NEXT_SYNC,
+                                  AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC};
+
+class NdkExtractorFuzzer {
+  public:
+    NdkExtractorFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+        mDataSourceFd = mkstemp(mTestPath);
+        std::vector<char> dataBuffer = mFdp.ConsumeBytes<char>(
+                mFdp.ConsumeIntegralInRange<int32_t>(kMinDataSizeFactor * size, size));
+        mDataSize = dataBuffer.size();
+        write(mDataSourceFd, dataBuffer.data(), dataBuffer.size());
+    };
+
+    ~NdkExtractorFuzzer() {
+        close(mDataSourceFd);
+        remove(mTestPath);
+    };
+
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+    int32_t mDataSourceFd = 0;
+    int32_t mDataSize = 0;
+
+    // Defined a mutable TestSource file path for mkstemp().
+    char mTestPath[64] = "/data/local/tmp/TestSource_XXXXXX";
+};
+
+void NdkExtractorFuzzer::process() {
+    AMediaExtractor* mMediaExtractor = AMediaExtractor_new();
+    AMediaDataSource* mDataSource = nullptr;
+
+    if (mFdp.ConsumeBool()) {
+        AMediaExtractor_setDataSourceFd(mMediaExtractor, mDataSourceFd, 0, mDataSize);
+    } else {
+        mDataSource = AMediaDataSource_newUri((kPathPrefix + mTestPath).c_str(), 0 /* numkeys */,
+                                              nullptr /* keyvalues */);
+        AMediaExtractor_setDataSourceCustom(mMediaExtractor, mDataSource);
+    }
+
+    /**
+     * Limiting the number of iterations of while loop
+     * to prevent a possible timeout.
+     */
+    int32_t count = 0;
+    while (mFdp.remaining_bytes() && count++ < kMaxIterations) {
+        switch (mFdp.ConsumeIntegralInRange<int32_t>(kCaseStart, kCaseEnd)) {
+            case 0:{
+                AMediaExtractor_selectTrack(mMediaExtractor,
+                                            mFdp.ConsumeIntegral<size_t>() /* idx */);
+                break;
+            }
+            case 1:{
+                AMediaExtractor_unselectTrack(mMediaExtractor,
+                                              mFdp.ConsumeIntegral<size_t>() /* idx */);
+                break;
+            }
+            case 2:{
+                int32_t sampleSize = AMediaExtractor_getSampleSize(mMediaExtractor);
+                if (sampleSize > 0) {
+                    std::vector<uint8_t> buffer(sampleSize);
+                    AMediaExtractor_readSampleData(
+                            mMediaExtractor, buffer.data(),
+                            mFdp.ConsumeIntegralInRange<size_t>(0, sampleSize) /* capacity */);
+                }
+                break;
+            }
+            case 3:{
+                AMediaExtractor_getSampleFlags(mMediaExtractor);
+                break;
+            }
+            case 4:{
+                AMediaExtractor_getSampleCryptoInfo(mMediaExtractor);
+                break;
+            }
+            case 5:{
+                AMediaExtractor_getPsshInfo(mMediaExtractor);
+                break;
+            }
+            case 6:{
+                AMediaExtractor_advance(mMediaExtractor);
+                break;
+            }
+            case 7:{
+                AMediaFormat* mediaFormat = mFdp.ConsumeBool() ? AMediaFormat_new() : nullptr;
+                AMediaExtractor_getSampleFormat(mMediaExtractor, mediaFormat);
+                AMediaFormat_delete(mediaFormat);
+                break;
+            }
+            case 8:{
+                AMediaExtractor_seekTo(mMediaExtractor,
+                                       mFdp.ConsumeIntegral<int64_t>() /* seekPosUs */,
+                                       mFdp.PickValueInArray(kSeekMode) /* mode */);
+                break;
+            }
+        };
+    }
+
+    AMediaDataSource_delete(mDataSource);
+    AMediaExtractor_delete(mMediaExtractor);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    /**
+     * Create a threadpool for incoming binder transactions,
+     * without this extractor results in a DoS after few instances.
+     */
+    ABinderProcess_startThreadPool();
+
+    NdkExtractorFuzzer ndkExtractorFuzzer(data, size);
+    ndkExtractorFuzzer.process();
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp b/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp
new file mode 100644
index 0000000..6c11798
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_image_reader_fuzzer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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 <cutils/native_handle.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gui/BufferQueue.h>
+#include <media/NdkImageReader.h>
+
+constexpr int32_t kMaxSize = INT_MAX;
+constexpr int32_t kMinSize = 1;
+constexpr int32_t kMinImages = 1;
+
+class NdkImageReaderFuzzer {
+  public:
+    NdkImageReaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+    static void onImageAvailable(void*, AImageReader*){};
+    static void onBufferRemoved(void*, AImageReader*, AHardwareBuffer*){};
+};
+
+void NdkImageReaderFuzzer::process() {
+    AImageReader* reader = nullptr;
+    AImage* img = nullptr;
+    native_handle_t* handle = nullptr;
+    int32_t* acquireFenceFd = nullptr;
+    int32_t imageWidth = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+    int32_t imageHeight = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+    int32_t imageFormat = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+    int32_t imageUsage = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+    int32_t imageMaxCount = mFdp.ConsumeIntegralInRange<int32_t>(
+            kMinImages, android::BufferQueue::MAX_MAX_ACQUIRED_BUFFERS);
+    AImageReader_ImageListener readerAvailableCb{this, NdkImageReaderFuzzer::onImageAvailable};
+    AImageReader_BufferRemovedListener readerDetachedCb{this, onBufferRemoved};
+
+    if (mFdp.ConsumeBool()) {
+        AImageReader_new(imageWidth, imageHeight, imageFormat, imageMaxCount, &reader);
+    } else {
+        AImageReader_newWithUsage(imageWidth, imageHeight, imageFormat, imageUsage, imageMaxCount,
+                                  &reader);
+    }
+    while (mFdp.remaining_bytes()) {
+        auto ndkImageFunction = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() { AImageReader_acquireNextImage(reader, &img); },
+                [&]() { AImageReader_acquireLatestImage(reader, &img); },
+                [&]() { AImageReader_setImageListener(reader, &readerAvailableCb); },
+                [&]() { AImageReader_acquireNextImageAsync(reader, &img, acquireFenceFd); },
+                [&]() { AImageReader_acquireLatestImageAsync(reader, &img, acquireFenceFd); },
+                [&]() { AImageReader_setBufferRemovedListener(reader, &readerDetachedCb); },
+                [&]() { AImageReader_getWindowNativeHandle(reader, &handle); },
+        });
+        ndkImageFunction();
+    }
+    AImageReader_delete(reader);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    NdkImageReaderFuzzer ndkImageReaderFuzzer(data, size);
+    ndkImageReaderFuzzer.process();
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
new file mode 100644
index 0000000..a428b57
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2022 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 <datasource/FileSource.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaFormat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <fstream>
+
+const char* kValidKeys[] = {
+        AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
+        AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
+        AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
+        AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
+        AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
+        AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
+        AMEDIAFORMAT_KEY_AAC_PROFILE,
+        AMEDIAFORMAT_KEY_AAC_SBR_MODE,
+        AMEDIAFORMAT_KEY_ALBUM,
+        AMEDIAFORMAT_KEY_ALBUMART,
+        AMEDIAFORMAT_KEY_ALBUMARTIST,
+        AMEDIAFORMAT_KEY_ARTIST,
+        AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
+        AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID,
+        AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID,
+        AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
+        AMEDIAFORMAT_KEY_AUTHOR,
+        AMEDIAFORMAT_KEY_BITRATE_MODE,
+        AMEDIAFORMAT_KEY_BIT_RATE,
+        AMEDIAFORMAT_KEY_BITS_PER_SAMPLE,
+        AMEDIAFORMAT_KEY_CAPTURE_RATE,
+        AMEDIAFORMAT_KEY_CDTRACKNUMBER,
+        AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+        AMEDIAFORMAT_KEY_CHANNEL_MASK,
+        AMEDIAFORMAT_KEY_COLOR_FORMAT,
+        AMEDIAFORMAT_KEY_COLOR_RANGE,
+        AMEDIAFORMAT_KEY_COLOR_STANDARD,
+        AMEDIAFORMAT_KEY_COLOR_TRANSFER,
+        AMEDIAFORMAT_KEY_COMPILATION,
+        AMEDIAFORMAT_KEY_COMPLEXITY,
+        AMEDIAFORMAT_KEY_COMPOSER,
+        AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
+        AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+        AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+        AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+        AMEDIAFORMAT_KEY_CRYPTO_IV,
+        AMEDIAFORMAT_KEY_CRYPTO_KEY,
+        AMEDIAFORMAT_KEY_CRYPTO_MODE,
+        AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+        AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
+        AMEDIAFORMAT_KEY_CSD,
+        AMEDIAFORMAT_KEY_CSD_0,
+        AMEDIAFORMAT_KEY_CSD_1,
+        AMEDIAFORMAT_KEY_CSD_2,
+        AMEDIAFORMAT_KEY_CSD_AVC,
+        AMEDIAFORMAT_KEY_CSD_HEVC,
+        AMEDIAFORMAT_KEY_D263,
+        AMEDIAFORMAT_KEY_DATE,
+        AMEDIAFORMAT_KEY_DISCNUMBER,
+        AMEDIAFORMAT_KEY_DISPLAY_CROP,
+        AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
+        AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
+        AMEDIAFORMAT_KEY_DURATION,
+        AMEDIAFORMAT_KEY_ENCODER_DELAY,
+        AMEDIAFORMAT_KEY_ENCODER_PADDING,
+        AMEDIAFORMAT_KEY_ESDS,
+        AMEDIAFORMAT_KEY_EXIF_OFFSET,
+        AMEDIAFORMAT_KEY_EXIF_SIZE,
+        AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
+        AMEDIAFORMAT_KEY_FRAME_COUNT,
+        AMEDIAFORMAT_KEY_FRAME_RATE,
+        AMEDIAFORMAT_KEY_GENRE,
+        AMEDIAFORMAT_KEY_GRID_COLUMNS,
+        AMEDIAFORMAT_KEY_GRID_ROWS,
+        AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
+        AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
+        AMEDIAFORMAT_KEY_HDR10_PLUS_INFO,
+        AMEDIAFORMAT_KEY_HEIGHT,
+        AMEDIAFORMAT_KEY_ICC_PROFILE,
+        AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
+        AMEDIAFORMAT_KEY_IS_ADTS,
+        AMEDIAFORMAT_KEY_IS_AUTOSELECT,
+        AMEDIAFORMAT_KEY_IS_DEFAULT,
+        AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
+        AMEDIAFORMAT_KEY_IS_SYNC_FRAME,
+        AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+        AMEDIAFORMAT_KEY_LANGUAGE,
+        AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK,
+        AMEDIAFORMAT_KEY_LATENCY,
+        AMEDIAFORMAT_KEY_LEVEL,
+        AMEDIAFORMAT_KEY_LOCATION,
+        AMEDIAFORMAT_KEY_LOOP,
+        AMEDIAFORMAT_KEY_LOW_LATENCY,
+        AMEDIAFORMAT_KEY_LYRICIST,
+        AMEDIAFORMAT_KEY_MANUFACTURER,
+        AMEDIAFORMAT_KEY_MAX_BIT_RATE,
+        AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
+        AMEDIAFORMAT_KEY_MAX_HEIGHT,
+        AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
+        AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
+        AMEDIAFORMAT_KEY_MAX_WIDTH,
+        AMEDIAFORMAT_KEY_MIME,
+        AMEDIAFORMAT_KEY_MPEG_USER_DATA,
+        AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER,
+        AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
+        AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
+        AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
+        AMEDIAFORMAT_KEY_OPERATING_RATE,
+        AMEDIAFORMAT_KEY_PCM_ENCODING,
+        AMEDIAFORMAT_KEY_PICTURE_TYPE,
+        AMEDIAFORMAT_KEY_PRIORITY,
+        AMEDIAFORMAT_KEY_PROFILE,
+        AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN,
+        AMEDIAFORMAT_KEY_PSSH,
+        AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
+        AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
+        AMEDIAFORMAT_KEY_ROTATION,
+        AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET,
+        AMEDIAFORMAT_KEY_SAMPLE_RATE,
+        AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND,
+        AMEDIAFORMAT_KEY_SAR_HEIGHT,
+        AMEDIAFORMAT_KEY_SAR_WIDTH,
+        AMEDIAFORMAT_KEY_SEI,
+        AMEDIAFORMAT_KEY_SLICE_HEIGHT,
+        AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS,
+        AMEDIAFORMAT_KEY_STRIDE,
+        AMEDIAFORMAT_KEY_TARGET_TIME,
+        AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT,
+        AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
+        AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
+        AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C,
+        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+        AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT,
+        AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
+        AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH,
+        AMEDIAFORMAT_KEY_TILE_HEIGHT,
+        AMEDIAFORMAT_KEY_TILE_WIDTH,
+        AMEDIAFORMAT_KEY_TIME_US,
+        AMEDIAFORMAT_KEY_TITLE,
+        AMEDIAFORMAT_KEY_TRACK_ID,
+        AMEDIAFORMAT_KEY_TRACK_INDEX,
+        AMEDIAFORMAT_KEY_VALID_SAMPLES,
+        AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL,
+        AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE,
+        AMEDIAFORMAT_VIDEO_QP_B_MAX,
+        AMEDIAFORMAT_VIDEO_QP_B_MIN,
+        AMEDIAFORMAT_VIDEO_QP_I_MAX,
+        AMEDIAFORMAT_VIDEO_QP_I_MIN,
+        AMEDIAFORMAT_VIDEO_QP_MAX,
+        AMEDIAFORMAT_VIDEO_QP_MIN,
+        AMEDIAFORMAT_VIDEO_QP_P_MAX,
+        AMEDIAFORMAT_VIDEO_QP_P_MIN,
+        AMEDIAFORMAT_KEY_WIDTH,
+        AMEDIAFORMAT_KEY_XMP_OFFSET,
+        AMEDIAFORMAT_KEY_XMP_SIZE,
+        AMEDIAFORMAT_KEY_YEAR,
+};
+constexpr size_t kMinBytes = 0;
+constexpr size_t kMaxBytes = 1000;
+constexpr size_t kMinChoice = 0;
+constexpr size_t kMaxChoice = 9;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+    AMediaFormat* mediaFormat = AMediaFormat_new();
+    while (fdp.remaining_bytes()) {
+        const char* name = nullptr;
+        if (fdp.ConsumeBool()) {
+            std::string nameString =
+                    fdp.ConsumeBool()
+                            ? fdp.PickValueInArray(kValidKeys)
+                            : fdp.ConsumeRandomLengthString(
+                                      fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+            name = nameString.c_str();
+        }
+        switch (fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice)) {
+            case 0: {
+                AMediaFormat_setInt32(mediaFormat, name,
+                                      fdp.ConsumeIntegral<int32_t>() /* value */);
+                break;
+            }
+            case 1: {
+                AMediaFormat_setInt64(mediaFormat, name,
+                                      fdp.ConsumeIntegral<int64_t>() /* value */);
+                break;
+            }
+            case 2: {
+                AMediaFormat_setFloat(mediaFormat, name,
+                                      fdp.ConsumeFloatingPoint<float>() /* value */);
+                break;
+            }
+            case 3: {
+                AMediaFormat_setDouble(mediaFormat, name,
+                                       fdp.ConsumeFloatingPoint<double>() /* value */);
+                break;
+            }
+            case 4: {
+                AMediaFormat_setSize(mediaFormat, name, fdp.ConsumeIntegral<size_t>() /* value */);
+                break;
+            }
+            case 5: {
+                std::string value;
+                if (fdp.ConsumeBool()) {
+                    value = fdp.ConsumeRandomLengthString(
+                            fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+                }
+                AMediaFormat_setString(mediaFormat, name,
+                                       fdp.ConsumeBool() ? nullptr : value.c_str());
+                break;
+            }
+            case 6: {
+                AMediaFormat_setRect(mediaFormat, name, fdp.ConsumeIntegral<int32_t>() /* left */,
+                                     fdp.ConsumeIntegral<int32_t>() /* top */,
+                                     fdp.ConsumeIntegral<int32_t>() /* bottom */,
+                                     fdp.ConsumeIntegral<int32_t>() /* right */);
+                break;
+            }
+            case 7: {
+                std::vector<uint8_t> bufferData = fdp.ConsumeBytes<uint8_t>(
+                        fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+                AMediaFormat_setBuffer(mediaFormat, name, bufferData.data(), bufferData.size());
+                break;
+            }
+            case 8: {
+                AMediaFormat_toString(mediaFormat);
+                break;
+            }
+            default: {
+                AMediaFormat* format = fdp.ConsumeBool() ? nullptr : AMediaFormat_new();
+                AMediaFormat_copy(format, mediaFormat);
+                AMediaFormat_delete(format);
+                break;
+            }
+        }
+    }
+    AMediaFormat_clear(mediaFormat);
+    AMediaFormat_delete(mediaFormat);
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp
new file mode 100644
index 0000000..8c49d28
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_mediamuxer_fuzzer.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_process.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/NdkMediaMuxer.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+const std::string kMuxerFile = "mediaMuxer";
+const std::string kAppendFile = "mediaAppend";
+constexpr size_t kMinBytes = 0;
+constexpr size_t kMaxBytes = 1000;
+constexpr size_t kMinChoice = 0;
+constexpr size_t kMaxChoice = 7;
+constexpr size_t kMaxStringLength = 20;
+constexpr size_t kOffset = 0;
+
+constexpr OutputFormat kOutputFormat[] = {AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4,
+                                          AMEDIAMUXER_OUTPUT_FORMAT_WEBM,
+                                          AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP};
+constexpr AppendMode kAppendMode[] = {AMEDIAMUXER_APPEND_IGNORE_LAST_VIDEO_GOP,
+                                      AMEDIAMUXER_APPEND_TO_EXISTING_DATA};
+
+const std::string kAudioMimeType[] = {"audio/3gpp", "audio/amr-wb", "audio/mp4a-latm",
+                                      "audio/flac", "audio/vorbis", "audio/opus"};
+
+const std::string kVideoMimeType[] = {"video/x-vnd.on2.vp8", "video/x-vnd.on2.vp9", "video/av01",
+                                      "video/avc",           "video/hevc",          "video/mp4v-es",
+                                      "video/3gpp"};
+
+void getSampleAudioFormat(FuzzedDataProvider& fdp, AMediaFormat* format) {
+    std::string mimeType = fdp.ConsumeBool() ? fdp.ConsumeRandomLengthString(kMaxStringLength)
+                                             : fdp.PickValueInArray(kAudioMimeType);
+    AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mimeType.c_str());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt64(format, AMEDIAFORMAT_KEY_DURATION, fdp.ConsumeIntegral<int64_t>());
+}
+
+void getSampleVideoFormat(FuzzedDataProvider& fdp, AMediaFormat* format) {
+    std::string mimeType = fdp.ConsumeBool() ? fdp.ConsumeRandomLengthString(kMaxStringLength)
+                                             : fdp.PickValueInArray(kAudioMimeType);
+    AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mimeType.c_str());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, fdp.ConsumeIntegral<int32_t>());
+    AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+                          fdp.ConsumeFloatingPoint<float>());
+    AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_CAPTURE_RATE, fdp.ConsumeFloatingPoint<float>());
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, fdp.ConsumeIntegral<int32_t>());
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    /**
+     * Create a threadpool for incoming binder transactions,
+     * without this muxer results in a DoS after few instances.
+     */
+    ABinderProcess_startThreadPool();
+    FuzzedDataProvider fdp(data, size);
+    /**
+     * memfd_create() creates an anonymous file and returns a file
+     * descriptor that refers to it. MFD_ALLOW_SEALING allow sealing
+     * operations on this file.
+     */
+    int32_t fd = -1;
+    AMediaMuxer* muxer = nullptr;
+    if (fdp.ConsumeBool()) {
+        fd = memfd_create(kMuxerFile.c_str(), MFD_ALLOW_SEALING);
+        muxer = AMediaMuxer_new(fd, fdp.ConsumeBool()
+                                            ? fdp.PickValueInArray(kOutputFormat)
+                                            : (OutputFormat)fdp.ConsumeIntegral<int32_t>());
+    } else {
+        fd = memfd_create(kAppendFile.c_str(), MFD_ALLOW_SEALING);
+        std::vector<uint8_t> appendData =
+                fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+        write(fd, appendData.data(), appendData.size());
+        muxer = AMediaMuxer_append(fd, fdp.PickValueInArray(kAppendMode) /* mode */);
+    }
+    if (!muxer) {
+        close(fd);
+        return 0;
+    }
+    AMediaFormat* mediaFormat = nullptr;
+    ssize_t trackIdx = 0;
+    while (fdp.remaining_bytes()) {
+        int32_t kSwitchChoice = fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice);
+        switch (kSwitchChoice) {
+            case 0: {
+                AMediaMuxer_setLocation(muxer, fdp.ConsumeFloatingPoint<float>() /* latitude */,
+                                        fdp.ConsumeFloatingPoint<float>() /* longitude */);
+                break;
+            }
+            case 1: {
+                AMediaMuxer_setOrientationHint(muxer, fdp.ConsumeIntegral<int32_t>() /* degrees */);
+                break;
+            }
+            case 2: {
+                AMediaMuxer_start(muxer);
+                break;
+            }
+            case 3: {
+                AMediaMuxer_stop(muxer);
+                break;
+            }
+            case 4: {
+                AMediaMuxer_getTrackCount(muxer);
+                break;
+            }
+            case 5: {
+                AMediaFormat* getFormat =
+                        AMediaMuxer_getTrackFormat(muxer, fdp.ConsumeIntegral<size_t>() /* idx */);
+                AMediaFormat_delete(getFormat);
+                break;
+            }
+            case 6: {
+                mediaFormat = AMediaFormat_new();
+                fdp.ConsumeBool() ? getSampleAudioFormat(fdp, mediaFormat)
+                                  : getSampleVideoFormat(fdp, mediaFormat);
+                trackIdx = AMediaMuxer_addTrack(muxer, mediaFormat);
+                AMediaFormat_delete(mediaFormat);
+                break;
+            }
+            default: {
+                std::vector<uint8_t> sampleData = fdp.ConsumeBytes<uint8_t>(
+                        fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+                AMediaCodecBufferInfo codecBuffer;
+                codecBuffer.size = sampleData.size();
+                codecBuffer.offset = kOffset;
+                codecBuffer.presentationTimeUs = fdp.ConsumeIntegral<int64_t>();
+                codecBuffer.flags = fdp.ConsumeIntegral<uint32_t>();
+                AMediaMuxer_writeSampleData(
+                        muxer,
+                        fdp.ConsumeBool() ? trackIdx : fdp.ConsumeIntegral<size_t>() /* trackIdx */,
+                        sampleData.data(), &codecBuffer);
+                break;
+            }
+        }
+    }
+    AMediaMuxer_delete(muxer);
+    close(fd);
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp b/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp
new file mode 100644
index 0000000..a3f3650
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_sync_codec_fuzzer.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 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 <NdkMediaCodecFuzzerBase.h>
+
+constexpr int32_t kMaxNdkCodecAPIs = 12;
+
+class NdkSyncCodecFuzzer : public NdkMediaCodecFuzzerBase {
+  public:
+    NdkSyncCodecFuzzer(const uint8_t* data, size_t size)
+        : NdkMediaCodecFuzzerBase(), mFdp(data, size) {
+        setFdp(&mFdp);
+    };
+    void invokeSyncCodeConfigAPI();
+
+    static void CodecOnFrameRendered(AMediaCodec* codec, void* userdata, int64_t mediaTimeUs,
+                                     int64_t systemNano) {
+        (void)codec;
+        (void)userdata;
+        (void)mediaTimeUs;
+        (void)systemNano;
+    };
+
+  private:
+    FuzzedDataProvider mFdp;
+    AMediaCodec* mCodec = nullptr;
+    void invokekSyncCodecAPIs(bool isEncoder);
+};
+
+void NdkSyncCodecFuzzer::invokekSyncCodecAPIs(bool isEncoder) {
+    ANativeWindow* nativeWindow = nullptr;
+    AMediaFormat* format = getCodecFormat();
+    int32_t numOfFrames = mFdp.ConsumeIntegralInRange<size_t>(kMinIterations, kMaxIterations);
+    int32_t count = 0;
+    while (++count <= numOfFrames) {
+        int32_t ndkcodecAPI = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxNdkCodecAPIs);
+        switch (ndkcodecAPI) {
+            case 0: {  // configure the codec
+                AMediaCodec_configure(mCodec, format, nativeWindow, nullptr /* crypto */,
+                                      (isEncoder ? AMEDIACODEC_CONFIGURE_FLAG_ENCODE : 0));
+                break;
+            }
+            case 1: {  // start codec
+                AMediaCodec_start(mCodec);
+                break;
+            }
+            case 2: {  // stop codec
+                AMediaCodec_stop(mCodec);
+                break;
+            }
+            case 3: {  // create persistent input surface
+                AMediaCodec_createPersistentInputSurface(&nativeWindow);
+                break;
+            }
+            case 4: {  // buffer operation APIs
+                invokeInputBufferOperationAPI(mCodec);
+                break;
+            }
+            case 5: {
+                invokeOutputBufferOperationAPI(mCodec);
+                break;
+            }
+            case 6: {  // get input and output Format
+                invokeCodecFormatAPI(mCodec);
+                break;
+            }
+            case 7: {
+                AMediaCodec_signalEndOfInputStream(mCodec);
+                break;
+            }
+            case 8: {  // set parameters
+                // Create a new parameter and set
+                AMediaFormat* params = AMediaFormat_new();
+                AMediaFormat_setInt32(
+                        params, "video-bitrate",
+                        mFdp.ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue));
+                AMediaCodec_setParameters(mCodec, params);
+                AMediaFormat_delete(params);
+                break;
+            }
+            case 9: {  // flush codec
+                AMediaCodec_flush(mCodec);
+                if (mFdp.ConsumeBool()) {
+                    AMediaCodec_start(mCodec);
+                }
+                break;
+            }
+            case 10: {  // get the codec name
+                char* name = nullptr;
+                AMediaCodec_getName(mCodec, &name);
+                AMediaCodec_releaseName(mCodec, name);
+                break;
+            }
+            case 11: {  // set callback API for frame render output
+                std::vector<uint8_t> userData = mFdp.ConsumeBytes<uint8_t>(
+                        mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+                AMediaCodecOnFrameRendered callback = CodecOnFrameRendered;
+                AMediaCodec_setOnFrameRenderedCallback(mCodec, callback, userData.data());
+                break;
+            }
+            case 12:
+            default: {  // set persistent input surface
+                AMediaCodec_setInputSurface(mCodec, nativeWindow);
+            }
+        }
+    }
+    if (nativeWindow) {
+        ANativeWindow_release(nativeWindow);
+    }
+    if (format) {
+        AMediaFormat_delete(format);
+    }
+}
+
+void NdkSyncCodecFuzzer::invokeSyncCodeConfigAPI() {
+    while (mFdp.remaining_bytes() > 0) {
+        bool isEncoder = mFdp.ConsumeBool();
+        mCodec = createCodec(isEncoder, mFdp.ConsumeBool() /* isCodecForClient */);
+        if (mCodec) {
+            invokekSyncCodecAPIs(isEncoder);
+            AMediaCodec_delete(mCodec);
+        }
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    NdkSyncCodecFuzzer ndkSyncCodecFuzzer(data, size);
+    ndkSyncCodecFuzzer.invokeSyncCodeConfigAPI();
+    return 0;
+}
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
index 40a8c9e..ba3e81a 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.h
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -50,7 +50,7 @@
         {
             lock_guard<mutex> lock(mMutex);
             needsNotify = mQueue.empty();
-            mQueue.push(move(elem));
+            mQueue.push(std::move(elem));
         }
         if (needsNotify) mQueueNotEmptyCondition.notify_one();
     }
diff --git a/services/OWNERS b/services/OWNERS
deleted file mode 100644
index 17e605d..0000000
--- a/services/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-elaurent@google.com
-essick@google.com
-etalvala@google.com
-hunga@google.com
-nchalko@google.com
-quxiangfang@google.com
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a68f63e..7f0fc1f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -597,6 +597,11 @@
                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
                                                     AUDIO_OUTPUT_FLAG_DIRECT),
                                             deviceId, &portId, &secondaryOutputs, &isSpatialized);
+        if (ret != NO_ERROR) {
+            config->sample_rate = fullConfig.sample_rate;
+            config->channel_mask = fullConfig.channel_mask;
+            config->format = fullConfig.format;
+        }
         ALOGW_IF(!secondaryOutputs.empty(),
                  "%s does not support secondary outputs, ignoring them", __func__);
     } else {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 496591a..c4c27e8 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -134,17 +134,17 @@
     // request an output appropriate for playback of the supplied stream type and parameters
     virtual audio_io_handle_t getOutput(audio_stream_type_t stream) = 0;
     virtual status_t getOutputForAttr(const audio_attributes_t *attr,
-                                        audio_io_handle_t *output,
-                                        audio_session_t session,
-                                        audio_stream_type_t *stream,
-                                        const AttributionSourceState& attributionSouce,
-                                        const audio_config_t *config,
-                                        audio_output_flags_t *flags,
-                                        audio_port_handle_t *selectedDeviceId,
-                                        audio_port_handle_t *portId,
-                                        std::vector<audio_io_handle_t> *secondaryOutputs,
-                                        output_type_t *outputType,
-                                        bool *isSpatialized) = 0;
+                                      audio_io_handle_t *output,
+                                      audio_session_t session,
+                                      audio_stream_type_t *stream,
+                                      const AttributionSourceState& attributionSouce,
+                                      audio_config_t *config,
+                                      audio_output_flags_t *flags,
+                                      audio_port_handle_t *selectedDeviceId,
+                                      audio_port_handle_t *portId,
+                                      std::vector<audio_io_handle_t> *secondaryOutputs,
+                                      output_type_t *outputType,
+                                      bool *isSpatialized) = 0;
     // indicates to the audio policy manager that the output starts being used by corresponding
     // stream.
     virtual status_t startOutput(audio_port_handle_t portId) = 0;
@@ -160,7 +160,7 @@
                                      audio_unique_id_t riid,
                                      audio_session_t session,
                                      const AttributionSourceState& attributionSouce,
-                                     const audio_config_base_t *config,
+                                     audio_config_base_t *config,
                                      audio_input_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId,
                                      input_type_t *inputType,
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 90b812d..37443ab 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -97,6 +97,25 @@
                              uint32_t flags,
                              bool exactMatchRequiredForInputFlags = false) const;
 
+    /**
+     * @brief areAllDevicesSupported: Checks if the given devices are supported by the IO profile.
+     *
+     * @param devices vector of devices to be checked for compatibility
+     * @return true if all devices are supported, false otherwise.
+     */
+    bool areAllDevicesSupported(const DeviceVector &devices) const;
+
+    /**
+     * @brief isCompatibleProfileForFlags: Checks if the IO profile is compatible with
+     * specified flags.
+     *
+     * @param flags to be checked for compatibility
+     * @param exactMatchRequiredForInputFlags true if exact match is required on flags
+     * @return true if the profile is compatible, false otherwise.
+     */
+    bool isCompatibleProfileForFlags(uint32_t flags,
+                                     bool exactMatchRequiredForInputFlags = false) const;
+
     void dump(String8 *dst, int spaces) const;
     void log();
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index 21f2018..7b4cecf 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -40,11 +40,9 @@
     const bool isRecordThread =
             getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK;
     ALOG_ASSERT(isPlaybackThread != isRecordThread);
-
-    if (!devices.isEmpty()) {
-        if (!mSupportedDevices.containsAllDevices(devices)) {
-            return false;
-        }
+    if (!areAllDevicesSupported(devices) ||
+            !isCompatibleProfileForFlags(flags, exactMatchRequiredForInputFlags)) {
+        return false;
     }
 
     if (!audio_is_valid_format(format) ||
@@ -78,6 +76,33 @@
         }
     }
 
+    if (updatedSamplingRate != NULL) {
+        *updatedSamplingRate = myUpdatedSamplingRate;
+    }
+    if (updatedFormat != NULL) {
+        *updatedFormat = myUpdatedFormat;
+    }
+    if (updatedChannelMask != NULL) {
+        *updatedChannelMask = myUpdatedChannelMask;
+    }
+    return true;
+}
+
+bool IOProfile::areAllDevicesSupported(const DeviceVector &devices) const {
+    if (devices.empty()) {
+        return true;
+    }
+    return mSupportedDevices.containsAllDevices(devices);
+}
+
+bool IOProfile::isCompatibleProfileForFlags(uint32_t flags,
+                                            bool exactMatchRequiredForInputFlags) const {
+    const bool isPlaybackThread =
+            getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SOURCE;
+    const bool isRecordThread =
+            getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK;
+    ALOG_ASSERT(isPlaybackThread != isRecordThread);
+
     const uint32_t mustMatchOutputFlags =
             AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
     if (isPlaybackThread && (((getFlags() ^ flags) & mustMatchOutputFlags)
@@ -93,15 +118,6 @@
         return false;
     }
 
-    if (updatedSamplingRate != NULL) {
-        *updatedSamplingRate = myUpdatedSamplingRate;
-    }
-    if (updatedFormat != NULL) {
-        *updatedFormat = myUpdatedFormat;
-    }
-    if (updatedChannelMask != NULL) {
-        *updatedChannelMask = myUpdatedChannelMask;
-    }
     return true;
 }
 
diff --git a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
index c3b19c2..c453dea 100644
--- a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
+++ b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
@@ -12,6 +12,7 @@
         </mixPort>
         <!-- Le Audio Audio Ports -->
         <mixPort name="le audio output" role="source" />
+        <mixPort name="le audio broadcast output" role="source" />
         <mixPort name="le audio input" role="sink">
             <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                      samplingRates="8000 16000 24000 32000 44100 48000"
@@ -65,6 +66,6 @@
         <route type="mix" sink="BLE Speaker Out"
                sources="le audio output"/>
         <route type="mix" sink="BLE Broadcast Out"
-               sources="le audio output"/>
+               sources="le audio broadcast output"/>
     </routes>
 </module>
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c21c6a2..4a62eda 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1132,7 +1132,7 @@
         const audio_attributes_t *attr,
         audio_stream_type_t *stream,
         uid_t uid,
-        const audio_config_t *config,
+        audio_config_t *config,
         audio_output_flags_t *flags,
         audio_port_handle_t *selectedDeviceId,
         bool *isRequestedDeviceForExclusiveUse,
@@ -1273,6 +1273,15 @@
                 flags, isSpatialized, resultAttr->flags & AUDIO_FLAG_MUTE_HAPTIC);
     }
     if (*output == AUDIO_IO_HANDLE_NONE) {
+        AudioProfileVector profiles;
+        status_t ret = getProfilesForDevices(outputDevices, profiles, *flags, false /*isInput*/);
+        if (ret == NO_ERROR && !profiles.empty()) {
+            config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
+                    : *profiles[0]->getChannels().begin();
+            config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
+                    : *profiles[0]->getSampleRates().begin();
+            config->format = profiles[0]->getFormat();
+        }
         return INVALID_OPERATION;
     }
 
@@ -1300,7 +1309,7 @@
                                               audio_session_t session,
                                               audio_stream_type_t *stream,
                                               const AttributionSourceState& attributionSource,
-                                              const audio_config_t *config,
+                                              audio_config_t *config,
                                               audio_output_flags_t *flags,
                                               audio_port_handle_t *selectedDeviceId,
                                               audio_port_handle_t *portId,
@@ -2412,7 +2421,7 @@
                                              audio_unique_id_t riid,
                                              audio_session_t session,
                                              const AttributionSourceState& attributionSource,
-                                             const audio_config_base_t *config,
+                                             audio_config_base_t *config,
                                              audio_input_flags_t flags,
                                              audio_port_handle_t *selectedDeviceId,
                                              input_type_t *inputType,
@@ -2553,6 +2562,16 @@
     *input = getInputForDevice(device, session, attributes, config, flags, policyMix);
     if (*input == AUDIO_IO_HANDLE_NONE) {
         status = INVALID_OPERATION;
+        AudioProfileVector profiles;
+        status_t ret = getProfilesForDevices(
+                DeviceVector(device), profiles, flags, true /*isInput*/);
+        if (ret == NO_ERROR && !profiles.empty()) {
+            config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
+                    : *profiles[0]->getChannels().begin();
+            config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
+                    : *profiles[0]->getSampleRates().begin();
+            config->format = profiles[0]->getFormat();
+        }
         goto error;
     }
 
@@ -2584,7 +2603,7 @@
 audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescriptor> &device,
                                                         audio_session_t session,
                                                         const audio_attributes_t &attributes,
-                                                        const audio_config_base_t *config,
+                                                        audio_config_base_t *config,
                                                         audio_input_flags_t flags,
                                                         const sp<AudioPolicyMix> &policyMix)
 {
@@ -4085,8 +4104,8 @@
 
 status_t AudioPolicyManager::getDirectProfilesForAttributes(const audio_attributes_t* attr,
                                                 AudioProfileVector& audioProfilesVector) {
-    AudioDeviceTypeAddrVector devices;
-    status_t status = getDevicesForAttributes(*attr, &devices, false /* forVolume */);
+    DeviceVector devices;
+    status_t status = getDevicesForAttributes(*attr, devices, false /* forVolume */);
     if (status != OK) {
         return status;
     }
@@ -4094,44 +4113,8 @@
     if (devices.empty()) {
         return OK; // no output devices for the attributes
     }
-
-    for (const auto& hwModule : mHwModules) {
-        // the MSD module checks for different conditions
-        if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
-            continue;
-        }
-        for (const auto& outputProfile : hwModule->getOutputProfiles()) {
-            if (!outputProfile->asAudioPort()->isDirectOutput()) {
-                continue;
-            }
-            // allow only profiles that support all the available and routed devices
-            if (outputProfile->getSupportedDevices().getDevicesFromDeviceTypeAddrVec(devices).size()
-                    != devices.size()) {
-                continue;
-            }
-            audioProfilesVector.addAllValidProfiles(
-                    outputProfile->asAudioPort()->getAudioProfiles());
-        }
-    }
-
-    // add the direct profiles from MSD if present and has audio patches to all the output(s)
-    const auto& msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
-    if (msdModule != nullptr) {
-        if (msdHasPatchesToAllDevices(devices)) {
-            ALOGV("%s: MSD audio patches set to all output devices.", __func__);
-            for (const auto& outputProfile : msdModule->getOutputProfiles()) {
-                if (!outputProfile->asAudioPort()->isDirectOutput()) {
-                    continue;
-                }
-                audioProfilesVector.addAllValidProfiles(
-                        outputProfile->asAudioPort()->getAudioProfiles());
-            }
-        } else {
-            ALOGV("%s: MSD audio patches NOT set to all output devices.", __func__);
-        }
-    }
-
-    return NO_ERROR;
+    return getProfilesForDevices(devices, audioProfilesVector,
+                                 AUDIO_OUTPUT_FLAG_DIRECT /*flags*/, false /*isInput*/);
 }
 
 status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
@@ -6680,70 +6663,15 @@
     return (stream1 == stream2);
 }
 
-// TODO - consider MSD routes b/214971780
 status_t AudioPolicyManager::getDevicesForAttributes(
         const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices, bool forVolume) {
     if (devices == nullptr) {
         return BAD_VALUE;
     }
 
-    // Devices are determined in the following precedence:
-    //
-    // 1) Devices associated with a dynamic policy matching the attributes.  This is often
-    //    a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
-    //
-    // If no such dynamic policy then
-    // 2) Devices containing an active client using setPreferredDevice
-    //    with same strategy as the attributes.
-    //    (from the default Engine::getOutputDevicesForAttributes() implementation).
-    //
-    // If no corresponding active client with setPreferredDevice then
-    // 3) Devices associated with the strategy determined by the attributes
-    //    (from the default Engine::getOutputDevicesForAttributes() implementation).
-    //
-    // See related getOutputForAttrInt().
-
-    // check dynamic policies but only for primary descriptors (secondary not used for audible
-    // audio routing, only used for duplication for playback capture)
-    sp<AudioPolicyMix> policyMix;
-    status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
-            0 /*uid unknown here*/, AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr);
-    if (status != OK) {
-        return status;
-    }
-
     DeviceVector curDevices;
-    if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
-            // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
-            // as they are unaffected by device/stream volume
-            // (per SwAudioOutputDescriptor::isFixedVolume()).
-            (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
-            ) {
-        sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
-                policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
-        curDevices.add(deviceDesc);
-    } else {
-        // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
-        // which selects setPreferredDevice if active.  This means forVolume call
-        // will take an active setPreferredDevice, if such exists.
-
-        curDevices = mEngine->getOutputDevicesForAttributes(
-                attr, nullptr /* preferredDevice */, false /* fromCache */);
-    }
-
-    if (forVolume) {
-        // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
-        // for single volume control in AudioService (such relationship should exist if
-        // SPEAKER_SAFE is present).
-        //
-        // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
-        DeviceVector speakerSafeDevices =
-                curDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
-        if (!speakerSafeDevices.isEmpty()) {
-            curDevices.merge(
-                    mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
-            curDevices.remove(speakerSafeDevices);
-        }
+    if (status_t status = getDevicesForAttributes(attr, curDevices, forVolume); status != OK) {
+        return status;
     }
     for (const auto& device : curDevices) {
         devices->push_back(device->getDeviceTypeAddr());
@@ -7897,4 +7825,109 @@
     return desc;
 }
 
+status_t AudioPolicyManager::getDevicesForAttributes(
+        const audio_attributes_t &attr, DeviceVector &devices, bool forVolume) {
+    // Devices are determined in the following precedence:
+    //
+    // 1) Devices associated with a dynamic policy matching the attributes.  This is often
+    //    a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
+    //
+    // If no such dynamic policy then
+    // 2) Devices containing an active client using setPreferredDevice
+    //    with same strategy as the attributes.
+    //    (from the default Engine::getOutputDevicesForAttributes() implementation).
+    //
+    // If no corresponding active client with setPreferredDevice then
+    // 3) Devices associated with the strategy determined by the attributes
+    //    (from the default Engine::getOutputDevicesForAttributes() implementation).
+    //
+    // See related getOutputForAttrInt().
+
+    // check dynamic policies but only for primary descriptors (secondary not used for audible
+    // audio routing, only used for duplication for playback capture)
+    sp<AudioPolicyMix> policyMix;
+    status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
+            0 /*uid unknown here*/, AUDIO_OUTPUT_FLAG_NONE, policyMix,
+            nullptr /* secondaryMixes */);
+    if (status != OK) {
+        return status;
+    }
+
+    if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
+            // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+            // as they are unaffected by device/stream volume
+            // (per SwAudioOutputDescriptor::isFixedVolume()).
+            (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
+            ) {
+        sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
+                policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+        devices.add(deviceDesc);
+    } else {
+        // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
+        // which selects setPreferredDevice if active.  This means forVolume call
+        // will take an active setPreferredDevice, if such exists.
+
+        devices = mEngine->getOutputDevicesForAttributes(
+                attr, nullptr /* preferredDevice */, false /* fromCache */);
+    }
+
+    if (forVolume) {
+        // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
+        // for single volume control in AudioService (such relationship should exist if
+        // SPEAKER_SAFE is present).
+        //
+        // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
+        DeviceVector speakerSafeDevices =
+                devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
+        if (!speakerSafeDevices.isEmpty()) {
+            devices.merge(mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
+            devices.remove(speakerSafeDevices);
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getProfilesForDevices(const DeviceVector& devices,
+                                                   AudioProfileVector& audioProfiles,
+                                                   uint32_t flags,
+                                                   bool isInput) {
+    for (const auto& hwModule : mHwModules) {
+        // the MSD module checks for different conditions
+        if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
+            continue;
+        }
+        IOProfileCollection ioProfiles = isInput ? hwModule->getInputProfiles()
+                                                 : hwModule->getOutputProfiles();
+        for (const auto& profile : ioProfiles) {
+            if (!profile->areAllDevicesSupported(devices) ||
+                    !profile->isCompatibleProfileForFlags(
+                            flags, false /*exactMatchRequiredForInputFlags*/)) {
+                continue;
+            }
+            audioProfiles.addAllValidProfiles(profile->asAudioPort()->getAudioProfiles());
+        }
+    }
+
+    if (!isInput) {
+        // add the direct profiles from MSD if present and has audio patches to all the output(s)
+        const auto &msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
+        if (msdModule != nullptr) {
+            if (msdHasPatchesToAllDevices(devices.toTypeAddrVector())) {
+                ALOGV("%s: MSD audio patches set to all output devices.", __func__);
+                for (const auto &profile: msdModule->getOutputProfiles()) {
+                    if (!profile->asAudioPort()->isDirectOutput()) {
+                        continue;
+                    }
+                    audioProfiles.addAllValidProfiles(profile->asAudioPort()->getAudioProfiles());
+                }
+            } else {
+                ALOGV("%s: MSD audio patches NOT set to all output devices.", __func__);
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 87e6974..74460c7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -117,7 +117,7 @@
                                   audio_session_t session,
                                   audio_stream_type_t *stream,
                                   const AttributionSourceState& attributionSource,
-                                  const audio_config_t *config,
+                                  audio_config_t *config,
                                   audio_output_flags_t *flags,
                                   audio_port_handle_t *selectedDeviceId,
                                   audio_port_handle_t *portId,
@@ -132,7 +132,7 @@
                                          audio_unique_id_t riid,
                                          audio_session_t session,
                                          const AttributionSourceState& attributionSource,
-                                         const audio_config_base_t *config,
+                                         audio_config_base_t *config,
                                          audio_input_flags_t flags,
                                          audio_port_handle_t *selectedDeviceId,
                                          input_type_t *inputType,
@@ -1052,7 +1052,7 @@
                 const audio_attributes_t *attr,
                 audio_stream_type_t *stream,
                 uid_t uid,
-                const audio_config_t *config,
+                audio_config_t *config,
                 audio_output_flags_t *flags,
                 audio_port_handle_t *selectedDeviceId,
                 bool *isRequestedDeviceForExclusiveUse,
@@ -1133,7 +1133,9 @@
          * @param session requester session id
          * @param uid requester uid
          * @param attributes requester audio attributes (e.g. input source and tags matter)
-         * @param config requester audio configuration (e.g. sample rate, format, channel mask).
+         * @param config requested audio configuration (e.g. sample rate, format, channel mask),
+         *               will be updated if current configuration doesn't support but another
+         *               one does
          * @param flags requester input flags
          * @param policyMix may be null, policy rules to be followed by the requester
          * @return input io handle aka unique input identifier selected for this device.
@@ -1141,7 +1143,7 @@
         audio_io_handle_t getInputForDevice(const sp<DeviceDescriptor> &device,
                 audio_session_t session,
                 const audio_attributes_t &attributes,
-                const audio_config_base_t *config,
+                audio_config_base_t *config,
                 audio_input_flags_t flags,
                 const sp<AudioPolicyMix> &policyMix);
 
@@ -1260,6 +1262,15 @@
 
         // Filters only the relevant flags for getProfileForOutput
         audio_output_flags_t getRelevantFlags (audio_output_flags_t flags, bool directOnly);
+
+        status_t getDevicesForAttributes(const audio_attributes_t &attr,
+                                         DeviceVector &devices,
+                                         bool forVolume);
+
+        status_t getProfilesForDevices(const DeviceVector& devices,
+                                       AudioProfileVector& audioProfiles,
+                                       uint32_t flags,
+                                       bool isInput);
 };
 
 };
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index df49bba..b15b61d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -443,6 +443,13 @@
                 convertContainer<std::vector<int32_t>>(secondaryOutputs,
                                                        legacy2aidl_audio_io_handle_t_int32_t));
         _aidl_return->isSpatialized = isSpatialized;
+    } else {
+        _aidl_return->configBase.format = VALUE_OR_RETURN_BINDER_STATUS(
+                legacy2aidl_audio_format_t_AudioFormatDescription(config.format));
+        _aidl_return->configBase.channelMask = VALUE_OR_RETURN_BINDER_STATUS(
+                legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+                        config.channel_mask, false /*isInput*/));
+        _aidl_return->configBase.sampleRate = config.sample_rate;
     }
     return binderStatusFromStatusT(result);
 }
@@ -755,6 +762,9 @@
             if (status == PERMISSION_DENIED) {
                 AutoCallerClear acc;
                 mAudioPolicyManager->releaseInput(portId);
+            } else {
+                _aidl_return->config = VALUE_OR_RETURN_BINDER_STATUS(
+                        legacy2aidl_audio_config_base_t_AudioConfigBase(config, true /*isInput*/));
             }
             return binderStatusFromStatusT(status);
         }
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 691f13c..5f29d3f 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -1210,6 +1210,14 @@
 
         dumpReleaseLock(mLock, locked);
 
+        if (mSpatializer != nullptr) {
+            std::string dumpString = mSpatializer->toString(1 /* level */);
+            write(fd, dumpString.c_str(), dumpString.size());
+        } else {
+            String8 spatializerPtr = String8::format("Spatializer no supportted on this device\n");
+            write(fd, spatializerPtr.c_str(), spatializerPtr.size());
+        }
+
         {
             std::string timeCheckStats = getIAudioPolicyServiceStatistics().dump();
             dprintf(fd, "\nIAudioPolicyService binder call profile\n");
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 20c7a5d..41ac202 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -15,11 +15,12 @@
 ** limitations under the License.
 */
 
-
+#include <string>
 #define LOG_TAG "Spatializer"
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include <limits.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -172,6 +173,41 @@
 };
 
 // ---------------------------------------------------------------------------
+
+// Convert recorded sensor data to string with level indentation.
+std::string Spatializer::HeadToStagePoseRecorder::toString_l(unsigned level) const {
+    std::string prefixSpace(level, ' ');
+    return mPoseRecordLog.dumpToString((prefixSpace + " ").c_str(), Spatializer::mMaxLocalLogLine);
+}
+
+// Compute sensor data, record into local log when it is time.
+void Spatializer::HeadToStagePoseRecorder::record_l(const std::vector<float>& headToStage) {
+    if (headToStage.size() != mPoseVectorSize) return;
+
+    if (mNumOfSampleSinceLastRecord++ == 0) {
+        mFirstSampleTimestamp = std::chrono::steady_clock::now();
+    }
+    // if it's time, do record and reset.
+    if (shouldRecordLog()) {
+        poseSumToAverage();
+        mPoseRecordLog.log(
+                "mean: %s, min: %s, max %s, calculated %d samples",
+                Spatializer::toString<double>(mPoseRadianSum, true /* radianToDegree */).c_str(),
+                Spatializer::toString<float>(mMinPoseAngle, true /* radianToDegree */).c_str(),
+                Spatializer::toString<float>(mMaxPoseAngle, true /* radianToDegree */).c_str(),
+                mNumOfSampleSinceLastRecord);
+        resetRecord(headToStage);
+    }
+    // update stream average.
+    for (int i = 0; i < mPoseVectorSize; i++) {
+        mPoseRadianSum[i] += headToStage[i];
+        mMaxPoseAngle[i] = std::max(mMaxPoseAngle[i], headToStage[i]);
+        mMinPoseAngle[i] = std::min(mMinPoseAngle[i], headToStage[i]);
+    }
+    return;
+}
+
+// ---------------------------------------------------------------------------
 sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) {
     sp<Spatializer> spatializer;
 
@@ -191,18 +227,20 @@
     ALOG_ASSERT(!descriptors.empty(),
             "%s getDescriptors() returned no error but empty list", __func__);
 
-    //TODO: get supported spatialization modes from FX engine or descriptor
-
+    // TODO: get supported spatialization modes from FX engine or descriptor
     sp<EffectHalInterface> effect;
     status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE,
             AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect);
-    ALOGI("%s FX create status %d effect %p", __func__, status, effect.get());
+    ALOGI("%s FX create status %d effect ID %" PRId64, __func__, status,
+          effect ? effect->effectId() : 0);
 
     if (status == NO_ERROR && effect != nullptr) {
         spatializer = new Spatializer(descriptors[0], callback);
         if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) {
             spatializer.clear();
         }
+        spatializer->mLocalLog.log("%s with effect Id %" PRId64, __func__,
+                                   effect ? effect->effectId() : 0);
     }
 
     return spatializer;
@@ -283,6 +321,7 @@
         ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES", __func__);
         return status;
     }
+
     for (const auto spatializationMode : spatializationModes) {
         if (!aidl_utils::isValidEnum(spatializationMode)) {
             ALOGW("%s: ignoring spatializationMode:%d", __func__, (int)spatializationMode);
@@ -381,7 +420,8 @@
 }
 
 Status Spatializer::setLevel(SpatializationLevel level) {
-    ALOGV("%s level %d", __func__, (int)level);
+    ALOGV("%s level %s", __func__, media::toString(level).c_str());
+    mLocalLog.log("%s with %s", __func__, media::toString(level).c_str());
     if (level != SpatializationLevel::NONE
             && std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) {
         return binderStatusFromStatusT(BAD_VALUE);
@@ -441,11 +481,12 @@
 }
 
 Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) {
-    ALOGV("%s mode %d", __func__, (int)mode);
+    ALOGV("%s mode %s", __func__, media::toString(mode).c_str());
 
     if (!mSupportsHeadTracking) {
         return binderStatusFromStatusT(INVALID_OPERATION);
     }
+    mLocalLog.log("%s with %s", __func__, media::toString(mode).c_str());
     std::lock_guard lock(mLock);
     switch (mode) {
         case SpatializerHeadTrackingMode::OTHER:
@@ -500,6 +541,7 @@
     }
     std::lock_guard lock(mLock);
     if (mPoseController != nullptr) {
+        mLocalLog.log("%s with %s", __func__, toString<float>(screenToStage).c_str());
         mPoseController->setScreenToStagePose(maybePose.value());
     }
     return Status::ok();
@@ -535,6 +577,7 @@
     }
     std::lock_guard lock(mLock);
     if (mHeadSensor != sensorHandle) {
+        mLocalLog.log("%s with 0x%08x", __func__, sensorHandle);
         mHeadSensor = sensorHandle;
         checkPoseController_l();
         checkSensorsState_l();
@@ -549,6 +592,7 @@
     }
     std::lock_guard lock(mLock);
     if (mScreenSensor != sensorHandle) {
+        mLocalLog.log("%s with 0x%08x", __func__, sensorHandle);
         mScreenSensor = sensorHandle;
         // TODO: consider a new method setHeadAndScreenSensor()
         // because we generally set both at the same time.
@@ -565,6 +609,7 @@
     }
     std::lock_guard lock(mLock);
     mDisplayOrientation = physicalToLogicalAngle;
+    mLocalLog.log("%s with %f", __func__, physicalToLogicalAngle);
     if (mPoseController != nullptr) {
         mPoseController->setDisplayOrientation(mDisplayOrientation);
     }
@@ -579,6 +624,7 @@
     std::lock_guard lock(mLock);
     ALOGV("%s hingeAngle %f", __func__, hingeAngle);
     if (mEngine != nullptr) {
+        mLocalLog.log("%s with %f", __func__, hingeAngle);
         setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{hingeAngle});
     }
     return Status::ok();
@@ -665,6 +711,7 @@
         callback = mHeadTrackingCallback;
         if (mEngine != nullptr) {
             setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
+            mPoseRecorder.record_l(headToStage);
         }
     }
 
@@ -674,7 +721,9 @@
 }
 
 void Spatializer::onActualModeChange(HeadTrackingMode mode) {
-    ALOGV("%s(%d)", __func__, (int)mode);
+    std::string modeStr = SpatializerPoseController::toString(mode);
+    ALOGV("%s(%s)", __func__, modeStr.c_str());
+    mLocalLog.log("%s with %s", __func__, modeStr.c_str());
     sp<AMessage> msg =
             new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
     msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
@@ -710,6 +759,9 @@
                                  std::vector<SpatializerHeadTrackingMode>{spatializerMode});
         }
         callback = mHeadTrackingCallback;
+        mLocalLog.log("%s: %s, spatializerMode %s", __func__,
+                      SpatializerPoseController::toString(mode).c_str(),
+                      media::toString(spatializerMode).c_str());
     }
     if (callback != nullptr) {
         callback->onHeadTrackingModeChanged(spatializerMode);
@@ -723,6 +775,8 @@
     {
         std::lock_guard lock(mLock);
         ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput);
+        mLocalLog.log("%s with output %d tracks %zu (mOutput %d)", __func__, (int)output,
+                      numActiveTracks, (int)mOutput);
         if (mOutput != AUDIO_IO_HANDLE_NONE) {
             LOG_ALWAYS_FATAL_IF(mEngine == nullptr, "%s output set without FX engine", __func__);
             // remove FX instance
@@ -777,6 +831,7 @@
 
     {
         std::lock_guard lock(mLock);
+        mLocalLog.log("%s with output %d tracks %zu", __func__, (int)mOutput, mNumActiveTracks);
         ALOGV("%s mOutput %d", __func__, (int)mOutput);
         if (mOutput == AUDIO_IO_HANDLE_NONE) {
             return output;
@@ -821,6 +876,7 @@
 void Spatializer::updateActiveTracks(size_t numActiveTracks) {
     std::lock_guard lock(mLock);
     if (mNumActiveTracks != numActiveTracks) {
+        mLocalLog.log("%s from %zu to %zu", __func__, mNumActiveTracks, numActiveTracks);
         mNumActiveTracks = numActiveTracks;
         checkEngineState_l();
         checkSensorsState_l();
@@ -899,4 +955,75 @@
     msg->post();
 }
 
+std::string Spatializer::toString(unsigned level) const {
+    std::string prefixSpace;
+    prefixSpace.append(level, ' ');
+    std::string ss = prefixSpace + "Spatializer:\n";
+    bool needUnlock = false;
+
+    prefixSpace += ' ';
+    if (!mLock.try_lock()) {
+        // dumpsys even try_lock failed, information dump can be useful although may not accurate
+        ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
+    } else {
+        needUnlock = true;
+    }
+
+    // Spatializer class information.
+    // 1. Capabilities (mLevels, mHeadTrackingModes, mSpatializationModes, mChannelMasks, etc)
+    ss.append(prefixSpace).append("Supported levels: [");
+    for (auto& level : mLevels) {
+        base::StringAppendF(&ss, " %s", media::toString(level).c_str());
+    }
+    base::StringAppendF(&ss, "], mLevel: %s", media::toString(mLevel).c_str());
+
+    base::StringAppendF(&ss, "\n%smHeadTrackingModes: [", prefixSpace.c_str());
+    for (auto& mode : mHeadTrackingModes) {
+        base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+    }
+    base::StringAppendF(&ss, "], Desired: %s, Actual %s\n",
+                        SpatializerPoseController::toString(mDesiredHeadTrackingMode).c_str(),
+                        media::toString(mActualHeadTrackingMode).c_str());
+
+    base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str());
+    for (auto& mode : mSpatializationModes) {
+        base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+    }
+    ss += "]\n";
+
+    base::StringAppendF(&ss, "%smChannelMasks: ", prefixSpace.c_str());
+    for (auto& mask : mChannelMasks) {
+        base::StringAppendF(&ss, "%s", audio_channel_out_mask_to_string(mask));
+    }
+    base::StringAppendF(&ss, "\n%smSupportsHeadTracking: %s\n", prefixSpace.c_str(),
+                        mSupportsHeadTracking ? "true" : "false");
+    // 2. Settings (Output, tracks)
+    base::StringAppendF(&ss, "%smNumActiveTracks: %zu\n", prefixSpace.c_str(), mNumActiveTracks);
+    base::StringAppendF(&ss, "%sOutputStreamHandle: %d\n", prefixSpace.c_str(), (int)mOutput);
+
+    // 3. Sensors, Effect information.
+    base::StringAppendF(&ss, "%sHeadSensorHandle: 0x%08x\n", prefixSpace.c_str(), mHeadSensor);
+    base::StringAppendF(&ss, "%sScreenSensorHandle: 0x%08x\n", prefixSpace.c_str(), mScreenSensor);
+    base::StringAppendF(&ss, "%sEffectHandle: %p\n", prefixSpace.c_str(), mEngine.get());
+    base::StringAppendF(&ss, "%sDisplayOrientation: %f\n", prefixSpace.c_str(),
+                        mDisplayOrientation);
+
+    ss.append(prefixSpace + "CommandLog:\n");
+    ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
+    ss.append(prefixSpace + "SensorLog:\n");
+    ss += mPoseRecorder.toString_l(level + 1);
+
+    // PostController dump.
+    if (mPoseController != nullptr) {
+        ss += mPoseController->toString(level + 1);
+    } else {
+        ss.append(prefixSpace).append("SpatializerPoseController not exist\n");
+    }
+
+    if (needUnlock) {
+        mLock.unlock();
+    }
+    return ss;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index bc95fe4..c0395a8 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -17,15 +17,19 @@
 #ifndef ANDROID_MEDIA_SPATIALIZER_H
 #define ANDROID_MEDIA_SPATIALIZER_H
 
+#include <android-base/stringprintf.h>
 #include <android/media/BnEffect.h>
 #include <android/media/BnSpatializer.h>
 #include <android/media/SpatializationLevel.h>
 #include <android/media/SpatializationMode.h>
 #include <android/media/SpatializerHeadTrackingMode.h>
+#include <audio_utils/SimpleLog.h>
+#include <math.h>
+#include <media/AudioEffect.h>
 #include <media/audiohal/EffectHalInterface.h>
 #include <media/stagefright/foundation/ALooper.h>
-#include <media/AudioEffect.h>
 #include <system/audio_effects/effect_spatializer.h>
+#include <string>
 
 #include "SpatializerPoseController.h"
 
@@ -156,6 +160,43 @@
 
     void calculateHeadPose();
 
+    /** Convert fields in Spatializer and sub-modules to a string. Disable thread-safety-analysis
+     * here because we want to dump mutex guarded members even try_lock failed to provide as much
+     * information as possible for debugging purpose. */
+    std::string toString(unsigned level) const NO_THREAD_SAFETY_ANALYSIS;
+
+    static std::string toString(audio_latency_mode_t mode) {
+        switch (mode) {
+            case AUDIO_LATENCY_MODE_FREE:
+                return "LATENCY_MODE_FREE";
+            case AUDIO_LATENCY_MODE_LOW:
+                return "LATENCY_MODE_LOW";
+        }
+        return "EnumNotImplemented";
+    };
+
+    /**
+     * Format head to stage vector to a string, [0.00, 0.00, 0.00, -1.29, -0.50, 15.27].
+     */
+    template <typename T>
+    static std::string toString(const std::vector<T>& vec, bool radianToDegree = false) {
+        if (vec.size() == 0) {
+            return "[]";
+        }
+
+        std::string ss = "[";
+        for (const auto& f : vec) {
+            if (radianToDegree) {
+                base::StringAppendF(&ss, "%0.2f, ",
+                                    HeadToStagePoseRecorder::getDegreeWithRadian(f));
+            } else {
+                base::StringAppendF(&ss, "%f, ", f);
+            }
+        }
+        ss.replace(ss.end() - 2, ss.end(), "]");
+        return ss;
+    };
+
 private:
     Spatializer(effect_descriptor_t engineDescriptor,
                      SpatializerPolicyCallback *callback);
@@ -364,9 +405,94 @@
     size_t mNumActiveTracks GUARDED_BY(mLock) = 0;
     std::vector<audio_latency_mode_t> mSupportedLatencyModes GUARDED_BY(mLock);
 
-    static const std::vector<const char *> sHeadPoseKeys;
-};
+    static const std::vector<const char*> sHeadPoseKeys;
 
+    // Local log for command messages.
+    static constexpr int mMaxLocalLogLine = 10;
+    SimpleLog mLocalLog{mMaxLocalLogLine};
+
+    /**
+     * @brief Calculate and record sensor data.
+     * Dump to local log with max/average pose angle every mPoseRecordThreshold.
+     * TODO: log azimuth/elevation angles obtained for debugging actual orientation.
+     */
+    class HeadToStagePoseRecorder {
+      public:
+        /** Convert recorded sensor data to string with level indentation */
+        std::string toString_l(unsigned level) const;
+        /**
+         * @brief Calculate sensor data, record into local log when it is time.
+         *
+         * @param headToStage The vector from Pose3f::toVector().
+         */
+        void record_l(const std::vector<float>& headToStage);
+
+        static constexpr float getDegreeWithRadian(const float radian) {
+            float radianToDegreeRatio = (180 / PI);
+            return (radian * radianToDegreeRatio);
+        }
+
+      private:
+        static constexpr float PI = M_PI;
+        /**
+         * Pose recorder time threshold to record sensor data in local log.
+         * Sensor data will be recorded at least every mPoseRecordThreshold.
+         */
+        // TODO: add another history log to record longer period of sensor data.
+        static constexpr std::chrono::duration<double> mPoseRecordThreshold =
+                std::chrono::seconds(1);
+        /**
+         * According to frameworks/av/media/libheadtracking/include/media/Pose.h
+         * "The vector will have exactly 6 elements, where the first three are a translation vector
+         * and the last three are a rotation vector."
+         */
+        static constexpr size_t mPoseVectorSize = 6;
+        /**
+         * Timestamp of last sensor data record in local log.
+         */
+        std::chrono::time_point<std::chrono::steady_clock> mFirstSampleTimestamp;
+        // Last pose recorded, vector obtained from Pose3f::toVector().
+        std::vector<float> mLastPoseRecorded{mPoseVectorSize};
+        /**
+         * Number of sensor samples received since last record, sample rate is ~100Hz which produce
+         * ~6k samples/minute.
+         */
+        uint32_t mNumOfSampleSinceLastRecord = 0;
+        /* The sum of pose angle represented by radian since last dump, div
+         * mNumOfSampleSinceLastRecord to get arithmetic mean. Largest possible value: 2PI * 100Hz *
+         * mPoseRecordThreshold.
+         */
+        std::vector<double> mPoseRadianSum{mPoseVectorSize};
+        std::vector<float> mMaxPoseAngle{mPoseVectorSize};
+        std::vector<float> mMinPoseAngle{mPoseVectorSize};
+        // Local log for history sensor data.
+        SimpleLog mPoseRecordLog{mMaxLocalLogLine};
+
+        bool shouldRecordLog() const {
+            return std::chrono::duration_cast<std::chrono::seconds>(
+                           std::chrono::steady_clock::now() - mFirstSampleTimestamp) >=
+                   mPoseRecordThreshold;
+        }
+
+        void resetRecord(const std::vector<float>& headToStage) {
+            mPoseRadianSum.assign(mPoseVectorSize, 0);
+            mMaxPoseAngle.assign(mPoseVectorSize, 0);
+            mMinPoseAngle.assign(mPoseVectorSize, 0);
+            mNumOfSampleSinceLastRecord = 0;
+            mLastPoseRecorded = headToStage;
+        }
+
+        // Add each sample to sum and only calculate when record.
+        void poseSumToAverage() {
+            if (mNumOfSampleSinceLastRecord == 0) return;
+            for (auto& p : mPoseRadianSum) {
+                const float reciprocal = 1.f / mNumOfSampleSinceLastRecord;
+                p *= reciprocal;
+            }
+        }
+    };  // HeadToStagePoseRecorder
+    HeadToStagePoseRecorder mPoseRecorder;
+};  // Spatializer
 
 }; // namespace android
 
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 23bcd77..e012a0b 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 #include "SpatializerPoseController.h"
+#include <android-base/stringprintf.h>
+#include <chrono>
+#include <cstdint>
+#include <string>
 
 #define LOG_TAG "SpatializerPoseController"
 //#define LOG_NDEBUG 0
@@ -291,4 +295,58 @@
     }
 }
 
+std::string SpatializerPoseController::toString(unsigned level) const {
+    std::string prefixSpace;
+    prefixSpace.append(level, ' ');
+    std::string ss = prefixSpace + "SpatializerPoseController:\n";
+    bool needUnlock = false;
+
+    prefixSpace += ' ';
+    auto now = std::chrono::steady_clock::now();
+    if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
+        ss.append(prefixSpace).append("try_lock failed, dumpsys maybe INACCURATE!\n");
+    } else {
+        needUnlock = true;
+    }
+
+    ss += prefixSpace;
+    if (mHeadSensor == media::SensorPoseProvider::INVALID_HANDLE) {
+        ss.append("HeadSensor: INVALID\n");
+    } else {
+        base::StringAppendF(&ss, "HeadSensor: 0x%08x\n", mHeadSensor);
+    }
+
+    ss += prefixSpace;
+    if (mScreenSensor == media::SensorPoseProvider::INVALID_HANDLE) {
+        ss += "ScreenSensor: INVALID\n";
+    } else {
+        base::StringAppendF(&ss, "ScreenSensor: 0x%08x\n", mScreenSensor);
+    }
+
+    ss += prefixSpace;
+    if (mActualMode.has_value()) {
+        base::StringAppendF(&ss, "ActualMode: %s", toString(mActualMode.value()).c_str());
+    } else {
+        ss += "ActualMode NOTEXIST\n";
+    }
+
+    if (mProcessor) {
+        ss += mProcessor->toString_l(level + 1);
+    } else {
+        ss.append(prefixSpace.c_str()).append("HeadTrackingProcessor not exist\n");
+    }
+
+    if (mPoseProvider) {
+        ss += mPoseProvider->toString(level + 1);
+    } else {
+        ss.append(prefixSpace.c_str()).append("SensorPoseProvider not exist\n");
+    }
+
+    if (needUnlock) {
+        mMutex.unlock();
+    }
+    // TODO: 233092747 add history sensor info with SimpleLog.
+    return ss;
+}
+
 }  // namespace android
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index f199ecb..546eba0 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -113,8 +113,23 @@
      */
     void waitUntilCalculated();
 
+    // convert fields to a printable string
+    std::string toString(unsigned level) const;
+
+    static std::string toString(media::HeadTrackingMode mode) {
+        switch (mode) {
+            case media::HeadTrackingMode::STATIC:
+                return "STATIC";
+            case media::HeadTrackingMode::WORLD_RELATIVE:
+                return "WORLD_RELATIVE";
+            case media::HeadTrackingMode::SCREEN_RELATIVE:
+                return "SCREEN_RELATIVE";
+        }
+        return "EnumNotImplemented";
+    };
+
   private:
-    mutable std::mutex mMutex;
+    mutable std::timed_mutex mMutex;
     Listener* const mListener;
     const std::chrono::microseconds mSensorPeriod;
     // Order matters for the following two members to ensure correct destruction.
@@ -123,7 +138,7 @@
     int32_t mHeadSensor = media::SensorPoseProvider::INVALID_HANDLE;
     int32_t mScreenSensor = media::SensorPoseProvider::INVALID_HANDLE;
     std::optional<media::HeadTrackingMode> mActualMode;
-    std::condition_variable mCondVar;
+    std::condition_variable_any mCondVar;
     bool mShouldCalculate = true;
     bool mShouldExit = false;
     bool mCalculated = false;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index acee2ab..644f682 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1512,6 +1512,7 @@
           maxExpectedDuration);
     status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
     if (res != OK) {
+        mStatusTracker->dumpActiveComponents();
         SET_ERR_L("Can't idle device in %f seconds!",
                 maxExpectedDuration/1e9);
     }
@@ -2231,7 +2232,6 @@
     if (mStatus == STATUS_ACTIVE) {
         markClientActive = true;
         mPauseStateNotify = true;
-        mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
 
         rc = internalPauseAndWaitLocked(maxExpectedDuration);
     }
@@ -3448,6 +3448,10 @@
         if (res == OK) {
             sp<Camera3Device> parent = mParent.promote();
             if (parent != nullptr) {
+                sp<StatusTracker> statusTracker = mStatusTracker.promote();
+                if (statusTracker != nullptr) {
+                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
+                }
                 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
             }
             setPaused(false);
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 99e3691..765a076 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -459,6 +459,15 @@
             [this](const std::shared_ptr<const android::mediametrics::Item> &item){
                 mAudioPowerUsage.checkCreatePatch(item);
             }));
+
+    // Handle Spatializer - these keys are prefixed by "audio.spatializer."
+    mActions.addAction(
+        AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "*." AMEDIAMETRICS_PROP_EVENT,
+        std::monostate{}, /* match any event */
+        std::make_shared<AnalyticsActions::Function>(
+            [this](const std::shared_ptr<const android::mediametrics::Item> &item){
+                mSpatializer.onEvent(item);
+            }));
 }
 
 AudioAnalytics::~AudioAnalytics()
@@ -1525,5 +1534,109 @@
     return { s, n };
 }
 
+void AudioAnalytics::Spatializer::onEvent(
+        const std::shared_ptr<const android::mediametrics::Item> &item)
+{
+    const auto key = item->getKey();
+
+    if (!startsWith(key, AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER)) return;
+
+    const std::string suffix =
+            key.substr(std::size(AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER) - 1);
+
+    std::string eventStr; // optional - find the actual event string.
+    (void)item->get(AMEDIAMETRICS_PROP_EVENT, &eventStr);
+
+    const size_t delim = suffix.find('.'); // note could use split.
+    if (delim == suffix.npos) {
+        // on create with suffix == "0" for the first spatializer effect.
+
+        std::string headTrackingModes;
+        (void)item->get(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, &headTrackingModes);
+
+        std::string levels;
+        (void)item->get(AMEDIAMETRICS_PROP_LEVELS, &levels);
+
+        std::string modes;
+        (void)item->get(AMEDIAMETRICS_PROP_MODES, &modes);
+
+        int32_t channelMask = 0;
+        (void)item->get(AMEDIAMETRICS_PROP_CHANNELMASK, &channelMask);
+
+        LOG(LOG_LEVEL) << "key:" << key
+                << " headTrackingModes:" << headTrackingModes
+                << " levels:" << levels
+                << " modes:" << modes
+                << " channelMask:" << channelMask
+                ;
+
+        const std::vector<int32_t> headTrackingModesVector =
+                types::vectorFromMap(headTrackingModes, types::getHeadTrackingModeMap());
+        const std::vector<int32_t> levelsVector =
+                types::vectorFromMap(levels, types::getSpatializerLevelMap());
+        const std::vector<int32_t> modesVector =
+                types::vectorFromMap(modes, types::getSpatializerModeMap());
+
+        // TODO: send to statsd
+
+        std::lock_guard lg(mLock);
+        mSimpleLog.log("%s suffix: %s item: %s",
+                __func__, suffix.c_str(), item->toString().c_str());
+    } else {
+        std::string subtype = suffix.substr(0, delim);
+        if (subtype != "device") return; // not a device.
+
+        std::string deviceType = suffix.substr(std::size("device.") - 1);
+
+        std::string enabled;
+        (void)item->get(AMEDIAMETRICS_PROP_ENABLED, &enabled);
+        std::string hasHeadTracker;
+        (void)item->get(AMEDIAMETRICS_PROP_HASHEADTRACKER, &hasHeadTracker);
+        std::string headTrackerEnabled;
+        (void)item->get(AMEDIAMETRICS_PROP_HEADTRACKERENABLED, &headTrackerEnabled);
+
+        std::lock_guard lg(mLock);
+
+        // Validate from our cached state
+        DeviceState& deviceState = mDeviceStateMap[deviceType];
+
+        if (!enabled.empty()) {
+            if (enabled != deviceState.enabled) {
+                deviceState.enabled = enabled;
+                const bool enabledStatsd = enabled == "true";
+                // TODO: send to statsd
+                (void)mAudioAnalytics;
+                (void)enabledStatsd;
+            }
+        }
+        if (!hasHeadTracker.empty()) {
+            if (hasHeadTracker != deviceState.hasHeadTracker) {
+                deviceState.hasHeadTracker = hasHeadTracker;
+                const bool supportedStatsd = hasHeadTracker == "true";
+                // TODO: send to statsd
+                (void)supportedStatsd;
+            }
+        }
+        if (!headTrackerEnabled.empty()) {
+            if (headTrackerEnabled != deviceState.headTrackerEnabled) {
+                deviceState.headTrackerEnabled = headTrackerEnabled;
+                const bool enabledStatsd = headTrackerEnabled == "true";
+                // TODO: send to statsd
+                (void)enabledStatsd;
+            }
+        }
+        mSimpleLog.log("%s deviceType: %s item: %s",
+                __func__, deviceType.c_str(), item->toString().c_str());
+    }
+}
+
+std::pair<std::string, int32_t> AudioAnalytics::Spatializer::dump(
+        int32_t lines, const char *prefix) const
+{
+    std::lock_guard lg(mLock);
+    std::string s = mSimpleLog.dumpToString(prefix == nullptr ? "" : prefix, lines);
+    size_t n = std::count(s.begin(), s.end(), '\n');
+    return { s, n };
+}
 
 } // namespace android::mediametrics
diff --git a/services/mediametrics/AudioTypes.cpp b/services/mediametrics/AudioTypes.cpp
index 6e24a58..f2515bb 100644
--- a/services/mediametrics/AudioTypes.cpp
+++ b/services/mediametrics/AudioTypes.cpp
@@ -135,6 +135,50 @@
     return map;
 }
 
+// A map for the Java AudioDeviceInfo types to internal (native) output devices.
+const std::unordered_map<std::string, int32_t>& getAudioDeviceOutCompactMap() {
+    // DO NOT MODIFY VALUES (OK to add new ones).
+    static std::unordered_map<std::string, int32_t> map{
+        // should "unknown" go to AUDIO_DEVICE_NONE?
+        {"earpiece", AUDIO_DEVICE_OUT_EARPIECE},
+        {"speaker", AUDIO_DEVICE_OUT_SPEAKER},
+        {"headset", AUDIO_DEVICE_OUT_WIRED_HEADSET},
+        {"headphone", AUDIO_DEVICE_OUT_WIRED_HEADPHONE},
+        {"bt_sco", AUDIO_DEVICE_OUT_BLUETOOTH_SCO},
+        {"bt_sco_hs", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET},
+        {"bt_sco_carkit", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT},
+        {"bt_a2dp", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP},
+        {"bt_a2dp_hp", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES},
+        {"bt_a2dp_spk", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER},
+        {"aux_digital", AUDIO_DEVICE_OUT_AUX_DIGITAL},
+        {"hdmi", AUDIO_DEVICE_OUT_HDMI},
+        {"analog_dock", AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET},
+        {"digital_dock", AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET},
+        {"usb_accessory", AUDIO_DEVICE_OUT_USB_ACCESSORY},
+        {"usb_device", AUDIO_DEVICE_OUT_USB_DEVICE},
+        {"remote_submix", AUDIO_DEVICE_OUT_REMOTE_SUBMIX},
+        {"telephony_tx", AUDIO_DEVICE_OUT_TELEPHONY_TX},
+        {"line", AUDIO_DEVICE_OUT_LINE},
+        {"hdmi_arc", AUDIO_DEVICE_OUT_HDMI_ARC},
+        {"hdmi_earc", AUDIO_DEVICE_OUT_HDMI_EARC},
+        {"spdif", AUDIO_DEVICE_OUT_SPDIF},
+        {"fm_transmitter", AUDIO_DEVICE_OUT_FM},
+        {"aux_line", AUDIO_DEVICE_OUT_AUX_LINE},
+        {"speaker_safe", AUDIO_DEVICE_OUT_SPEAKER_SAFE},
+        {"ip", AUDIO_DEVICE_OUT_IP},
+        {"bus", AUDIO_DEVICE_OUT_BUS},
+        {"proxy", AUDIO_DEVICE_OUT_PROXY},
+        {"usb_headset", AUDIO_DEVICE_OUT_USB_HEADSET},
+        {"hearing_aid_out", AUDIO_DEVICE_OUT_HEARING_AID},
+        {"echo_canceller", AUDIO_DEVICE_OUT_ECHO_CANCELLER},
+        // default does not exist
+        {"ble_headset", AUDIO_DEVICE_OUT_BLE_HEADSET},
+        {"ble_speaker", AUDIO_DEVICE_OUT_BLE_SPEAKER},
+        {"ble_broadcast", AUDIO_DEVICE_OUT_BLE_BROADCAST},
+    };
+    return map;
+}
+
 const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap() {
     // DO NOT MODIFY VALUES (OK to add new ones).
     // This may be found in frameworks/av/services/audioflinger/Threads.h
@@ -197,6 +241,41 @@
     return map;
 }
 
+const std::unordered_map<std::string, int32_t>& getHeadTrackingModeMap() {
+    // DO NOT MODIFY VALUES(OK to add new ones).
+    // frameworks/base/media/java/android/media/Spatializer.java
+    // frameworks/av/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
+    static std::unordered_map<std::string, int32_t> map {
+        {"OTHER", 0},
+        {"DISABLED", -1},
+        {"RELATIVE_WORLD", 1},
+        {"RELATIVE_SCREEN", 2},
+    };
+    return map;
+}
+
+const std::unordered_map<std::string, int32_t>& getSpatializerLevelMap() {
+    // DO NOT MODIFY VALUES(OK to add new ones).
+    // frameworks/base/media/java/android/media/Spatializer.java
+    // frameworks/av/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
+    static std::unordered_map<std::string, int32_t> map {
+        {"NONE", 0},
+        {"SPATIALIZER_MULTICHANNEL", 1},
+        {"SPATIALIZER_MCHAN_BED_PLUS_OBJECTS", 2},
+    };
+    return map;
+}
+
+const std::unordered_map<std::string, int32_t>& getSpatializerModeMap() {
+    // DO NOT MODIFY VALUES(OK to add new ones).
+    // frameworks/av/media/libaudioclient/aidl/android/media/SpatializationMode.aidl
+    static std::unordered_map<std::string, int32_t> map {
+        {"SPATIALIZER_BINAURAL", 0},
+        {"SPATIALIZER_TRANSAURAL", 1},
+    };
+    return map;
+}
+
 const std::unordered_map<std::string, int32_t>& getStatusMap() {
     // DO NOT MODIFY VALUES(OK to add new ones).
     static std::unordered_map<std::string, int32_t> map {
@@ -286,6 +365,22 @@
     return value;
 }
 
+std::vector<int32_t> vectorFromMap(
+        const std::string &str, const std::unordered_map<std::string, int32_t>& map)
+{
+    std::vector<int32_t> v;
+
+    if (str.empty()) return v;
+
+    const auto result = stringutils::split(str, "|");
+    for (const auto &s : result) {
+        auto it = map.find(s);
+        if (it == map.end()) continue;
+        v.push_back(it->second);
+    }
+    return v;
+}
+
 template <>
 int32_t lookup<CONTENT_TYPE>(const std::string &contentType)
 {
@@ -463,6 +558,39 @@
 }
 
 template <>
+int32_t lookup<HEAD_TRACKING_MODE>(const std::string& headTrackingMode)
+{
+    auto& map = getHeadTrackingModeMap();
+    auto it = map.find(headTrackingMode);
+    if (it == map.end()) {
+        return 0;
+    }
+    return it->second;
+}
+
+template <>
+int32_t lookup<SPATIALIZER_LEVEL>(const std::string& spatializerLevel)
+{
+    auto& map = getSpatializerLevelMap();
+    auto it = map.find(spatializerLevel);
+    if (it == map.end()) {
+        return 0;
+    }
+    return it->second;
+}
+
+template <>
+int32_t lookup<SPATIALIZER_MODE>(const std::string& spatializerMode)
+{
+    auto& map = getSpatializerModeMap();
+    auto it = map.find(spatializerMode);
+    if (it == map.end()) {
+        return 0;
+    }
+    return it->second;
+}
+
+template <>
 int32_t lookup<STATUS>(const std::string &status)
 {
     auto& map = getStatusMap();
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 9e2f896..ceb3e6a 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -338,6 +338,15 @@
                 result << "-- some lines may be truncated --\n";
             }
 
+            const int32_t spatializerLinesToDump = all ? INT32_MAX : 15;
+            result << "\nSpatializer Message Log:";
+            const auto [ spatializerDumpString, spatializerLines ] =
+                    mAudioAnalytics.dumpSpatializer(spatializerLinesToDump);
+            result << "\n" << spatializerDumpString;
+            if (spatializerLines == spatializerLinesToDump) {
+                result << "-- some lines may be truncated --\n";
+            }
+
             result << "\nLogSessionId:\n"
                    << mediametrics::ValidateId::get()->dump();
 
diff --git a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
index 5ee8c30..d51dc59 100644
--- a/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
+++ b/services/mediametrics/include/mediametricsservice/AudioAnalytics.h
@@ -92,6 +92,15 @@
         return mHealth.dump(lines);
     }
 
+    /**
+     * Returns a pair consisting of the dump string and the number of lines in the string.
+     *
+     * Spatializer dump.
+     */
+    std::pair<std::string, int32_t> dumpSpatializer(int32_t lines = INT32_MAX) const {
+        return mSpatializer.dump(lines);
+    }
+
     void clear() {
         // underlying state is locked.
         mPreviousAnalyticsState->clear();
@@ -317,6 +326,35 @@
         SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
     } mHealth{*this};
 
+    // Spatializer is a nested class that tracks related messages.
+    class Spatializer {
+    public:
+        explicit Spatializer(AudioAnalytics &audioAnalytics)
+            : mAudioAnalytics(audioAnalytics) {}
+
+        // an item that starts with "audio.spatializer"
+        void onEvent(const std::shared_ptr<const android::mediametrics::Item> &item);
+
+        std::pair<std::string, int32_t> dump(
+                int32_t lines = INT32_MAX, const char *prefix = nullptr) const;
+
+    private:
+
+        // Current device state as strings:
+        // "" means unknown, "true" or "false".
+        struct DeviceState {
+            std::string enabled;
+            std::string hasHeadTracker;
+            std::string headTrackerEnabled;
+        };
+
+        AudioAnalytics& mAudioAnalytics;
+
+        mutable std::mutex mLock;
+        std::map<std::string, DeviceState> mDeviceStateMap GUARDED_BY(mLock);
+        SimpleLog mSimpleLog GUARDED_BY(mLock) {64};
+    } mSpatializer{*this};
+
     AudioPowerUsage mAudioPowerUsage;
 };
 
diff --git a/services/mediametrics/include/mediametricsservice/AudioTypes.h b/services/mediametrics/include/mediametricsservice/AudioTypes.h
index 5dbff9b..0184baf 100644
--- a/services/mediametrics/include/mediametricsservice/AudioTypes.h
+++ b/services/mediametrics/include/mediametricsservice/AudioTypes.h
@@ -29,6 +29,12 @@
 const std::unordered_map<std::string, int64_t>& getAudioDeviceOutMap();
 const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap();
 const std::unordered_map<std::string, int32_t>& getAudioTrackTraitsMap();
+const std::unordered_map<std::string, int32_t>& getHeadTrackingModeMap();
+const std::unordered_map<std::string, int32_t>& getSpatializerLevelMap();
+const std::unordered_map<std::string, int32_t>& getSpatializerModeMap();
+
+std::vector<int32_t> vectorFromMap(
+        const std::string &str, const std::unordered_map<std::string, int32_t>& map);
 
 // Enumeration for the device connection results.
 enum DeviceConnectionResult : int32_t {
@@ -50,11 +56,14 @@
     CALLER_NAME,
     CONTENT_TYPE,
     ENCODING,
+    HEAD_TRACKING_MODE,
     INPUT_DEVICE,  // int64_t
     INPUT_FLAG,
     OUTPUT_DEVICE, // int64_t
     OUTPUT_FLAG,
     SOURCE_TYPE,
+    SPATIALIZER_LEVEL,
+    SPATIALIZER_MODE,
     STATUS,
     STREAM_TYPE,
     THREAD_TYPE,
diff --git a/services/mediametrics/include/mediametricsservice/MediaMetricsService.h b/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
index 8d0b1cf..3ec5ac7 100644
--- a/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
+++ b/services/mediametrics/include/mediametricsservice/MediaMetricsService.h
@@ -125,7 +125,7 @@
     std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.
 
     // mStatsdLog is locked internally (thread-safe) and shows the last atoms logged
-    static constexpr size_t STATSD_LOG_LINES_MAX = 30; // recent log lines to keep
+    static constexpr size_t STATSD_LOG_LINES_MAX = 48; // recent log lines to keep
     static constexpr size_t STATSD_LOG_LINES_DUMP = 4; // normal amount of lines to dump
     const std::shared_ptr<mediametrics::StatsdLog> mStatsdLog{
             std::make_shared<mediametrics::StatsdLog>(STATSD_LOG_LINES_MAX)};
diff --git a/services/mediametrics/include/mediametricsservice/StringUtils.h b/services/mediametrics/include/mediametricsservice/StringUtils.h
index a56f5b8..a91d37b 100644
--- a/services/mediametrics/include/mediametricsservice/StringUtils.h
+++ b/services/mediametrics/include/mediametricsservice/StringUtils.h
@@ -23,6 +23,19 @@
 
 namespace android::mediametrics::stringutils {
 
+// Define a way of printing a vector - this
+// is used for proto repeated arguments.
+template <typename T>
+inline std::ostream & operator<< (std::ostream& s,
+                           std::vector<T> const& v) {
+    s << "{ ";
+    for (const auto& e : v) {
+        s << e << " ";
+    }
+    s << "}";
+    return s;
+}
+
 /**
  * fieldPrint is a helper method that logs to a stringstream a sequence of
  * field names (in a fixed size array) together with a variable number of arg parameters.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index b4610bc..4d18876 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -271,10 +271,9 @@
             snprintf(buffer, SIZE, "        Id: %lld\n", (long long)infos[j].clientId);
             result.append(buffer);
 
-            std::string clientName;
-            Status status = infos[j].client->getName(&clientName);
-            if (!status.isOk()) {
-                clientName = "<unknown client>";
+            std::string clientName = "<unknown client>";
+            if (infos[j].client != nullptr) {
+                Status status = infos[j].client->getName(&clientName);
             }
             snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
             result.append(buffer);
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index bbfa0b7..133b9b4 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include <map>
 #include <mutex>
+#include <set>
 #include <sstream>
 #include <thread>
 #include <utils/Singleton.h>
@@ -68,6 +69,24 @@
     return result.str();
 }
 
+namespace {
+
+const static std::map<audio_format_t, audio_format_t> NEXT_FORMAT_TO_TRY = {
+        {AUDIO_FORMAT_PCM_FLOAT,         AUDIO_FORMAT_PCM_32_BIT},
+        {AUDIO_FORMAT_PCM_32_BIT,        AUDIO_FORMAT_PCM_24_BIT_PACKED},
+        {AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_16_BIT}
+};
+
+audio_format_t getNextFormatToTry(audio_format_t curFormat, audio_format_t returnedFromAPM) {
+    if (returnedFromAPM != AUDIO_FORMAT_DEFAULT) {
+        return returnedFromAPM;
+    }
+    const auto it = NEXT_FORMAT_TO_TRY.find(curFormat);
+    return it != NEXT_FORMAT_TO_TRY.end() ? it->second : AUDIO_FORMAT_DEFAULT;
+}
+
+}
+
 aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
     aaudio_result_t result = AAUDIO_OK;
     copyFrom(request.getConstantConfiguration());
@@ -79,36 +98,38 @@
         legacy2aidl_pid_t_int32_t(IPCThreadState::self()->getCallingPid()));
 
     audio_format_t audioFormat = getFormat();
+    std::set<audio_format_t> formatsTried;
+    while (true) {
+        if (formatsTried.find(audioFormat) != formatsTried.end()) {
+            // APM returning something that has already tried.
+            ALOGW("Have already tried to open #x, but failed before");
+            break;
+        }
+        formatsTried.insert(audioFormat);
 
-    result = openWithFormat(audioFormat);
-    if (result == AAUDIO_OK) return result;
+        audio_format_t nextFormatToTry = AUDIO_FORMAT_DEFAULT;
+        result = openWithFormat(audioFormat, &nextFormatToTry);
+        if (result == AAUDIO_OK || result != AAUDIO_ERROR_UNAVAILABLE) {
+            // Return if it is successful or there is an error that is not
+            // AAUDIO_ERROR_UNAVAILABLE happens.
+            ALOGI("Opened format=%#x with result=%d", audioFormat, result);
+            break;
+        }
 
-    if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
-        ALOGD("%s() FLOAT failed, perhaps due to format. Try again with 32_BIT", __func__);
-        audioFormat = AUDIO_FORMAT_PCM_32_BIT;
-        result = openWithFormat(audioFormat);
-    }
-    if (result == AAUDIO_OK) return result;
-
-    if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_32_BIT) {
-        ALOGD("%s() 32_BIT failed, perhaps due to format. Try again with 24_BIT_PACKED", __func__);
-        audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
-        result = openWithFormat(audioFormat);
-    }
-    if (result == AAUDIO_OK) return result;
-
-    // TODO The HAL and AudioFlinger should be recommending a format if the open fails.
-    //      But that recommendation is not propagating back from the HAL.
-    //      So for now just try something very likely to work.
-    if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
-        ALOGD("%s() 24_BIT failed, perhaps due to format. Try again with 16_BIT", __func__);
-        audioFormat = AUDIO_FORMAT_PCM_16_BIT;
-        result = openWithFormat(audioFormat);
+        nextFormatToTry = getNextFormatToTry(audioFormat, nextFormatToTry);
+        ALOGD("%s() %#x failed, perhaps due to format. Try again with %#x",
+              __func__, audioFormat, nextFormatToTry);
+        audioFormat = nextFormatToTry;
+        if (audioFormat == AUDIO_FORMAT_DEFAULT) {
+            // Nothing else to try
+            break;
+        }
     }
     return result;
 }
 
-aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(audio_format_t audioFormat) {
+aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(
+        audio_format_t audioFormat, audio_format_t* nextFormatToTry) {
     aaudio_result_t result = AAUDIO_OK;
     audio_config_base_t config;
     audio_port_handle_t deviceId;
@@ -151,6 +172,8 @@
     audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
 
     // Open HAL stream. Set mMmapStream
+    ALOGD("%s trying to open MMAP stream with format=%#x, sample_rate=%u, channel_mask=%#x",
+          __func__, config.format, config.sample_rate, config.channel_mask);
     status_t status = MmapStreamInterface::openMmapStream(streamDirection,
                                                           &attributes,
                                                           &config,
@@ -165,7 +188,11 @@
     if (status != OK) {
         // This can happen if the resource is busy or the config does
         // not match the hardware.
-        ALOGD("%s() - openMmapStream() returned status %d",  __func__, status);
+        ALOGD("%s() - openMmapStream() returned status=%d, suggested format=%#x, sample_rate=%u, "
+              "channel_mask=%#x",
+              __func__, status, config.format, config.sample_rate, config.format);
+        *nextFormatToTry = config.format != audioFormat ? config.format
+                                                        : *nextFormatToTry;
         return AAUDIO_ERROR_UNAVAILABLE;
     }
 
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 3658c58..73e0f61 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -92,7 +92,7 @@
 
 private:
 
-    aaudio_result_t openWithFormat(audio_format_t audioFormat);
+    aaudio_result_t openWithFormat(audio_format_t audioFormat, audio_format_t* nextFormatToTry);
 
     aaudio_result_t createMmapBuffer(android::base::unique_fd* fileDescriptor);