Merge "Invalidate all other clients when bit-perfect playback becomes active." into udc-qpr-dev am: c120d093fa am: 8d15f4c171

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

Change-Id: I357a83a078e65c15d63bb3b15200a582a7493015
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 9ae4607..ef40f6c 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -103,7 +103,6 @@
 
 namespace {
     sp<::android::hardware::ICameraService> gCameraService;
-    const int                 kCameraServicePollDelay = 500000; // 0.5s
     const char*               kCameraServiceName      = "media.camera";
 
     Mutex                     gLock;
@@ -141,14 +140,10 @@
 
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
-        do {
-            binder = sm->getService(String16(kCameraServiceName));
-            if (binder != 0) {
-                break;
-            }
-            ALOGW("CameraService not published, waiting...");
-            usleep(kCameraServicePollDelay);
-        } while(true);
+        binder = sm->waitForService(String16(kCameraServiceName));
+        if (binder == nullptr) {
+            return nullptr;
+        }
         if (gDeathNotifier == NULL) {
             gDeathNotifier = new DeathNotifier();
         }
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 8472562..13b705c 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -26,12 +26,15 @@
 
     srcs: ["main_cameraserver.cpp"],
 
+    defaults: [
+        "libcameraservice_deps",
+    ],
+
     header_libs: [
         "libmedia_headers",
     ],
 
     shared_libs: [
-        "libcameraservice",
         "liblog",
         "libutils",
         "libui",
@@ -40,15 +43,13 @@
         "libbinder_ndk",
         "libhidlbase",
         "android.hardware.camera.common@1.0",
-        "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.provider@2.5",
-        "android.hardware.camera.provider@2.6",
-        "android.hardware.camera.provider@2.7",
-        "android.hardware.camera.provider-V2-ndk",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
     ],
+    static_libs: [
+        "libcameraservice",
+    ],
     compile_multilib: "first",
     cflags: [
         "-Wall",
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index bfd02b3..866dc72 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -182,6 +182,7 @@
     shared_libs: [
         "libcamera2ndk_vendor",
         "libcamera_metadata",
+        "libhidlbase",
         "libmediandk",
         "libnativewindow",
         "libutils",
@@ -191,6 +192,7 @@
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
+        "android.hidl.token@1.0",
     ],
     cflags: [
         "-D__ANDROID_VNDK__",
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7f6ea9d..74c6cad 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -31,10 +31,13 @@
 #include <stdio.h>
 
 #include <android/log.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/hidl/token/1.0/ITokenManager.h>
 #include <camera/NdkCameraError.h>
 #include <camera/NdkCameraManager.h>
 #include <camera/NdkCameraDevice.h>
 #include <camera/NdkCameraCaptureSession.h>
+#include <hidl/ServiceManagement.h>
 #include <media/NdkImage.h>
 #include <media/NdkImageReader.h>
 #include <cutils/native_handle.h>
@@ -50,6 +53,8 @@
 static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
 
 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+using android::hidl::manager::V1_0::IServiceManager;
+using android::hidl::token::V1_0::ITokenManager;
 using ConfiguredWindows = std::set<const native_handle_t *>;
 
 class CameraHelper {
@@ -981,11 +986,19 @@
 
 
 TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+    auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+    if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+        GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+    }
     testBasicTakePictures(/*prepareSurfaces*/ false);
     testBasicTakePictures(/*prepareSurfaces*/ true);
 }
 
 TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+    auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+    if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+        GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+    }
     for (auto & v2 : {true, false}) {
         testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
         testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 301538f..6744e25 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -36,13 +36,6 @@
 using aidl::android::media::MediaResourceParcel;
 using aidl::android::media::ClientInfoParcel;
 
-namespace {
-void ResourceManagerServiceDied(void* cookie) {
-    auto thiz = static_cast<DrmSessionManager*>(cookie);
-    thiz->binderDied();
-}
-}
-
 using ::ndk::ScopedAStatus;
 
 static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
@@ -60,6 +53,12 @@
     return vec;
 }
 
+static Vector<uint8_t> toAndroidVec(const std::vector<uint8_t>& array) {
+    Vector<uint8_t> vec;
+    vec.appendArray(array.data(), array.size());
+    return vec;
+}
+
 static std::vector<MediaResourceParcel> toResourceVec(
         const Vector<uint8_t> &sessionId, int64_t value) {
     using Type = aidl::android::media::MediaResourceType;
@@ -72,11 +71,6 @@
     return resources;
 }
 
-static std::shared_ptr<IResourceManagerService> getResourceManagerService() {
-    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
-    return IResourceManagerService::fromBinder(binder);
-}
-
 bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
     if (sessionId1.size() != sessionId2.size()) {
         return false;
@@ -96,16 +90,15 @@
 }
 
 DrmSessionManager::DrmSessionManager()
-    : DrmSessionManager(getResourceManagerService()) {
+    : DrmSessionManager(nullptr) {
 }
 
 DrmSessionManager::DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service)
     : mService(service),
-      mInitialized(false),
-      mDeathRecipient(AIBinder_DeathRecipient_new(ResourceManagerServiceDied)) {
-    if (mService == NULL) {
-        ALOGE("Failed to init ResourceManagerService");
-    }
+      mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
+          AIBinder_DeathRecipient_new(ResourceManagerServiceDied))) {
+    // Setting callback notification when DeathRecipient gets deleted.
+    AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), BinderUnlinkedCallback);
 }
 
 DrmSessionManager::~DrmSessionManager() {
@@ -114,14 +107,64 @@
     }
 }
 
-void DrmSessionManager::init() {
+status_t DrmSessionManager::init() {
     Mutex::Autolock lock(mLock);
-    if (mInitialized) {
+    getResourceManagerService_l();
+    if (mService == nullptr) {
+        ALOGE("Failed to init ResourceManagerService");
+        return DEAD_OBJECT;
+    }
+
+    return OK;
+}
+
+void DrmSessionManager::getResourceManagerService_l() {
+    if (mService != nullptr) {
         return;
     }
-    mInitialized = true;
-    if (mService != NULL) {
-        AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+
+    // Get binder interface to resource manager.
+    ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.resource_manager"));
+    mService = IResourceManagerService::fromBinder(binder);
+    if (mService == nullptr) {
+        ALOGE("Failed to get ResourceManagerService");
+        return;
+    }
+
+    // Create the context that is passed as cookie to the binder death notification.
+    // The context gets deleted at BinderUnlinkedCallback.
+    BinderDiedContext* context = new BinderDiedContext{
+        .mDrmSessionManager = wp<DrmSessionManager>::fromExisting(this)};
+    // Register for the callbacks by linking to death notification.
+    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), context);
+
+    // If the RM was restarted, re-register all the resources.
+    if (mBinderDied) {
+        reRegisterAllResources_l();
+        mBinderDied = false;
+    }
+}
+
+void DrmSessionManager::reRegisterAllResources_l() {
+    if (mSessionMap.empty()) {
+        // Nothing to register.
+        ALOGV("No resources to add");
+        return;
+    }
+
+    if (mService == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
+
+    // Go through the session map and re-register all the resources for those sessions.
+    for (SessionInfoMap::const_iterator iter = mSessionMap.begin();
+         iter != mSessionMap.end(); ++iter) {
+        ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(iter->second.pid),
+                                    .uid = static_cast<int32_t>(iter->second.uid),
+                                    .id = iter->second.clientId};
+        mService->addResource(clientInfo, iter->second.drm,
+                              toResourceVec(toAndroidVec(iter->first), iter->second.resourceValue));
     }
 }
 
@@ -137,7 +180,7 @@
     }
 
     static int64_t clientId = 0;
-    mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
+    mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId, drm, INT64_MAX};
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
                                 .uid = static_cast<int32_t>(uid),
                                 .id = clientId++};
@@ -154,6 +197,7 @@
     }
 
     auto info = it->second;
+    info.resourceValue = -1;
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(info.pid),
                                 .uid = static_cast<int32_t>(info.uid),
                                 .id = info.clientId};
@@ -215,7 +259,31 @@
 void DrmSessionManager::binderDied() {
     ALOGW("ResourceManagerService died.");
     Mutex::Autolock lock(mLock);
-    mService.reset();
+    mService = nullptr;
+    mBinderDied = true;
+    // start an async operation that will reconnect with the RM and
+    // re-registers all the resources.
+    mGetServiceFuture = std::async(std::launch::async, [this] { getResourceManagerService(); });
+}
+
+void DrmSessionManager::ResourceManagerServiceDied(void* cookie) {
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+
+    // Validate the context and check if the DrmSessionManager object is still in scope.
+    if (context != nullptr) {
+        sp<DrmSessionManager> thiz = context->mDrmSessionManager.promote();
+        if (thiz != nullptr) {
+            thiz->binderDied();
+        } else {
+            ALOGI("DrmSessionManager is out of scope already");
+        }
+    }
+}
+
+void DrmSessionManager::BinderUnlinkedCallback(void* cookie) {
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+    // Since we don't need the context anymore, we are deleting it now.
+    delete context;
 }
 
 }  // namespace android
diff --git a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
index c56bf01..025261d 100644
--- a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
+++ b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
@@ -27,8 +27,10 @@
 #include <utils/threads.h>
 #include <utils/Vector.h>
 
+#include <future>
 #include <map>
 #include <memory>
+#include <set>
 #include <utility>
 #include <vector>
 
@@ -38,6 +40,7 @@
 
 using aidl::android::media::IResourceManagerClient;
 using aidl::android::media::IResourceManagerService;
+using aidl::android::media::MediaResourceParcel;
 
 bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
 
@@ -45,6 +48,9 @@
     pid_t pid;
     uid_t uid;
     int64_t clientId;
+    std::shared_ptr<IResourceManagerClient> drm;
+    int64_t resourceValue;
+
 };
 
 typedef std::map<std::vector<uint8_t>, SessionInfo> SessionInfoMap;
@@ -66,20 +72,52 @@
     size_t getSessionCount() const;
     bool containsSession(const Vector<uint8_t>& sessionId) const;
 
-    // implements DeathRecipient
-    void binderDied();
-
 protected:
     virtual ~DrmSessionManager();
 
 private:
-    void init();
+    status_t init();
 
-    std::shared_ptr<IResourceManagerService> mService;
+    // To set up the binder interface with the resource manager service.
+    void getResourceManagerService() {
+        Mutex::Autolock lock(mLock);
+        getResourceManagerService_l();
+    }
+    void getResourceManagerService_l();
+
+    // To add/register all the resources currently added/registered with
+    // the ResourceManagerService.
+    // This function will be called right after the death of the Resource
+    // Manager to make sure that the newly started ResourceManagerService
+    // knows about the current resource usage.
+    void reRegisterAllResources_l();
+
+    // For binder death handling
+    static void ResourceManagerServiceDied(void* cookie);
+    static void BinderUnlinkedCallback(void* cookie);
+    void binderDied();
+
+    // BinderDiedContext defines the cookie that is passed as DeathRecipient.
+    // Since this can maintain more context than a raw pointer, we can
+    // validate the scope of DrmSessionManager,
+    // before deferencing it upon the binder death.
+    struct BinderDiedContext {
+        wp<DrmSessionManager> mDrmSessionManager;
+    };
+
+    std::shared_ptr<IResourceManagerService> mService = nullptr;
     mutable Mutex mLock;
     SessionInfoMap mSessionMap;
-    bool mInitialized;
+    bool mBinderDied = false;
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+    /**
+     * Reconnecting with the ResourceManagerService, after its binder interface dies,
+     * is done asynchronously. It will also make sure that, all the resources
+     * asssociated with this DrmSessionManager are added with the new instance
+     * of the ResourceManagerService to persist the state of resources.
+     * We must store the reference of the furture to guarantee real asynchronous operation.
+     */
+    std::future<void> mGetServiceFuture;
 
     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
 };
diff --git a/media/audioserver/Android.bp b/media/audioserver/Android.bp
index 828d861..2030dc7 100644
--- a/media/audioserver/Android.bp
+++ b/media/audioserver/Android.bp
@@ -25,21 +25,31 @@
         "libmediametrics_headers",
     ],
 
-    shared_libs: [
-        "packagemanager_aidl-cpp",
+    defaults: [
+        "libaaudioservice_dependencies",
+        "libaudioflinger_dependencies",
+        "libaudiopolicyservice_dependencies",
+        "latest_android_media_audio_common_types_cpp_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
+    ],
+
+    static_libs: [
         "libaaudioservice",
-        "libaudioclient",
         "libaudioflinger",
         "libaudiopolicyservice",
+        "libmedialogservice",
+        "libnbaio",
+    ],
+
+    shared_libs: [
+        "libaudioclient",
         "libaudioprocessing",
         "libbinder",
         "libcutils",
         "libhidlbase",
         "liblog",
         "libmedia",
-        "libmedialogservice",
         "libmediautils",
-        "libnbaio",
         "libnblog",
         "libpowermanager",
         "libutils",
@@ -59,9 +69,9 @@
         "frameworks/av/services/audiopolicy/engine/interface",
         "frameworks/av/services/audiopolicy/service",
         "frameworks/av/services/medialog",
+        "frameworks/av/services/oboeservice", // TODO oboeservice is the old folder name for aaudioservice. It will be changed.
 
-        // TODO oboeservice is the old folder name for aaudioservice. It will be changed.
-        "frameworks/av/services/oboeservice",
+
     ],
 
     init_rc: ["audioserver.rc"],
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 3e4247b..5f5f05d 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -752,6 +752,19 @@
     return true;
 }
 
+bool C2SoftGav1Dec::fillMonochromeRow(int value) {
+    const size_t tmpSize = mWidth;
+    const bool needFill = tmpSize > mTmpFrameBufferSize;
+    if (!allocTmpFrameBuffer(tmpSize)) {
+        ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+        return false;
+    }
+    if (needFill) {
+        std::fill_n(mTmpFrameBuffer.get(), tmpSize, value);
+    }
+    return true;
+}
+
 bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
                                  const std::unique_ptr<C2Work> &work) {
   if (!(work && pool)) return false;
@@ -773,6 +786,16 @@
     return false;
   }
 
+#if LIBYUV_VERSION < 1871
+  if (buffer->bitdepth > 10) {
+    ALOGE("bitdepth %d is not supported", buffer->bitdepth);
+    mSignalledError = true;
+    work->workletsProcessed = 1u;
+    work->result = C2_CORRUPTED;
+    return false;
+  }
+#endif
+
   const int width = buffer->displayed_width[0];
   const int height = buffer->displayed_height[0];
   if (width != mWidth || height != mHeight) {
@@ -816,7 +839,7 @@
   std::shared_ptr<C2GraphicBlock> block;
   uint32_t format = HAL_PIXEL_FORMAT_YV12;
   std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects;
-  if (buffer->bitdepth == 10 && mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
+  if (buffer->bitdepth >= 10 && mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
     IntfImpl::Lock lock = mIntf->lock();
     codedColorAspects = mIntf->getColorAspects_l();
     bool allowRGBA1010102 = false;
@@ -828,8 +851,9 @@
     format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
 #if !HAVE_LIBYUV_I410_I210_TO_AB30
     if ((format == HAL_PIXEL_FORMAT_RGBA_1010102) &&
-        (buffer->image_format != libgav1::kImageFormatYuv420)) {
-        ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
+        (buffer->image_format != libgav1::kImageFormatYuv420) &&
+        (buffer->bitdepth == 10)) {
+        ALOGE("Only YUV420 output is supported for 10-bit when targeting RGBA_1010102");
       mSignalledError = true;
       work->result = C2_OMITTED;
       work->workletsProcessed = 1u;
@@ -837,6 +861,18 @@
     }
 #endif
   }
+  if (buffer->bitdepth == 12 && format == HAL_PIXEL_FORMAT_RGBA_1010102 &&
+      (buffer->image_format == libgav1::kImageFormatYuv422 ||
+       buffer->image_format == libgav1::kImageFormatYuv444)) {
+      // There are no 12-bit color conversion functions from YUV422/YUV444 to
+      // RGBA_1010102. Use 8-bit YV12 in this case.
+      format = HAL_PIXEL_FORMAT_YV12;
+  }
+  if (buffer->bitdepth == 12 && format == HAL_PIXEL_FORMAT_YCBCR_P010) {
+      // There are no 12-bit color conversion functions to P010. Use 8-bit YV12
+      // in this case.
+      format = HAL_PIXEL_FORMAT_YV12;
+  }
 
   if (mHalPixelFormat != format) {
     C2StreamPixelFormatInfo::output pixelFormat(0u, format);
@@ -890,7 +926,41 @@
   size_t dstUStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
   size_t dstVStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
 
-  if (buffer->bitdepth == 10) {
+  if (buffer->bitdepth == 12) {
+#if LIBYUV_VERSION >= 1871
+      const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
+      const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
+      const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
+      size_t srcYStride = buffer->stride[0] / 2;
+      size_t srcUStride = buffer->stride[1] / 2;
+      size_t srcVStride = buffer->stride[2] / 2;
+      if (isMonochrome) {
+          if (!fillMonochromeRow(2048)) {
+              setError(work, C2_NO_MEMORY);
+              return false;
+          }
+          srcU = srcV = mTmpFrameBuffer.get();
+          srcUStride = srcVStride = 0;
+      }
+      if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+          libyuv::I012ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+                                   dstY, dstYStride, &libyuv::kYuvV2020Constants,
+                                   mWidth, mHeight);
+      } else if (isMonochrome || buffer->image_format == libgav1::kImageFormatYuv420) {
+          libyuv::I012ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+                             dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+                             mWidth, mHeight);
+      } else if (buffer->image_format == libgav1::kImageFormatYuv444) {
+          libyuv::I412ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+                             dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+                             mWidth, mHeight);
+      } else {
+          libyuv::I212ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+                             dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+                             mWidth, mHeight);
+      }
+#endif  // LIBYUV_VERSION >= 1871
+  } else if (buffer->bitdepth == 10) {
     const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
     const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
     const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
@@ -915,18 +985,12 @@
 #endif  // HAVE_LIBYUV_I410_I210_TO_AB30
         if (!processed) {
             if (isMonochrome) {
-                const size_t tmpSize = mWidth;
-                const bool needFill = tmpSize > mTmpFrameBufferSize;
-                if (!allocTmpFrameBuffer(tmpSize)) {
-                    ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+                if (!fillMonochromeRow(512)) {
                     setError(work, C2_NO_MEMORY);
                     return false;
                 }
                 srcU = srcV = mTmpFrameBuffer.get();
                 srcUStride = srcVStride = 0;
-                if (needFill) {
-                    std::fill_n(mTmpFrameBuffer.get(), tmpSize, 512);
-                }
             }
             convertYUV420Planar16ToY410OrRGBA1010102(
                     (uint32_t *)dstY, srcY, srcU, srcV, srcYStride,
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index c3b27ea..0e09fcc 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -105,6 +105,7 @@
   // Sets |work->result| and mSignalledError. Returns false.
   void setError(const std::unique_ptr<C2Work> &work, c2_status_t error);
   bool allocTmpFrameBuffer(size_t size);
+  bool fillMonochromeRow(int value);
   bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
                     const std::unique_ptr<C2Work>& work);
   c2_status_t drainInternal(uint32_t drainMode,
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index f272499..0803dc3 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -23,6 +23,7 @@
 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
 #include <android/hardware/graphics/common/1.2/types.h>
 #include <cutils/native_handle.h>
+#include <drm/drm_fourcc.h>
 #include <gralloctypes/Gralloc4.h>
 #include <hardware/gralloc.h>
 #include <ui/GraphicBufferAllocator.h>
@@ -478,7 +479,25 @@
     // 'NATIVE' on Android means LITTLE_ENDIAN
     constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
 
-    switch (mFormat) {
+    // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
+    // possible.
+    uint32_t format = mFormat;
+    uint32_t fourCc;
+    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+        !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) {
+        switch (fourCc)  {
+            case DRM_FORMAT_XBGR8888:
+                 format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
+                 break;
+            case DRM_FORMAT_ABGR8888:
+                 format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
+                 break;
+            default:
+                 break;
+        }
+    }
+
+    switch (format) {
         case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
             // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
             // Surface. In all other cases it is RGBA. We don't know which case it is here, so
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 84c715f..93ac966 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -132,10 +132,6 @@
 
     request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());
 
-    request.getConfiguration().setHardwareSamplesPerFrame(builder.getHardwareSamplesPerFrame());
-    request.getConfiguration().setHardwareSampleRate(builder.getHardwareSampleRate());
-    request.getConfiguration().setHardwareFormat(builder.getHardwareFormat());
-
     mDeviceChannelCount = getSamplesPerFrame(); // Assume it will be the same. Update if not.
 
     mServiceStreamHandleInfo = mServiceInterface.openStream(request, configurationOutput);
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
index a3ce58c..611ddcd 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
@@ -135,10 +135,9 @@
     int coefficientIndex = 0;
     double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples
     // Stretch the sinc function for low pass filtering.
-    const float cutoffScaler = normalizedCutoff *
-            ((outputRate < inputRate)
-             ? ((float)outputRate / inputRate)
-             : ((float)inputRate / outputRate));
+    const float cutoffScaler = (outputRate < inputRate)
+             ? (normalizedCutoff * (float)outputRate / inputRate)
+             : 1.0f; // Do not filter when upsampling.
     const int numTapsHalf = getNumTaps() / 2; // numTaps must be even.
     const float numTapsHalfInverse = 1.0f / numTapsHalf;
     for (int i = 0; i < numRows; i++) {
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
index 717f3fd..9e47335 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
@@ -111,6 +111,9 @@
          * Set lower to reduce aliasing.
          * Default is 0.70.
          *
+         * Note that this value is ignored when upsampling, which is when
+         * the outputRate is higher than the inputRate.
+         *
          * @param normalizedCutoff anti-aliasing filter cutoff
          * @return address of this builder for chaining calls
          */
@@ -227,6 +230,10 @@
 
     /**
      * Generate the filter coefficients in optimal order.
+     *
+     * Note that normalizedCutoff is ignored when upsampling, which is when
+     * the outputRate is higher than the inputRate.
+     *
      * @param inputRate sample rate of the input stream
      * @param outputRate  sample rate of the output stream
      * @param numRows number of rows in the array that contain a set of tap coefficients
diff --git a/media/libaaudio/tests/test_resampler.cpp b/media/libaaudio/tests/test_resampler.cpp
index 1e4f59c..13e4a20 100644
--- a/media/libaaudio/tests/test_resampler.cpp
+++ b/media/libaaudio/tests/test_resampler.cpp
@@ -101,14 +101,20 @@
         }
     }
 
+    // Flush out remaining frames from the flowgraph
+    while (!mcResampler->isWriteNeeded()) {
+        mcResampler->readNextFrame(output);
+        output++;
+        numRead++;
+    }
+
     ASSERT_LE(numRead, kNumOutputSamples);
     // Some frames are lost priming the FIR filter.
-    const int kMaxAlgorithmicFrameLoss = 16;
+    const int kMaxAlgorithmicFrameLoss = 5;
     EXPECT_GT(numRead, kNumOutputSamples - kMaxAlgorithmicFrameLoss);
 
     int sinkZeroCrossingCount = countZeroCrossingsWithHysteresis(outputBuffer.get(), numRead);
-    // Some cycles may get chopped off at the end.
-    const int kMaxZeroCrossingDelta = 3;
+    const int kMaxZeroCrossingDelta = std::max(sinkRate / sourceRate / 2, 1);
     EXPECT_LE(abs(sourceZeroCrossingCount - sinkZeroCrossingCount), kMaxZeroCrossingDelta);
 
     // Detect glitches by looking for spikes in the second derivative.
@@ -136,8 +142,7 @@
 
 
 TEST(test_resampler, resampler_scan_all) {
-    // TODO Add 64000, 88200, 96000 when they work. Failing now.
-    const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000};
+    const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000, 64000, 88200, 96000};
     const MultiChannelResampler::Quality qualities[] =
     {
         MultiChannelResampler::Quality::Fastest,
@@ -193,10 +198,9 @@
     checkResampler(11025, 44100, MultiChannelResampler::Quality::Best);
 }
 
-// TODO This fails because the output is very low.
-//TEST(test_resampler, resampler_11025_88200_best) {
-//    checkResampler(11025, 88200, MultiChannelResampler::Quality::Best);
-//}
+TEST(test_resampler, resampler_11025_88200_best) {
+    checkResampler(11025, 88200, MultiChannelResampler::Quality::Best);
+}
 
 TEST(test_resampler, resampler_16000_48000_best) {
     checkResampler(16000, 48000, MultiChannelResampler::Quality::Best);
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 7cec2e8..871318f 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -132,12 +132,10 @@
                 binder = gAudioFlingerBinder;
             } else {
                 sp<IServiceManager> sm = defaultServiceManager();
-                do {
-                    binder = sm->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
-                    if (binder != nullptr) break;
-                    ALOGW("AudioFlinger not published, waiting...");
-                    usleep(500000); // 0.5 s
-                } while (true);
+                binder = sm->waitForService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+                if (binder == nullptr) {
+                    return nullptr;
+                }
             }
             binder->linkToDeath(gAudioFlingerClient);
             const auto afs = interface_cast<media::IAudioFlingerService>(binder);
@@ -870,14 +868,10 @@
         Mutex::Autolock _l(gLockAPS);
         if (gAudioPolicyService == 0) {
             sp<IServiceManager> sm = defaultServiceManager();
-            sp<IBinder> binder;
-            do {
-                binder = sm->getService(String16("media.audio_policy"));
-                if (binder != 0)
-                    break;
-                ALOGW("AudioPolicyService not published, waiting...");
-                usleep(500000); // 0.5 s
-            } while (true);
+            sp<IBinder> binder = sm->waitForService(String16("media.audio_policy"));
+            if (binder == nullptr) {
+                return nullptr;
+            }
             if (gAudioPolicyServiceClient == NULL) {
                 gAudioPolicyServiceClient = new AudioPolicyServiceClient();
             }
@@ -2093,8 +2087,7 @@
         return BAD_VALUE;
     }
 
-    const sp<IAudioPolicyService>
-            & aps = AudioSystem::get_audio_policy_service();
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
     std::vector<AudioFormatDescription> formatsAidl;
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
new file mode 100644
index 0000000..1ca3042
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+cc_defaults {
+    name: "libaudioclient_aidl_fuzzer_defaults",
+    static_libs: [
+        "android.hardware.audio.common@7.0-enums",
+        "effect-aidl-cpp",
+        "liblog",
+        "libbinder_random_parcel",
+        "libbase",
+        "libcgrouprc",
+        "libcgrouprc_format",
+        "libcutils",
+        "libjsoncpp",
+        "libmediametricsservice",
+        "libmedia_helper",
+        "libprocessgroup",
+        "shared-file-region-aidl-cpp",
+        "libfakeservicemanager"
+    ],
+    shared_libs: [
+        "libaudioclient",
+        "libaudioflinger",
+        "libmediautils",
+        "libnblog",
+        "libaudioprocessing",
+        "libnbaio",
+        "libpowermanager",
+        "libvibrator",
+        "packagemanager_aidl-cpp",
+        "android.hardware.audio.common-util",
+        "audioclient-types-aidl-cpp",
+        "audioflinger-aidl-cpp",
+        "audiopolicy-aidl-cpp",
+        "audiopolicy-types-aidl-cpp",
+        "av-types-aidl-cpp",
+        "capture_state_listener-aidl-cpp",
+        "libaudioclient_aidl_conversion",
+        "libaudiofoundation",
+        "libaudiomanager",
+        "libaudiopolicy",
+        "libaudioutils",
+        "libdl",
+        "libutils",
+        "libxml2",
+        "mediametricsservice-aidl-cpp",
+        "framework-permission-aidl-cpp",
+        "libvndksupport",
+        "libmediametrics",
+        "libbinder_ndk",
+        "libbinder",
+        "libfakeservicemanager",
+        "libactivitymanager_aidl",
+        "libheadtracking",
+        "libaudiopolicyservice",
+        "libsensorprivacy",
+        "libaudiopolicymanagerdefault",
+        "libaudiohal",
+        "libhidlbase",
+        "libpermission",
+        "libaudiohal@7.0",
+    ],
+    header_libs: [
+        "libaudiopolicymanager_interface_headers",
+        "libbinder_headers",
+        "libaudiofoundation_headers",
+        "libmedia_headers",
+        "libaudiohal_headers",
+        "libaudioflinger_headers",
+        "mediautils_headers",
+    ],
+     fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+        hotlists: ["4593311"],
+        description: "The fuzzer targets the APIs of libaudioflinger",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
+    },
+}
+
+cc_fuzz {
+    name: "audioflinger_aidl_fuzzer",
+    srcs: ["audioflinger_aidl_fuzzer.cpp"],
+    defaults: ["libaudioclient_aidl_fuzzer_defaults"],
+}
diff --git a/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
new file mode 100644
index 0000000..fac5f53
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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 <AudioFlinger.h>
+#include <ISchedulingPolicyService.h>
+#include <fakeservicemanager/FakeServiceManager.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_process.h>
+#include <android/media/IAudioPolicyService.h>
+#include <binder/IActivityManager.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <binder/PermissionController.h>
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/IAudioFlinger.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
+#include <service/AudioPolicyService.h>
+
+using namespace android;
+using namespace android::binder;
+using android::fuzzService;
+
+static sp<media::IAudioFlingerService> gAudioFlingerService;
+
+class FuzzerSchedulingPolicyService : public BnInterface<ISchedulingPolicyService> {
+    int32_t requestPriority(int32_t /*pid_t*/, int32_t /*tid*/, int32_t /*prio*/, bool /*isForApp*/,
+                            bool /*asynchronous*/) {
+        return 0;
+    }
+
+    int32_t requestCpusetBoost(bool /*enable*/, const sp<IBinder>& /*client*/) { return 0; }
+};
+
+class FuzzerPermissionController : public BnInterface<IPermissionController> {
+  public:
+    bool checkPermission(const String16& /*permission*/, int32_t /*pid*/, int32_t /*uid*/) {
+        return true;
+    }
+    int32_t noteOp(const String16& /*op*/, int32_t /*uid*/, const String16& /*packageName*/) {
+        return 0;
+    }
+    void getPackagesForUid(const uid_t /*uid*/, Vector<String16>& /*packages*/) {}
+    bool isRuntimePermission(const String16& /*permission*/) { return true; }
+    int32_t getPackageUid(const String16& /*package*/, int /*flags*/) { return 0; }
+};
+
+class FuzzerSensorPrivacyManager : public BnInterface<hardware::ISensorPrivacyManager> {
+  public:
+    Status supportsSensorToggle(int32_t /*toggleType*/, int32_t /*sensor*/,
+                                bool* /*_aidl_return*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status addSensorPrivacyListener(
+            const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+        return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+    }
+    Status addToggleSensorPrivacyListener(
+            const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status removeSensorPrivacyListener(
+            const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+        return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+    }
+    Status removeToggleSensorPrivacyListener(
+            const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+        return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+    }
+    Status isSensorPrivacyEnabled(bool* /*_aidl_return*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status isCombinedToggleSensorPrivacyEnabled(int32_t /*sensor*/,
+                                                bool* /*_aidl_return*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status isToggleSensorPrivacyEnabled(int32_t /*toggleType*/, int32_t /*sensor*/,
+                                        bool* /*_aidl_return*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status setSensorPrivacy(bool /*enable*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status setToggleSensorPrivacy(int32_t /*userId*/, int32_t /*source*/, int32_t /*sensor*/,
+                                  bool /*enable*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+    Status setToggleSensorPrivacyForProfileGroup(int32_t /*userId*/, int32_t /*source*/,
+                                                 int32_t /*sensor*/, bool /*enable*/) override {
+        return Status::fromStatusT(UNKNOWN_TRANSACTION);
+    }
+};
+
+class FuzzerActivityManager : public BnInterface<IActivityManager> {
+  public:
+    int32_t openContentUri(const String16& /*stringUri*/) override { return 0; }
+
+    status_t registerUidObserver(const sp<IUidObserver>& /*observer*/, const int32_t /*event*/,
+                                 const int32_t /*cutpoint*/,
+                                 const String16& /*callingPackage*/) override {
+        return OK;
+    }
+
+    status_t unregisterUidObserver(const sp<IUidObserver>& /*observer*/) override { return OK; }
+
+    bool isUidActive(const uid_t /*uid*/, const String16& /*callingPackage*/) override {
+        return true;
+    }
+
+    int32_t getUidProcessState(const uid_t /*uid*/, const String16& /*callingPackage*/) override {
+        return ActivityManager::PROCESS_STATE_UNKNOWN;
+    }
+
+    status_t checkPermission(const String16& /*permission*/, const pid_t /*pid*/,
+                             const uid_t /*uid*/, int32_t* /*outResult*/) override {
+        return NO_ERROR;
+    }
+
+    status_t registerUidObserverForUids(const sp<IUidObserver>& /*observer*/ ,
+                                        const int32_t /*event*/ ,
+                                        const int32_t /*cutpoint*/ ,
+                                        const String16& /*callingPackage*/ ,
+                                        const int32_t uids[] ,
+                                        size_t /*nUids*/ ,
+                                        /*out*/ sp<IBinder>& /*observerToken*/ ) {
+        (void)uids;
+        return OK;
+    }
+
+    status_t addUidToObserver(const sp<IBinder>& /*observerToken*/ ,
+                              const String16& /*callingPackage*/ ,
+                              int32_t /*uid*/ ) override {
+        return NO_ERROR;
+    }
+
+    status_t removeUidFromObserver(const sp<IBinder>& /*observerToken*/ ,
+                                   const String16& /*callingPackage*/ ,
+                                   int32_t /*uid*/ ) override {
+        return NO_ERROR;
+    }
+
+    status_t logFgsApiBegin(int32_t /*apiType*/ , int32_t /*appUid*/ ,
+                            int32_t /*appPid*/ ) override {
+        return NO_ERROR;
+    }
+    status_t logFgsApiEnd(int32_t /*apiType*/ , int32_t /*appUid*/ ,
+                          int32_t /*appPid*/ ) override {
+        return NO_ERROR;
+    }
+    status_t logFgsApiStateChanged(int32_t /*apiType*/ , int32_t /*state*/ ,
+                                   int32_t /*appUid*/ ,
+                                   int32_t /*appPid*/ ) override {
+        return NO_ERROR;
+    }
+};
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+    /* Create a FakeServiceManager instance and add required services */
+    sp<FakeServiceManager> fakeServiceManager = new FakeServiceManager();
+    setDefaultServiceManager(fakeServiceManager);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    sp<FuzzerActivityManager> am = new FuzzerActivityManager();
+    fakeServiceManager->addService(String16("activity"), IInterface::asBinder(am));
+
+    sp<FuzzerSensorPrivacyManager> sensorPrivacyManager = new FuzzerSensorPrivacyManager();
+    fakeServiceManager->addService(String16("sensor_privacy"),
+                                   IInterface::asBinder(sensorPrivacyManager));
+    sp<FuzzerPermissionController> permissionController = new FuzzerPermissionController();
+    fakeServiceManager->addService(String16("permission"),
+                                   IInterface::asBinder(permissionController));
+
+    sp<FuzzerSchedulingPolicyService> schedulingService = new FuzzerSchedulingPolicyService();
+    fakeServiceManager->addService(String16("scheduling_policy"),
+                                   IInterface::asBinder(schedulingService));
+
+    const auto audioFlingerObj = sp<AudioFlinger>::make();
+    const auto afAdapter = sp<AudioFlingerServerAdapter>::make(audioFlingerObj);
+
+    fakeServiceManager->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
+                                   IInterface::asBinder(afAdapter), false /* allowIsolated */,
+                                   IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+
+    const auto audioPolicyService = sp<AudioPolicyService>::make();
+    fakeServiceManager->addService(String16("media.audio_policy"), audioPolicyService,
+                                   false /* allowIsolated */,
+                                   IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+
+    sp<IBinder> binder =
+            fakeServiceManager->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+    gAudioFlingerService = interface_cast<media::IAudioFlingerService>(binder);
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (!gAudioFlingerService) {
+        return 0;
+    }
+
+    fuzzService(media::IAudioFlingerService::asBinder(gAudioFlingerService),
+                FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 2ba1fc3..6834b7d 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -476,35 +476,37 @@
 }
 
 bool HeifDecoderImpl::setOutputColor(HeifColorFormat heifColor) {
-    if (heifColor == (HeifColorFormat)mOutputColor) {
-        return true;
-    }
-
+    android_pixel_format_t outputColor;
     switch(heifColor) {
         case kHeifColorFormat_RGB565:
         {
-            mOutputColor = HAL_PIXEL_FORMAT_RGB_565;
+            outputColor = HAL_PIXEL_FORMAT_RGB_565;
             break;
         }
         case kHeifColorFormat_RGBA_8888:
         {
-            mOutputColor = HAL_PIXEL_FORMAT_RGBA_8888;
+            outputColor = HAL_PIXEL_FORMAT_RGBA_8888;
             break;
         }
         case kHeifColorFormat_BGRA_8888:
         {
-            mOutputColor = HAL_PIXEL_FORMAT_BGRA_8888;
+            outputColor = HAL_PIXEL_FORMAT_BGRA_8888;
             break;
         }
         case kHeifColorFormat_RGBA_1010102:
         {
-            mOutputColor = HAL_PIXEL_FORMAT_RGBA_1010102;
+            outputColor = HAL_PIXEL_FORMAT_RGBA_1010102;
             break;
         }
         default:
             ALOGE("Unsupported output color format %d", heifColor);
             return false;
     }
+    if (outputColor == mOutputColor) {
+        return true;
+    }
+
+    mOutputColor = outputColor;
 
     if (mFrameDecoded) {
         return reinit(nullptr);
diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp
index c43ef66..f498453 100644
--- a/media/libmedia/IMediaDeathNotifier.cpp
+++ b/media/libmedia/IMediaDeathNotifier.cpp
@@ -38,16 +38,10 @@
     Mutex::Autolock _l(sServiceLock);
     if (sMediaPlayerService == 0) {
         sp<IServiceManager> sm = defaultServiceManager();
-        sp<IBinder> binder;
-        do {
-            binder = sm->getService(String16("media.player"));
-            if (binder != 0) {
-                break;
-            }
-            ALOGW("Media player service not published, waiting...");
-            usleep(500000); // 0.5 s
-        } while (true);
-
+        sp<IBinder> binder = sm->waitForService(String16("media.player"));
+        if (binder == nullptr) {
+            return nullptr;
+        }
         if (sDeathNotifier == NULL) {
             sDeathNotifier = new DeathNotifier();
         }
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 2ae76b3..40fd022 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -41,14 +41,10 @@
     if (sService == 0) {
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
-        do {
-            binder = sm->getService(String16("media.player"));
-            if (binder != 0) {
-                break;
-            }
-            ALOGW("MediaPlayerService not published, waiting...");
-            usleep(500000); // 0.5 s
-        } while (true);
+        binder = sm->waitForService(String16("media.player"));
+        if (binder == nullptr) {
+            return nullptr;
+        }
         if (sDeathNotifier == NULL) {
             sDeathNotifier = new DeathNotifier();
         }
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index 89e9806..434ae00 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -49,7 +49,7 @@
     defaults: ["libnbaio_mono_defaults"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libnbaio",
     defaults: ["libnbaio_mono_defaults"],
     srcs: [
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 54ca1ea..5a651fa 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -21,9 +21,9 @@
 
 #include <dlfcn.h>
 #include <inttypes.h>
+#include <future>
 #include <random>
 #include <set>
-#include <stdlib.h>
 #include <string>
 
 #include <C2Buffer.h>
@@ -31,7 +31,6 @@
 #include "include/SoftwareRenderer.h"
 
 #include <android/api-level.h>
-#include <android/binder_manager.h>
 #include <android/content/pm/IPackageManagerNative.h>
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
@@ -74,7 +73,6 @@
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaCodecList.h>
-#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/OMXClient.h>
@@ -291,6 +289,10 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+/*
+ * Implementation of IResourceManagerClient interrface that facilitates
+ * MediaCodec reclaim for the ResourceManagerService.
+ */
 struct ResourceManagerClient : public BnResourceManagerClient {
     explicit ResourceManagerClient(MediaCodec* codec, int32_t pid, int32_t uid) :
             mMediaCodec(codec), mPid(pid), mUid(uid) {}
@@ -303,7 +305,9 @@
             std::shared_ptr<IResourceManagerService> service =
                     IResourceManagerService::fromBinder(binder);
             if (service == nullptr) {
-                ALOGW("MediaCodec::ResourceManagerClient unable to find ResourceManagerService");
+                ALOGE("MediaCodec::ResourceManagerClient unable to find ResourceManagerService");
+                *_aidl_return = false;
+                return Status::fromStatus(STATUS_INVALID_OPERATION);
             }
             ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
@@ -351,21 +355,25 @@
     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
 };
 
-struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
+/*
+ * Proxy for ResourceManagerService that communicates with the
+ * ResourceManagerService for MediaCodec
+ */
+struct MediaCodec::ResourceManagerServiceProxy :
+    public std::enable_shared_from_this<ResourceManagerServiceProxy> {
+
+    // BinderDiedContext defines the cookie that is passed as DeathRecipient.
+    // Since this can maintain more context than a raw pointer, we can
+    // validate the scope of ResourceManagerServiceProxy,
+    // before deferencing it upon the binder death.
+    struct BinderDiedContext {
+        std::weak_ptr<ResourceManagerServiceProxy> mRMServiceProxy;
+    };
+
     ResourceManagerServiceProxy(pid_t pid, uid_t uid,
             const std::shared_ptr<IResourceManagerClient> &client);
-    virtual ~ResourceManagerServiceProxy();
-
+    ~ResourceManagerServiceProxy();
     status_t init();
-
-    // implements DeathRecipient
-    static void BinderDiedCallback(void* cookie);
-    void binderDied();
-    static Mutex sLockCookies;
-    static std::set<void*> sCookies;
-    static void addCookie(void* cookie);
-    static void removeCookie(void* cookie);
-
     void addResource(const MediaResourceParcel &resource);
     void removeResource(const MediaResourceParcel &resource);
     void removeClient();
@@ -381,50 +389,92 @@
     }
 
 private:
-    Mutex mLock;
+    // To get the binder interface to ResourceManagerService.
+    void getService() {
+        std::scoped_lock lock{mLock};
+        getService_l();
+    }
+
+    std::shared_ptr<IResourceManagerService> getService_l();
+
+    // To add/register all the resources currently added/registered with
+    // the ResourceManagerService.
+    // This function will be called right after the death of the Resource
+    // Manager to make sure that the newly started ResourceManagerService
+    // knows about the current resource usage.
+    void reRegisterAllResources_l();
+
+    void deinit() {
+        std::scoped_lock lock{mLock};
+        // Unregistering from DeathRecipient notification.
+        if (mService != nullptr) {
+            AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+            mService = nullptr;
+        }
+    }
+
+    // For binder death handling
+    static void BinderDiedCallback(void* cookie);
+    static void BinderUnlinkedCallback(void* cookie);
+
+    void binderDied() {
+        std::scoped_lock lock{mLock};
+        ALOGE("ResourceManagerService died.");
+        mService = nullptr;
+        mBinderDied = true;
+        // start an async operation that will reconnect with the RM and
+        // re-registers all the resources.
+        mGetServiceFuture = std::async(std::launch::async, [this] { getService(); });
+    }
+
+
+private:
+    std::mutex mLock;
     pid_t mPid;
     uid_t mUid;
+    bool mBinderDied = false;
     std::string mCodecName;
-    std::shared_ptr<IResourceManagerService> mService;
+    /**
+     * Reconnecting with the ResourceManagerService, after its binder interface dies,
+     * is done asynchronously. It will also make sure that, all the resources
+     * asssociated with this Proxy (MediaCodec) is added with the new instance
+     * of the ResourceManagerService to persist the state of resources.
+     * We must store the reference of the furture to guarantee real asynchronous operation.
+     */
+    std::future<void> mGetServiceFuture;
+    // To maintain the list of all the resources currently added/registered with
+    // the ResourceManagerService.
+    std::set<MediaResourceParcel> mMediaResourceParcel;
     std::shared_ptr<IResourceManagerClient> mClient;
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+    std::shared_ptr<IResourceManagerService> mService;
 };
 
 MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
-        pid_t pid, uid_t uid, const std::shared_ptr<IResourceManagerClient> &client)
-        : mPid(pid), mUid(uid), mClient(client),
-          mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
+        pid_t pid, uid_t uid, const std::shared_ptr<IResourceManagerClient> &client) :
+    mPid(pid), mUid(uid), mClient(client),
+    mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
+            AIBinder_DeathRecipient_new(BinderDiedCallback))) {
     if (mUid == MediaCodec::kNoUid) {
         mUid = AIBinder_getCallingUid();
     }
     if (mPid == MediaCodec::kNoPid) {
         mPid = AIBinder_getCallingPid();
     }
+    // Setting callback notification when DeathRecipient gets deleted.
+    AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), BinderUnlinkedCallback);
 }
 
 MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
-
-    // remove the cookie, so any in-flight death notification will get dropped
-    // by our handler.
-    removeCookie(this);
-
-    Mutex::Autolock _l(mLock);
-    if (mService != nullptr) {
-        AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
-        mService = nullptr;
-    }
+    deinit();
 }
 
 status_t MediaCodec::ResourceManagerServiceProxy::init() {
-    ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.resource_manager"));
-    mService = IResourceManagerService::fromBinder(binder);
-    if (mService == nullptr) {
-        ALOGE("Failed to get ResourceManagerService");
-        return UNKNOWN_ERROR;
-    }
+    std::scoped_lock lock{mLock};
 
     int callerPid = AIBinder_getCallingPid();
     int callerUid = AIBinder_getCallingUid();
+
     if (mPid != callerPid || mUid != callerUid) {
         // Media processes don't need special permissions to act on behalf of other processes.
         if (callerUid != AID_MEDIA) {
@@ -437,60 +487,57 @@
         }
     }
 
+    mService = getService_l();
+    if (mService == nullptr) {
+        return DEAD_OBJECT;
+    }
+
     // Kill clients pending removal.
     mService->reclaimResourcesFromClientsPendingRemoval(mPid);
-
-    // so our handler will process the death notifications
-    addCookie(this);
-
-    // after this, require mLock whenever using mService
-    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
     return OK;
 }
 
-//static
-// these are no_destroy to keep them from being destroyed at process exit
-// where some thread calls exit() while other threads are still running.
-// see b/194783918
-[[clang::no_destroy]] Mutex MediaCodec::ResourceManagerServiceProxy::sLockCookies;
-[[clang::no_destroy]] std::set<void*> MediaCodec::ResourceManagerServiceProxy::sCookies;
-
-//static
-void MediaCodec::ResourceManagerServiceProxy::addCookie(void* cookie) {
-    Mutex::Autolock _l(sLockCookies);
-    sCookies.insert(cookie);
-}
-
-//static
-void MediaCodec::ResourceManagerServiceProxy::removeCookie(void* cookie) {
-    Mutex::Autolock _l(sLockCookies);
-    sCookies.erase(cookie);
-}
-
-//static
-void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
-    Mutex::Autolock _l(sLockCookies);
-    if (sCookies.find(cookie) != sCookies.end()) {
-        auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
-        thiz->binderDied();
+std::shared_ptr<IResourceManagerService> MediaCodec::ResourceManagerServiceProxy::getService_l() {
+    if (mService != nullptr) {
+        return mService;
     }
-}
 
-void MediaCodec::ResourceManagerServiceProxy::binderDied() {
-    ALOGW("ResourceManagerService died.");
-    Mutex::Autolock _l(mLock);
-    mService = nullptr;
-}
-
-void MediaCodec::ResourceManagerServiceProxy::addResource(
-        const MediaResourceParcel &resource) {
-    std::vector<MediaResourceParcel> resources;
-    resources.push_back(resource);
-
-    Mutex::Autolock _l(mLock);
+    // Get binder interface to resource manager.
+    ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.resource_manager"));
+    mService = IResourceManagerService::fromBinder(binder);
     if (mService == nullptr) {
+        ALOGE("Failed to get ResourceManagerService");
+        return mService;
+    }
+
+    // Create the context that is passed as cookie to the binder death notification.
+    // The context gets deleted at BinderUnlinkedCallback.
+    BinderDiedContext* context = new BinderDiedContext{.mRMServiceProxy = weak_from_this()};
+    // Register for the callbacks by linking to death notification.
+    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), context);
+
+    // If the RM was restarted, re-register all the resources.
+    if (mBinderDied) {
+        reRegisterAllResources_l();
+        mBinderDied = false;
+    }
+    return mService;
+}
+
+void MediaCodec::ResourceManagerServiceProxy::reRegisterAllResources_l() {
+    if (mMediaResourceParcel.empty()) {
+        ALOGV("No resources to add");
         return;
     }
+
+    if (mService == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
+
+    std::vector<MediaResourceParcel> resources;
+    std::copy(mMediaResourceParcel.begin(), mMediaResourceParcel.end(),
+              std::back_inserter(resources));
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
@@ -498,50 +545,98 @@
     mService->addResource(clientInfo, mClient, resources);
 }
 
-void MediaCodec::ResourceManagerServiceProxy::removeResource(
-        const MediaResourceParcel &resource) {
-    std::vector<MediaResourceParcel> resources;
-    resources.push_back(resource);
+void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
 
-    Mutex::Autolock _l(mLock);
-    if (mService == nullptr) {
+    // Validate the context and check if the ResourceManagerServiceProxy object is still in scope.
+    if (context != nullptr) {
+        std::shared_ptr<ResourceManagerServiceProxy> thiz = context->mRMServiceProxy.lock();
+        if (thiz != nullptr) {
+            thiz->binderDied();
+        } else {
+            ALOGI("ResourceManagerServiceProxy is out of scope already");
+        }
+    }
+}
+
+void MediaCodec::ResourceManagerServiceProxy::BinderUnlinkedCallback(void* cookie) {
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+    // Since we don't need the context anymore, we are deleting it now.
+    delete context;
+}
+
+void MediaCodec::ResourceManagerServiceProxy::addResource(
+        const MediaResourceParcel &resource) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
         return;
     }
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
                                 .name = mCodecName};
-    mService->removeResource(clientInfo, resources);
+    service->addResource(clientInfo, mClient, resources);
+    mMediaResourceParcel.emplace(resource);
+}
+
+void MediaCodec::ResourceManagerServiceProxy::removeResource(
+        const MediaResourceParcel &resource) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
+    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+                                .uid = static_cast<int32_t>(mUid),
+                                .id = getId(mClient),
+                                .name = mCodecName};
+    service->removeResource(clientInfo, resources);
+    mMediaResourceParcel.erase(resource);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::removeClient() {
-    Mutex::Autolock _l(mLock);
-    if (mService == nullptr) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
         return;
     }
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
                                 .name = mCodecName};
-    mService->removeClient(clientInfo);
+    service->removeClient(clientInfo);
+    mMediaResourceParcel.clear();
 }
 
 void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() {
-    Mutex::Autolock _l(mLock);
-    if (mService == nullptr) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
         return;
     }
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
                                 .name = mCodecName};
-    mService->markClientForPendingRemoval(clientInfo);
+    service->markClientForPendingRemoval(clientInfo);
+    mMediaResourceParcel.clear();
 }
 
 bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
         const std::vector<MediaResourceParcel> &resources) {
-    Mutex::Autolock _l(mLock);
-    if (mService == NULL) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
         return false;
     }
     bool success;
@@ -549,43 +644,67 @@
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
                                 .name = mCodecName};
-    Status status = mService->reclaimResource(clientInfo, resources, &success);
+    Status status = service->reclaimResource(clientInfo, resources, &success);
     return status.isOk() && success;
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientCreated() {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
     ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
                                 .uid = static_cast<int32_t>(mUid),
                                 .id = getId(mClient),
                                 .name = mCodecName};
-    mService->notifyClientCreated(clientInfo);
+    service->notifyClientCreated(clientInfo);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientStarted(
         ClientConfigParcel& clientConfig) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
     clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
     clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
     clientConfig.clientInfo.id = getId(mClient);
     clientConfig.clientInfo.name = mCodecName;
-    mService->notifyClientStarted(clientConfig);
+    service->notifyClientStarted(clientConfig);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientStopped(
         ClientConfigParcel& clientConfig) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
     clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
     clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
     clientConfig.clientInfo.id = getId(mClient);
     clientConfig.clientInfo.name = mCodecName;
-    mService->notifyClientStopped(clientConfig);
+    service->notifyClientStopped(clientConfig);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::notifyClientConfigChanged(
         ClientConfigParcel& clientConfig) {
+    std::scoped_lock lock{mLock};
+    std::shared_ptr<IResourceManagerService> service = getService_l();
+    if (service == nullptr) {
+        ALOGW("Service isn't available");
+        return;
+    }
     clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
     clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
     clientConfig.clientInfo.id = getId(mClient);
     clientConfig.clientInfo.name = mCodecName;
-    mService->notifyClientConfigChanged(clientConfig);
+    service->notifyClientConfigChanged(clientConfig);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1041,7 +1160,7 @@
       mGetCodecBase(getCodecBase),
       mGetCodecInfo(getCodecInfo) {
     mCodecId = GenerateCodecId();
-    mResourceManagerProxy = new ResourceManagerServiceProxy(pid, uid,
+    mResourceManagerProxy = std::make_shared<ResourceManagerServiceProxy>(pid, uid,
             ::ndk::SharedRefBase::make<ResourceManagerClient>(this, pid, uid));
     if (!mGetCodecBase) {
         mGetCodecBase = [](const AString &name, const char *owner) {
@@ -2281,9 +2400,11 @@
     std::vector<MediaResourceParcel> resources;
     resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
             toMediaResourceSubType(mDomain)));
-    // Don't know the buffer size at this point, but it's fine to use 1 because
-    // the reclaimResource call doesn't consider the requester's buffer size for now.
-    resources.push_back(MediaResource::GraphicMemoryResource(1));
+    if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
+        // Don't know the buffer size at this point, but it's fine to use 1 because
+        // the reclaimResource call doesn't consider the requester's buffer size for now.
+        resources.push_back(MediaResource::GraphicMemoryResource(1));
+    }
     for (int i = 0; i <= kMaxRetry; ++i) {
         sp<AMessage> response;
         err = PostAndAwaitResponse(msg, &response);
@@ -2884,9 +3005,11 @@
     std::vector<MediaResourceParcel> resources;
     resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
             toMediaResourceSubType(mDomain)));
-    // Don't know the buffer size at this point, but it's fine to use 1 because
-    // the reclaimResource call doesn't consider the requester's buffer size for now.
-    resources.push_back(MediaResource::GraphicMemoryResource(1));
+    if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
+        // Don't know the buffer size at this point, but it's fine to use 1 because
+        // the reclaimResource call doesn't consider the requester's buffer size for now.
+        resources.push_back(MediaResource::GraphicMemoryResource(1));
+    }
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 144ea53..3a4a34a 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -473,7 +473,7 @@
     sp<AMessage> mAsyncReleaseCompleteNotification;
     sp<AMessage> mOnFirstTunnelFrameReadyNotification;
 
-    sp<ResourceManagerServiceProxy> mResourceManagerProxy;
+    std::shared_ptr<ResourceManagerServiceProxy> mResourceManagerProxy;
 
     Domain mDomain;
     AString mLogSessionId;
diff --git a/media/libstagefright/rtsp/fuzzer/Android.bp b/media/libstagefright/rtsp/fuzzer/Android.bp
new file mode 100644
index 0000000..8e10b0c
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/Android.bp
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2023 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+cc_defaults {
+    name: "libstagefright_rtsp_fuzzer_defaults",
+    shared_libs: [
+        "liblog",
+        "libmedia",
+        "libutils",
+        "libstagefright_foundation",
+    ],
+    static_libs: [
+        "libdatasource",
+        "libstagefright_rtsp",
+    ],
+    header_libs: [
+        "libstagefright_rtsp_headers",
+    ],
+    fuzz_config:{
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
+
+cc_fuzz {
+    name: "sdploader_fuzzer",
+    srcs: [
+        "sdploader_fuzzer.cpp",
+    ],
+    defaults: [
+        "libstagefright_rtsp_fuzzer_defaults",
+    ]
+}
+
+cc_fuzz {
+    name: "rtp_writer_fuzzer",
+    srcs: [
+        "rtp_writer_fuzzer.cpp",
+    ],
+    defaults: [
+        "libstagefright_rtsp_fuzzer_defaults",
+    ],
+    shared_libs:[
+        "libandroid_net",
+        "libbase",
+        "libstagefright",
+        "libcutils",
+    ],
+}
diff --git a/media/libstagefright/rtsp/fuzzer/README.md b/media/libstagefright/rtsp/fuzzer/README.md
new file mode 100644
index 0000000..657fb48
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/README.md
@@ -0,0 +1,64 @@
+# Fuzzers for libstagefright_rtsp
+
+## Table of contents
++ [sdploader_fuzzer](#SDPLoader)
++ [rtp_writer_fuzzer](#ARTPWriter)
+
+# <a name="SDPLoader"></a> Fuzzer for SDPLoader
+
+SDPLoader supports the following parameters:
+1. Flag (parameter name: "flags")
+2. URL (parameter name: "url")
+3. Header (parameter name: "headers")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`flags`| `UINT32_MIN`  to  `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`url`| `String` |Value obtained from FuzzedDataProvider|
+|`headers`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) sdploader_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/sdploader_fuzzer/sdploader_fuzzer
+```
+
+# <a name="ARTPWriter"></a> Fuzzer for ARTPWriter
+
+ARTPWriter supports the following parameters:
+1. File descriptor (parameter name: "fd")
+2. Local Ip (parameter name: "localIp")
+3. Local Port (parameter name: "localPort")
+4. Remote Ip (parameter name: "remoteIp")
+5. Remote Port (parameter name: "remotePort")
+6. Sequence No (parameter name: "seqNo")
+7. OpponentID (parameter name: "opponentID")
+8. Bit Rate (parameter name: "bitrate")
+9. kKeyMIMETypeArray (parameter name: "mimeType")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`localIp`| `String` |Value obtained from FuzzedDataProvider|
+|`localPort`| `UINT32_MIN`  to  `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`remoteIp`| `String` |Value obtained from FuzzedDataProvider|
+|`remotePort`| `UINT32_MIN`  to  `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`seqNo`| `0`  to  `10000000` |Value obtained from FuzzedDataProvider|
+|`opponentID`| `UINT32_MIN`  to  `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`bitrate`| `UINT32_MIN`  to  `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`mimeType`| 0. `MEDIA_MIMETYPE_VIDEO_AVC`<br> 1. `MEDIA_MIMETYPE_VIDEO_HEVC`<br> 2. `MEDIA_MIMETYPE_VIDEO_H263`<br> 3. `MEDIA_MIMETYPE_AUDIO_AMR_NB`<br> 4. `MEDIA_MIMETYPE_AUDIO_AMR_WB`|Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) rtp_writer_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/rtp_writer_fuzzer/rtp_writer_fuzzer
+```
diff --git a/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp b/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp
new file mode 100644
index 0000000..8d9f923
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/rtsp/ARTPWriter.h>
+
+constexpr int32_t kMinSize = 0;
+constexpr int32_t kMaxSize = 65536;
+constexpr int32_t kMaxTime = 1000;
+constexpr int32_t kMaxBytes = 128;
+constexpr int32_t kAMRNBFrameSizes[] = {13, 14, 16, 18, 20, 21, 27, 32};
+constexpr int32_t kAMRWBFrameSizes[] = {18, 24, 33, 37, 41, 47, 51, 59, 61};
+constexpr int32_t kAMRIndexOffset = 8;
+
+using namespace android;
+
+const char* kKeyMimeTypeArray[] = {MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_HEVC,
+                                   MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AMR_NB,
+                                   MEDIA_MIMETYPE_AUDIO_AMR_WB};
+
+struct TestMediaSource : public MediaSource {
+  public:
+    TestMediaSource(FuzzedDataProvider& mFdp) : mTestMetaData(new MetaData) {
+        int32_t vectorSize = 0;
+        mAllowRead = mFdp.ConsumeBool();
+        mKeySps = mFdp.ConsumeIntegral<int32_t>();
+        mKeyVps = mFdp.ConsumeIntegral<int32_t>();
+        mKeyPps = mFdp.ConsumeIntegral<int32_t>();
+        mKeyTime = mFdp.ConsumeIntegralInRange<int64_t>(kMinSize, kMaxTime);
+
+        mMimeType = mFdp.PickValueInArray(kKeyMimeTypeArray);
+        mTestMetaData->setCString(kKeyMIMEType, mMimeType);
+        if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_NB) {
+            int32_t index =
+                    mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRNBFrameSizes) - 1);
+            vectorSize = kAMRNBFrameSizes[index];
+            mData.push_back(kAMRIndexOffset * index);
+        } else if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB) {
+            int32_t index =
+                    mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRWBFrameSizes) - 1);
+            vectorSize = kAMRWBFrameSizes[index];
+            mData.push_back(kAMRIndexOffset * index);
+        } else if (mMimeType == MEDIA_MIMETYPE_VIDEO_H263) {
+            // Required format for H263 media data
+            mData.push_back(0);
+            mData.push_back(0);
+            vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+        } else {
+            vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+        }
+        for (size_t idx = mData.size(); idx < vectorSize; ++idx) {
+            mData.push_back(mFdp.ConsumeIntegral<uint8_t>());
+        }
+    }
+    virtual status_t start(MetaData* /*params*/) { return OK; }
+    virtual status_t stop() { return OK; }
+    virtual sp<MetaData> getFormat() { return mTestMetaData; }
+    virtual status_t read(MediaBufferBase** buffer, const ReadOptions* /*options*/) {
+        if (!mAllowRead) {
+            return -1;
+        }
+        *buffer = new MediaBuffer(mData.data() /*data*/, mData.size() /*size*/);
+        if (mKeySps) {
+            (*buffer)->meta_data().setInt32(kKeySps, mKeySps);
+        }
+        if (mKeyVps) {
+            (*buffer)->meta_data().setInt32(kKeyVps, mKeyVps);
+        }
+        if (mKeyPps) {
+            (*buffer)->meta_data().setInt32(kKeyPps, mKeyPps);
+        }
+        (*buffer)->meta_data().setInt64(kKeyTime, mKeyTime);
+        return OK;
+    }
+
+  private:
+    int32_t mKeySps;
+    int32_t mKeyVps;
+    int32_t mKeyPps;
+    int64_t mKeyTime;
+    bool mAllowRead;
+    const char* mMimeType;
+    sp<MetaData> mTestMetaData;
+    std::vector<uint8_t> mData;
+};
+
+class ARTPWriterFuzzer {
+  public:
+    ARTPWriterFuzzer(const uint8_t* data, size_t size)
+        : mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)), mFdp(data, size) {}
+    ~ARTPWriterFuzzer() { close(mDataSourceFd); }
+    void process();
+
+  private:
+    void createARTPWriter();
+    const int32_t mDataSourceFd;
+    FuzzedDataProvider mFdp;
+    sp<ARTPWriter> mArtpWriter;
+};
+
+void ARTPWriterFuzzer::createARTPWriter() {
+    String8 localIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
+    String8 remoteIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
+    mArtpWriter = sp<ARTPWriter>::make(
+            mDataSourceFd, localIp, mFdp.ConsumeIntegral<uint16_t>() /* localPort */, remoteIp,
+            mFdp.ConsumeIntegral<uint16_t>() /* remotePort */,
+            mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize) /* seqNo */);
+}
+
+void ARTPWriterFuzzer::process() {
+    if (mFdp.ConsumeBool()) {
+        mArtpWriter = sp<ARTPWriter>::make(mDataSourceFd);
+        if (mArtpWriter->getSequenceNum() > kMaxSize) {
+            createARTPWriter();
+        }
+    } else {
+        createARTPWriter();
+    }
+
+    mArtpWriter->addSource(sp<TestMediaSource>::make(mFdp) /* source */);
+
+    while (mFdp.remaining_bytes()) {
+        auto invokeRTPWriterFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    sp<MetaData> metaData = sp<MetaData>::make();
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt32(kKeySelfID, mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt32(kKeyPayloadType, mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt32(kKeyRtpExtMap, mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt32(kKeyRtpCvoDegrees, mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt32(kKeyRtpDscp, mFdp.ConsumeIntegral<int32_t>());
+                    }
+                    if (mFdp.ConsumeBool()) {
+                        metaData->setInt64(kKeySocketNetwork, mFdp.ConsumeIntegral<int64_t>());
+                    }
+                    mArtpWriter->start(metaData.get() /*param*/);
+                },
+                [&]() {
+                    mArtpWriter->setTMMBNInfo(mFdp.ConsumeIntegral<uint32_t>() /* opponentID */,
+                                              mFdp.ConsumeIntegral<uint32_t>() /* bitrate */);
+                },
+                [&]() { mArtpWriter->stop(); },
+                [&]() {
+                    mArtpWriter->updateCVODegrees(mFdp.ConsumeIntegral<int32_t>() /* cvoDegrees */);
+                },
+                [&]() {
+                    mArtpWriter->updatePayloadType(
+                            mFdp.ConsumeIntegral<int32_t>() /* payloadType */);
+                },
+
+        });
+        invokeRTPWriterFuzzer();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    ARTPWriterFuzzer artpWriterFuzzer(data, size);
+    artpWriterFuzzer.process();
+    return 0;
+}
diff --git a/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp b/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp
new file mode 100644
index 0000000..748e5b6
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <datasource/HTTPBase.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/rtsp/SDPLoader.h>
+
+using namespace android;
+
+constexpr int32_t kMinCapacity = 0;
+constexpr int32_t kMaxCapacity = 1000;
+constexpr int32_t kMaxStringLength = 20;
+constexpr int32_t kMaxBytes = 128;
+enum { kWhatLoad = 'load' };
+
+struct FuzzAHandler : public AHandler {
+  public:
+    FuzzAHandler(std::function<void()> signalEosFunction) : mSignalEosFunction(signalEosFunction) {}
+
+  protected:
+    void onMessageReceived(const sp<AMessage>& msg) override {
+        switch (msg->what()) {
+            case kWhatLoad: {
+                mSignalEosFunction();
+                break;
+            }
+        }
+        return;
+    }
+
+  private:
+    std::function<void()> mSignalEosFunction;
+};
+
+struct FuzzMediaHTTPConnection : public MediaHTTPConnection {
+  public:
+    FuzzMediaHTTPConnection(FuzzedDataProvider* fdp) : mFdp(fdp) {
+        mSize = mFdp->ConsumeIntegralInRange(kMinCapacity, kMaxCapacity);
+        mData = mFdp->ConsumeBytes<uint8_t>(mSize);
+        mSize = mData.size();
+    }
+    virtual bool connect(const char* /* uri */,
+                         const KeyedVector<String8, String8>* /* headers */) {
+        return mFdp->ConsumeBool();
+    }
+    virtual void disconnect() { return; }
+    virtual ssize_t readAt(off64_t offset, void* data, size_t size) {
+        if ((size + offset <= mData.size()) && (offset >= 0)) {
+           memcpy(data, mData.data() + offset, size);
+           return size;
+        }
+        return 0;
+    }
+    virtual off64_t getSize() { return mSize; }
+    virtual status_t getMIMEType(String8* /*mimeType*/) {return mFdp->ConsumeIntegral<status_t>();}
+    virtual status_t getUri(String8* /*uri*/) {return mFdp->ConsumeIntegral<status_t>();}
+
+  private:
+    FuzzedDataProvider* mFdp = nullptr;
+    std::vector<uint8_t> mData;
+    size_t mSize = 0;
+};
+
+struct FuzzMediaHTTPService : public MediaHTTPService {
+  public:
+    FuzzMediaHTTPService(FuzzedDataProvider* fdp) : mFdp(fdp) {}
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() {
+        mediaHTTPConnection = sp<FuzzMediaHTTPConnection>::make(mFdp);
+        return mediaHTTPConnection;
+    }
+
+  private:
+    sp<FuzzMediaHTTPConnection> mediaHTTPConnection = nullptr;
+    FuzzedDataProvider* mFdp = nullptr;
+};
+
+class SDPLoaderFuzzer {
+  public:
+    SDPLoaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {}
+    void process();
+
+  private:
+    void signalEos();
+
+    bool mEosReached = false;
+    std::mutex mMsgPostCompleteMutex;
+    std::condition_variable mConditionalVariable;
+    FuzzedDataProvider mFdp;
+};
+
+void SDPLoaderFuzzer::signalEos() {
+    mEosReached = true;
+    mConditionalVariable.notify_one();
+    return;
+}
+
+void SDPLoaderFuzzer::process() {
+    sp<FuzzAHandler> handler = sp<FuzzAHandler>::make(std::bind(&SDPLoaderFuzzer::signalEos, this));
+    sp<ALooper> looper = sp<ALooper>::make();
+    looper->start();
+    looper->registerHandler(handler);
+    const sp<AMessage> notify = sp<AMessage>::make(kWhatLoad, handler);
+    sp<SDPLoader> sdpLoader =
+            sp<SDPLoader>::make(notify, mFdp.ConsumeIntegral<uint32_t>() /* flags */,
+                                sp<FuzzMediaHTTPService>::make(&mFdp) /* httpService */);
+
+    KeyedVector<String8, String8> headers;
+    for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange<size_t>(kMinCapacity, kMaxCapacity);
+         ++idx) {
+        headers.add(String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* key */,
+                    String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* value */);
+    }
+
+    sdpLoader->load(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* url */, &headers);
+
+    std::unique_lock waitForMsgPostComplete(mMsgPostCompleteMutex);
+    mConditionalVariable.wait(waitForMsgPostComplete, [this] { return mEosReached; });
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    SDPLoaderFuzzer sdpLoaderFuzzer(data, size);
+    sdpLoaderFuzzer.process();
+    return 0;
+}
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 38cf29d..184e4f4 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -2007,7 +2007,7 @@
             uint8_t mhac_header[mhac_header_size];
             off64_t data_offset = *offset;
 
-            if (chunk_size < sizeof(mhac_header)) {
+            if (mLastTrack == NULL || chunk_size < sizeof(mhac_header)) {
                 return ERROR_MALFORMED;
             }
 
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 067c8f4..0f7d98b 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -570,6 +570,9 @@
     }
 }
 
+// The LL-NDK API is now deprecated. New devices will no longer have the token
+// manager service installed, so createHalToken will return false and this
+// will return AMEDIA_ERROR_UNKNOWN on those devices.
 media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) {
     if (mWindowHandle != nullptr) {
         *handle = mWindowHandle;
diff --git a/media/ndk/fuzzer/Android.bp b/media/ndk/fuzzer/Android.bp
index a3d6a96..6d7dda9 100644
--- a/media/ndk/fuzzer/Android.bp
+++ b/media/ndk/fuzzer/Android.bp
@@ -56,6 +56,14 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 155276,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of libmediandk library",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
 
@@ -116,3 +124,16 @@
     header_libs: ["libnativewindow_headers",],
     defaults: ["libmediandk_fuzzer_defaults",],
 }
+
+cc_fuzz {
+    name: "ndk_async_codec_fuzzer",
+    srcs: [
+           "ndk_async_codec_fuzzer.cpp",
+           "NdkMediaCodecFuzzerBase.cpp",
+          ],
+    header_libs: [
+           "libnativewindow_headers",
+           "libutils_headers",
+          ],
+    defaults: ["libmediandk_fuzzer_defaults",],
+}
diff --git a/media/ndk/fuzzer/README.md b/media/ndk/fuzzer/README.md
index 0fd08b0..7f6bdd7 100644
--- a/media/ndk/fuzzer/README.md
+++ b/media/ndk/fuzzer/README.md
@@ -8,6 +8,7 @@
 + [ndk_drm_fuzzer](#NdkDrm)
 + [ndk_mediamuxer_fuzzer](#NdkMediaMuxer)
 + [ndk_sync_codec_fuzzer](#NdkSyncCodec)
++ [ndk_async_codec_fuzzer](#NdkAsyncCodec)
 
 # <a name="NdkCrypto"></a> Fuzzer for NdkCrypto
 
@@ -156,3 +157,16 @@
   $ adb sync data
   $ adb shell /data/fuzz/arm64/ndk_sync_codec_fuzzer/ndk_sync_codec_fuzzer
 ```
+
+# <a name="NdkAsyncCodec"></a>Fuzzer for NdkAsyncCodec
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) ndk_async_codec_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/ndk_async_codec_fuzzer/ndk_sync_codec_fuzzer
+```
diff --git a/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp b/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp
new file mode 100644
index 0000000..28a38fe
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp
@@ -0,0 +1,441 @@
+/*
+ * 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>
+#include <media/NdkMediaFormatPriv.h>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+using namespace android;
+using namespace std;
+
+constexpr int32_t kMaxCryptoInfoAPIs = 3;
+constexpr int32_t kMaxNdkCodecAPIs = 5;
+
+template <typename T>
+class CallBackQueue {
+  public:
+    void push(T elem) {
+        bool needsNotify = false;
+        {
+            unique_lock<mutex> lock(mMutex);
+            needsNotify = mQueue.empty();
+            mQueue.push(std::move(elem));
+        }
+        if (needsNotify) {
+            mQueueNotEmptyCondition.notify_one();
+        }
+    }
+
+    T pop() {
+        unique_lock<mutex> lock(mMutex);
+        if (mQueue.empty()) {
+            mQueueNotEmptyCondition.wait(lock, [this]() { return !mQueue.empty(); });
+        }
+        auto result = mQueue.front();
+        mQueue.pop();
+        return result;
+    }
+
+  private:
+    mutex mMutex;
+    std::queue<T> mQueue;
+    std::condition_variable mQueueNotEmptyCondition;
+};
+
+class CallBackHandle {
+  public:
+    CallBackHandle() : mSawError(false), mIsDone(false) {}
+
+    virtual ~CallBackHandle() {}
+
+    void ioThread();
+
+    // Implementation in child class (Decoder/Encoder)
+    virtual void invokeInputBufferAPI(AMediaCodec* codec, int32_t index) {
+        (void)codec;
+        (void)index;
+    }
+    virtual void onFormatChanged(AMediaCodec* codec, AMediaFormat* format) {
+        (void)codec;
+        (void)format;
+    }
+    virtual void receiveError(void) {}
+    virtual void invokeOutputBufferAPI(AMediaCodec* codec, int32_t index,
+                                       AMediaCodecBufferInfo* bufferInfo) {
+        (void)codec;
+        (void)index;
+        (void)bufferInfo;
+    }
+
+    // Keep a queue of all function callbacks.
+    typedef function<void()> IOTask;
+    CallBackQueue<IOTask> mIOQueue;
+    bool mSawError;
+    bool mIsDone;
+};
+
+void CallBackHandle::ioThread() {
+    while (!mIsDone && !mSawError) {
+        auto task = mIOQueue.pop();
+        task();
+    }
+}
+
+static void onAsyncInputAvailable(AMediaCodec* codec, void* userdata, int32_t index) {
+    CallBackHandle* self = (CallBackHandle*)userdata;
+    self->mIOQueue.push([self, codec, index]() { self->invokeInputBufferAPI(codec, index); });
+}
+
+static void onAsyncOutputAvailable(AMediaCodec* codec, void* userdata, int32_t index,
+                                   AMediaCodecBufferInfo* bufferInfo) {
+    CallBackHandle* self = (CallBackHandle*)userdata;
+    AMediaCodecBufferInfo bufferInfoCopy = *bufferInfo;
+    self->mIOQueue.push([self, codec, index, bufferInfoCopy]() {
+        AMediaCodecBufferInfo bc = bufferInfoCopy;
+        self->invokeOutputBufferAPI(codec, index, &bc);
+    });
+}
+
+static void onAsyncFormatChanged(AMediaCodec* codec, void* userdata, AMediaFormat* format) {
+    (void)codec;
+    (void)userdata;
+    (void)format;
+};
+
+static void onAsyncError(AMediaCodec* codec, void* userdata, media_status_t err, int32_t actionCode,
+                         const char* detail) {
+    CallBackHandle* self = (CallBackHandle*)userdata;
+    self->mSawError = true;
+    self->receiveError();
+    (void)codec;
+    (void)err;
+    (void)actionCode;
+    (void)detail;
+};
+
+class NdkAsyncCodecFuzzer : public NdkMediaCodecFuzzerBase, public CallBackHandle {
+  public:
+    NdkAsyncCodecFuzzer(const uint8_t* data, size_t size)
+        : NdkMediaCodecFuzzerBase(), mFdp(data, size) {
+        setFdp(&mFdp);
+        mStopCodec = false;
+        mSawInputEOS = false;
+        mSignalledError = false;
+        mIsEncoder = false;
+        mNumOfFrames = 0;
+        mNumInputFrames = 0;
+    };
+    ~NdkAsyncCodecFuzzer() {
+        mIOThreadPool->stop();
+        delete (mIOThreadPool);
+    };
+
+    void process();
+
+    static void codecOnFrameRendered(AMediaCodec* codec, void* userdata, int64_t mediaTimeUs,
+                                     int64_t systemNano) {
+        (void)codec;
+        (void)userdata;
+        (void)mediaTimeUs;
+        (void)systemNano;
+    };
+    class ThreadPool {
+      public:
+        void start();
+        void queueJob(const std::function<void()>& job);
+        void stop();
+
+      private:
+        void ThreadLoop();
+        bool mShouldTerminate = false;
+        std::vector<std::thread> mThreads;
+        std::mutex mQueueMutex;
+        std::condition_variable mQueueMutexCondition;
+        std::queue<std::function<void()>> mJobs;
+    };
+
+  private:
+    FuzzedDataProvider mFdp;
+    AMediaCodec* mCodec = nullptr;
+    void invokeCodecCryptoInfoAPI();
+    void invokekAsyncCodecAPIs(bool isEncoder);
+    void invokeAsyncCodeConfigAPI();
+    void invokeInputBufferAPI(AMediaCodec* codec, int32_t bufferIndex);
+    void invokeOutputBufferAPI(AMediaCodec* codec, int32_t bufferIndex,
+                               AMediaCodecBufferInfo* bufferInfo);
+    void invokeFormatAPI(AMediaCodec* codec);
+    void receiveError();
+    bool mStopCodec;
+    bool mSawInputEOS;
+    bool mSignalledError;
+    int32_t mNumOfFrames;
+    int32_t mNumInputFrames;
+    mutable Mutex mMutex;
+    bool mIsEncoder;
+    ThreadPool* mIOThreadPool = new ThreadPool();
+};
+
+void NdkAsyncCodecFuzzer::ThreadPool::start() {
+    const uint32_t numThreads = std::thread::hardware_concurrency();
+    mThreads.resize(numThreads);
+    for (uint32_t i = 0; i < numThreads; ++i) {
+        mThreads.at(i) = std::thread(&ThreadPool::ThreadLoop, this);
+    }
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::ThreadLoop() {
+    while (true) {
+        std::function<void()> job;
+        {
+            std::unique_lock<std::mutex> lock(mQueueMutex);
+            mQueueMutexCondition.wait(lock, [this] { return !mJobs.empty() || mShouldTerminate; });
+            if (mShouldTerminate) {
+                return;
+            }
+            job = mJobs.front();
+            mJobs.pop();
+        }
+        job();
+    }
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::queueJob(const std::function<void()>& job) {
+    {
+        std::unique_lock<std::mutex> lock(mQueueMutex);
+        mJobs.push(job);
+    }
+    mQueueMutexCondition.notify_one();
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::stop() {
+    {
+        std::unique_lock<std::mutex> lock(mQueueMutex);
+        mShouldTerminate = true;
+    }
+    mQueueMutexCondition.notify_all();
+    for (std::thread& active_thread : mThreads) {
+        active_thread.join();
+    }
+    mThreads.clear();
+}
+
+void NdkAsyncCodecFuzzer::receiveError(void) {
+    mSignalledError = true;
+}
+
+void NdkAsyncCodecFuzzer::invokeInputBufferAPI(AMediaCodec* codec, int32_t bufferIndex) {
+    size_t bufferSize = 0;
+    Mutex::Autolock autoLock(mMutex);
+    if (mSignalledError) {
+        CallBackHandle::mSawError = true;
+        return;
+    }
+    if (mStopCodec || bufferIndex < 0 || mSawInputEOS) {
+        return;
+    }
+
+    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();
+    } else {
+        mSignalledError = true;
+        return;
+    }
+
+    uint32_t flag = 0;
+    if (!bufferSize || mNumInputFrames == mNumOfFrames) {
+        flag |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+        mSawInputEOS = true;
+    }
+    AMediaCodec_queueInputBuffer(codec, bufferIndex, 0 /* offset */, bufferSize, 0 /* time */,
+                                 flag);
+    mNumInputFrames++;
+}
+
+void NdkAsyncCodecFuzzer::invokeOutputBufferAPI(AMediaCodec* codec, int32_t bufferIndex,
+                                                AMediaCodecBufferInfo* bufferInfo) {
+    size_t bufferSize = 0;
+    Mutex::Autolock autoLock(mMutex);
+
+    if (mSignalledError) {
+        CallBackHandle::mSawError = true;
+        return;
+    }
+
+    if (mStopCodec || bufferIndex < 0 || mIsDone) {
+        return;
+    }
+
+    if (!mIsEncoder) {
+        (void)AMediaCodec_getOutputBuffer(codec, bufferIndex, &bufferSize);
+    }
+    AMediaCodec_releaseOutputBuffer(codec, bufferIndex, mFdp.ConsumeBool());
+    mIsDone = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
+}
+
+void NdkAsyncCodecFuzzer::invokeFormatAPI(AMediaCodec* codec) {
+    AMediaFormat* codecFormat = nullptr;
+    if (mFdp.ConsumeBool()) {
+        codecFormat = AMediaCodec_getInputFormat(codec);
+    } else {
+        codecFormat = AMediaCodec_getOutputFormat(codec);
+    }
+    if (codecFormat) {
+        AMediaFormat_delete(codecFormat);
+    }
+}
+
+void NdkAsyncCodecFuzzer::invokekAsyncCodecAPIs(bool isEncoder) {
+    ANativeWindow* nativeWindow = nullptr;
+
+    if (mFdp.ConsumeBool()) {
+        AMediaCodec_createInputSurface(mCodec, &nativeWindow);
+    }
+
+    if (AMEDIA_OK == AMediaCodec_configure(mCodec, getCodecFormat(), nativeWindow,
+                                           nullptr /* crypto */,
+                                           (isEncoder ? AMEDIACODEC_CONFIGURE_FLAG_ENCODE : 0))) {
+        mNumOfFrames = mFdp.ConsumeIntegralInRange<size_t>(kMinIterations, kMaxIterations);
+        // Configure codecs to run in async mode.
+        AMediaCodecOnAsyncNotifyCallback callBack = {onAsyncInputAvailable, onAsyncOutputAvailable,
+                                                     onAsyncFormatChanged, onAsyncError};
+        AMediaCodec_setAsyncNotifyCallback(mCodec, callBack, this);
+        mIOThreadPool->queueJob([this] { CallBackHandle::ioThread(); });
+
+        AMediaCodec_start(mCodec);
+        sleep(5);
+        int32_t count = 0;
+        while (++count <= mNumOfFrames) {
+            int32_t ndkcodecAPI =
+                    mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxNdkCodecAPIs);
+            switch (ndkcodecAPI) {
+                case 0: {  // get input and output Format
+                    invokeFormatAPI(mCodec);
+                    break;
+                }
+                case 1: {
+                    AMediaCodec_signalEndOfInputStream(mCodec);
+                    mSawInputEOS = true;
+                    break;
+                }
+                case 2: {  // 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 3: {  // flush codec
+                    AMediaCodec_flush(mCodec);
+                    if (mFdp.ConsumeBool()) {
+                        AMediaCodec_start(mCodec);
+                    }
+                    break;
+                }
+                case 4: {
+                    char* name = nullptr;
+                    AMediaCodec_getName(mCodec, &name);
+                    AMediaCodec_releaseName(mCodec, name);
+                    break;
+                }
+                case 5:
+                default: {
+                    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;
+                }
+            }
+        }
+        {
+            Mutex::Autolock autoLock(mMutex);
+            mStopCodec = 1;
+            AMediaCodec_stop(mCodec);
+        }
+    }
+
+    if (nativeWindow) {
+        ANativeWindow_release(nativeWindow);
+    }
+}
+
+void NdkAsyncCodecFuzzer::invokeAsyncCodeConfigAPI() {
+    mIOThreadPool->start();
+
+    while (mFdp.remaining_bytes() > 0) {
+        mIsEncoder = mFdp.ConsumeBool();
+        mCodec = createCodec(mIsEncoder, mFdp.ConsumeBool() /* isCodecForClient */);
+        if (mCodec) {
+            invokekAsyncCodecAPIs(mIsEncoder);
+            AMediaCodec_delete(mCodec);
+        }
+    }
+    mIOThreadPool->stop();
+}
+
+void NdkAsyncCodecFuzzer::invokeCodecCryptoInfoAPI() {
+    while (mFdp.remaining_bytes() > 0) {
+        AMediaCodecCryptoInfo* cryptoInfo = getAMediaCodecCryptoInfo();
+        int32_t ndkCryptoInfoAPI =
+                mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxCryptoInfoAPIs);
+        switch (ndkCryptoInfoAPI) {
+            case 0: {
+                size_t sizes[kMaxCryptoKey];
+                AMediaCodecCryptoInfo_getEncryptedBytes(cryptoInfo, sizes);
+                break;
+            }
+            case 1: {
+                size_t sizes[kMaxCryptoKey];
+                AMediaCodecCryptoInfo_getClearBytes(cryptoInfo, sizes);
+                break;
+            }
+            case 2: {
+                uint8_t bytes[kMaxCryptoKey];
+                AMediaCodecCryptoInfo_getIV(cryptoInfo, bytes);
+                break;
+            }
+            case 3:
+            default: {
+                uint8_t bytes[kMaxCryptoKey];
+                AMediaCodecCryptoInfo_getKey(cryptoInfo, bytes);
+                break;
+            }
+        }
+        AMediaCodecCryptoInfo_delete(cryptoInfo);
+    }
+}
+
+void NdkAsyncCodecFuzzer::process() {
+    if (mFdp.ConsumeBool()) {
+        invokeCodecCryptoInfoAPI();
+    } else {
+        invokeAsyncCodeConfigAPI();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    NdkAsyncCodecFuzzer ndkAsyncCodecFuzzer(data, size);
+    ndkAsyncCodecFuzzer.process();
+    return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
index c19ea13..23e2eaf 100644
--- a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
+++ b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
@@ -18,6 +18,7 @@
 #include <fcntl.h>
 #include <fuzzer/FuzzedDataProvider.h>
 #include <media/NdkMediaFormat.h>
+#include <media/stagefright/foundation/AMessage.h>
 #include <sys/mman.h>
 #include <unistd.h>
 #include <utils/Log.h>
@@ -176,11 +177,13 @@
 constexpr size_t kMaxBytes = 1000;
 constexpr size_t kMinChoice = 0;
 constexpr size_t kMaxChoice = 9;
+const size_t kMaxIteration = android::AMessage::maxAllowedEntries();
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
     FuzzedDataProvider fdp(data, size);
     AMediaFormat* mediaFormat = AMediaFormat_new();
-    while (fdp.remaining_bytes()) {
+    std::vector<std::string> nameCollection;
+    while (fdp.remaining_bytes() && nameCollection.size() < kMaxIteration) {
         const char* name = nullptr;
         std::string nameString;
         if (fdp.ConsumeBool()) {
@@ -190,6 +193,11 @@
                             : fdp.ConsumeRandomLengthString(
                                       fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
             name = nameString.c_str();
+            std::vector<std::string>::iterator it =
+                    find(nameCollection.begin(), nameCollection.end(), name);
+            if (it == nameCollection.end()) {
+                nameCollection.push_back(name);
+            }
         }
         switch (fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice)) {
             case 0: {
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index b6dcaae..48a0a82 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -540,9 +540,11 @@
  *
  * @return AMEDIA_OK if the method call succeeds.
  *         AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
- *         AMEDIA_ERROR_UNKNOWN if some other error is encountered.
+ *         AMEDIA_ERROR_UNKNOWN if some other error is encountered or
+ *         the device no longer has android.hidl.token service to
+ *         satisfy the request because it is deprecated.
  */
-media_status_t AImageReader_getWindowNativeHandle(
+[[deprecated]] media_status_t AImageReader_getWindowNativeHandle(
     AImageReader *reader, /* out */native_handle_t **handle);
 #endif
 
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 7abb0b6..07dac5e 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -179,3 +179,8 @@
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
 }
+
+cc_library_headers {
+    name: "mediautils_headers",
+    export_include_dirs: ["include", "."],
+}
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
index 0689083..3fdc6eb 100644
--- a/media/utils/tests/Android.bp
+++ b/media/utils/tests/Android.bp
@@ -200,7 +200,10 @@
     name: "timerthread_tests",
 
     defaults: ["libmediautils_tests_defaults"],
-
+    // TODO(b/270180838)
+    test_options: {
+        unit_test: false,
+    },
     srcs: [
         "TimerThread-test.cpp",
     ],
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 61df672..fec327f 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -138,10 +138,56 @@
     ],
 }
 
-cc_library_shared {
+cc_defaults {
+    name: "libaudioflinger_dependencies",
+
+    shared_libs: [
+        "audioflinger-aidl-cpp",
+        "audioclient-types-aidl-cpp",
+        "av-types-aidl-cpp",
+        "effect-aidl-cpp",
+        "libaudioclient_aidl_conversion",
+        "libactivitymanager_aidl",
+        "libaudioflinger_fastpath",
+        "libaudioflinger_timing",
+        "libaudioflinger_utils",
+        "libaudiofoundation",
+        "libaudiohal",
+        "libaudioprocessing",
+        "libaudioutils",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libbinder",
+        "libbinder_ndk",
+        "libaudioclient",
+        "libaudiomanager",
+        "libmediametrics",
+        "libmediautils",
+        "libnbaio",
+        "libnblog",
+        "libpermission",
+        "libpowermanager",
+        "libmemunreachable",
+        "libmedia_helper",
+        "libshmemcompat",
+        "libsounddose",
+        "libvibrator",
+        "packagemanager_aidl-cpp",
+    ],
+
+    static_libs: [
+        "libmedialogservice",
+        "libaudiospdif",
+    ],
+}
+
+
+cc_library {
     name: "libaudioflinger",
 
     defaults: [
+        "libaudioflinger_dependencies",
         "latest_android_media_audio_common_types_cpp_shared",
         "latest_android_hardware_audio_core_sounddose_ndk_shared",
         "audioflinger_flags_defaults",
@@ -167,43 +213,6 @@
         "frameworks/av/services/medialog",
     ],
 
-    shared_libs: [
-        "audioflinger-aidl-cpp",
-        "audioclient-types-aidl-cpp",
-        "av-types-aidl-cpp",
-        "effect-aidl-cpp",
-        "libaudioclient_aidl_conversion",
-        "libactivitymanager_aidl",
-        "libaudioflinger_fastpath",
-        "libaudioflinger_timing",
-        "libaudioflinger_utils",
-        "libaudiofoundation",
-        "libaudiohal",
-        "libaudioprocessing",
-        "libaudiospdif",
-        "libaudioutils",
-        "libcutils",
-        "libutils",
-        "liblog",
-        "libbinder",
-        "libbinder_ndk",
-        "libaudioclient",
-        "libaudiomanager",
-        "libmedialogservice",
-        "libmediametrics",
-        "libmediautils",
-        "libnbaio",
-        "libnblog",
-        "libpermission",
-        "libpowermanager",
-        "libmemunreachable",
-        "libmedia_helper",
-        "libshmemcompat",
-        "libsounddose",
-        "libvibrator",
-        "packagemanager_aidl-cpp",
-    ],
-
     static_libs: [
         "libcpustats",
         "libpermission",
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index f4fc8f1..3a530aa 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -7,26 +7,8 @@
     default_applicable_licenses: ["frameworks_av_license"],
 }
 
-cc_library_shared {
-    name: "libaudiopolicyservice",
-
-    defaults: [
-        "latest_android_media_audio_common_types_cpp_shared",
-    ],
-
-    srcs: [
-        "AudioPolicyClientImpl.cpp",
-        "AudioPolicyEffects.cpp",
-        "AudioPolicyInterfaceImpl.cpp",
-        "AudioPolicyService.cpp",
-        "CaptureStateNotifier.cpp",
-        "Spatializer.cpp",
-        "SpatializerPoseController.cpp",
-    ],
-
-    include_dirs: [
-        "frameworks/av/services/audioflinger"
-    ],
+cc_defaults {
+    name: "libaudiopolicyservice_dependencies",
 
     shared_libs: [
         "libactivitymanager_aidl",
@@ -41,7 +23,6 @@
         "libaudioutils",
         "libbinder",
         "libcutils",
-        "libeffectsconfig",
         "libhardware_legacy",
         "libheadtracking",
         "libheadtracking-binding",
@@ -67,6 +48,35 @@
     ],
 
     static_libs: [
+        "libeffectsconfig",
+        "libaudiopolicycomponents",
+    ]
+}
+
+cc_library {
+    name: "libaudiopolicyservice",
+
+    defaults: [
+        "libaudiopolicyservice_dependencies",
+        "latest_android_media_audio_common_types_cpp_shared",
+    ],
+
+    srcs: [
+        "AudioPolicyClientImpl.cpp",
+        "AudioPolicyEffects.cpp",
+        "AudioPolicyInterfaceImpl.cpp",
+        "AudioPolicyService.cpp",
+        "CaptureStateNotifier.cpp",
+        "Spatializer.cpp",
+        "SpatializerPoseController.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/audioflinger"
+    ],
+
+
+    static_libs: [
         "framework-permission-aidl-cpp",
     ],
 
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index a45365a..84dcf26 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -35,9 +35,91 @@
     ],
 }
 
-cc_library_shared {
+cc_defaults {
+    name: "libcameraservice_deps",
+
+    shared_libs: [
+        "libactivitymanager_aidl",
+        "libbase",
+        "libdl",
+        "libui",
+        "liblog",
+        "libutilscallstack",
+        "libutils",
+        "libbinder",
+        "libbinder_ndk",
+        "libactivitymanager_aidl",
+        "libpermission",
+        "libcutils",
+        "libexif",
+        "libmedia",
+        "libmediautils",
+        "libcamera_client",
+        "libcamera_metadata",
+        "libfmq",
+        "libgui",
+        "libhardware",
+        "libhidlbase",
+        "libimage_io",
+        "libjpeg",
+        "libultrahdr",
+        "libmedia_codeclist",
+        "libmedia_omx",
+        "libmemunreachable",
+        "libprocessgroup",
+        "libprocinfo",
+        "libsensorprivacy",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libxml2",
+        "libyuv",
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.device@3.6",
+        "android.hardware.camera.device@3.7",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.graphics.common-V4-ndk",
+        "media_permission-aidl-cpp",
+    ],
+
+    static_libs: [
+        "android.frameworks.cameraservice.common@2.0",
+        "android.frameworks.cameraservice.service@2.0",
+        "android.frameworks.cameraservice.service@2.1",
+        "android.frameworks.cameraservice.service@2.2",
+        "android.frameworks.cameraservice.device@2.0",
+        "android.frameworks.cameraservice.device@2.1",
+        "android.frameworks.cameraservice.common-V1-ndk",
+        "android.frameworks.cameraservice.service-V1-ndk",
+        "android.frameworks.cameraservice.device-V1-ndk",
+        "android.hardware.camera.common-V1-ndk",
+        "android.hardware.camera.device-V2-ndk",
+        "android.hardware.camera.metadata-V2-ndk",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.provider@2.6",
+        "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V2-ndk",
+        "libaidlcommonsupport",
+        "libdynamic_depth",
+        "libprocessinfoservice_aidl",
+        "libbinderthreadstateutils",
+        "media_permission-aidl-cpp",
+        "libcameraservice_device_independent",
+    ],
+}
+
+cc_library {
     name: "libcameraservice",
 
+    defaults: [
+        "libcameraservice_deps",
+    ],
     // Camera service source
 
     srcs: [
@@ -105,6 +187,7 @@
         "utils/CameraThreadState.cpp",
         "utils/CameraTraces.cpp",
         "utils/AutoConditionLock.cpp",
+        "utils/SchedulingPolicyUtils.cpp",
         "utils/SessionConfigurationUtils.cpp",
         "utils/SessionConfigurationUtilsHidl.cpp",
         "utils/SessionStatsBuilder.cpp",
@@ -119,73 +202,6 @@
         "libmediametrics_headers",
     ],
 
-    shared_libs: [
-        "libactivitymanager_aidl",
-        "libbase",
-        "libdl",
-        "libexif",
-        "libui",
-        "liblog",
-        "libutilscallstack",
-        "libutils",
-        "libbinder",
-        "libbinder_ndk",
-        "libactivitymanager_aidl",
-        "libpermission",
-        "libcutils",
-        "libmedia",
-        "libmediautils",
-        "libcamera_client",
-        "libcamera_metadata",
-        "libdynamic_depth",
-        "libfmq",
-        "libgui",
-        "libhardware",
-        "libhidlbase",
-        "libimage_io",
-        "libjpeg",
-        "libultrahdr",
-        "libmedia_codeclist",
-        "libmedia_omx",
-        "libmemunreachable",
-        "libsensorprivacy",
-        "libstagefright",
-        "libstagefright_foundation",
-        "libxml2",
-        "libyuv",
-        "android.frameworks.cameraservice.common@2.0",
-        "android.frameworks.cameraservice.service@2.0",
-        "android.frameworks.cameraservice.service@2.1",
-        "android.frameworks.cameraservice.service@2.2",
-        "android.frameworks.cameraservice.device@2.0",
-        "android.frameworks.cameraservice.device@2.1",
-        "android.frameworks.cameraservice.common-V1-ndk",
-        "android.frameworks.cameraservice.service-V1-ndk",
-        "android.frameworks.cameraservice.device-V1-ndk",
-        "android.hardware.camera.common@1.0",
-        "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.provider@2.5",
-        "android.hardware.camera.provider@2.6",
-        "android.hardware.camera.provider@2.7",
-        "android.hardware.camera.provider-V2-ndk",
-        "android.hardware.camera.device@3.2",
-        "android.hardware.camera.device@3.3",
-        "android.hardware.camera.device@3.4",
-        "android.hardware.camera.device@3.5",
-        "android.hardware.camera.device@3.6",
-        "android.hardware.camera.device@3.7",
-        "android.hardware.camera.device-V2-ndk",
-        "media_permission-aidl-cpp",
-    ],
-
-    static_libs: [
-        "libaidlcommonsupport",
-        "libprocessinfoservice_aidl",
-        "libbinderthreadstateutils",
-        "media_permission-aidl-cpp",
-        "libcameraservice_device_independent",
-    ],
-
     export_shared_lib_headers: [
         "libbinder",
         "libactivitymanager_aidl",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 668a51a..ca894fe 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -87,6 +87,7 @@
     const char* kActivityServiceName = "activity";
     const char* kSensorPrivacyServiceName = "sensor_privacy";
     const char* kAppopsServiceName = "appops";
+    const char* kProcessInfoServiceName = "processinfo";
 }; // namespace anonymous
 
 namespace android {
@@ -145,6 +146,7 @@
 static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
 static constexpr int32_t kSystemNativeClientState =
         ActivityManager::PROCESS_STATE_PERSISTENT_UI;
+static const String16 kServiceName("cameraserver");
 
 const String8 CameraService::kOfflineDevice("offline-");
 const String16 CameraService::kWatchAllClientsFlag("all");
@@ -701,17 +703,100 @@
     broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
 }
 
-static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
+static bool isAutomotiveDevice() {
+    // Checks the property ro.hardware.type and returns true if it is
+    // automotive.
+    char value[PROPERTY_VALUE_MAX] = {0};
+    property_get("ro.hardware.type", value, "");
+    return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
+static bool isAutomotivePrivilegedClient(int32_t uid) {
+    // Returns false if this is not an automotive device type.
+    if (!isAutomotiveDevice())
+        return false;
+
+    // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
+    // privileged client uid used for safety critical use cases such as
+    // rear view and surround view.
+    return uid == AID_AUTOMOTIVE_EVS;
+}
+
+bool CameraService::isAutomotiveExteriorSystemCamera(const String8& cam_id) const{
+    // Returns false if this is not an automotive device type.
+    if (!isAutomotiveDevice())
+        return false;
+
+    // Returns false if no camera id is provided.
+    if (cam_id.isEmpty())
+        return false;
+
+    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+    if (getSystemCameraKind(cam_id, &systemCameraKind) != OK) {
+        // This isn't a known camera ID, so it's not a system camera.
+        ALOGE("%s: Unknown camera id %s, ", __FUNCTION__, cam_id.c_str());
+        return false;
+    }
+
+    if (systemCameraKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) {
+        ALOGE("%s: camera id %s is not a system camera", __FUNCTION__, cam_id.c_str());
+        return false;
+    }
+
+    CameraMetadata cameraInfo;
+    status_t res = mCameraProviderManager->getCameraCharacteristics(
+            cam_id.string(), false, &cameraInfo, false);
+    if (res != OK){
+        ALOGE("%s: Not able to get camera characteristics for camera id %s",__FUNCTION__,
+                cam_id.c_str());
+        return false;
+    }
+
+    camera_metadata_entry auto_location  = cameraInfo.find(ANDROID_AUTOMOTIVE_LOCATION);
+    if (auto_location.count != 1)
+        return false;
+
+    uint8_t location = auto_location.data.u8[0];
+    if ((location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT) &&
+            (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR) &&
+            (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT) &&
+            (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT)) {
+        return false;
+    }
+
+    return true;
+}
+
+bool CameraService::checkPermission(const String8& cam_id, const String16& permission,
+        const AttributionSourceState& attributionSource,const String16& message,
+        int32_t attributedOpCode) const{
+    if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+        // If cam_id is empty, then it means that this check is not used for the
+        // purpose of accessing a specific camera, hence grant permission just
+        // based on uid to the automotive privileged client.
+        if (cam_id.isEmpty())
+            return true;
+        // If this call is used for accessing a specific camera then cam_id must be provided.
+        // In that case, only pre-grants the permission for accessing the exterior system only
+        // camera.
+        return isAutomotiveExteriorSystemCamera(cam_id);
+
+    }
+
     permission::PermissionChecker permissionChecker;
+    return permissionChecker.checkPermissionForPreflight(permission, attributionSource,
+            message, attributedOpCode) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+bool CameraService::hasPermissionsForSystemCamera(const String8& cam_id, int callingPid,
+        int callingUid) const{
     AttributionSourceState attributionSource{};
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
-    bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
-            sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
-    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+    bool checkPermissionForSystemCamera = checkPermission(cam_id,
+            sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE);
+    bool checkPermissionForCamera = checkPermission(cam_id,
+            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE);
     return checkPermissionForSystemCamera && checkPermissionForCamera;
 }
 
@@ -719,7 +804,7 @@
     ATRACE_CALL();
     Mutex::Autolock l(mServiceLock);
     bool hasSystemCameraPermissions =
-            hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
+            hasPermissionsForSystemCamera(String8(), CameraThreadState::getCallingPid(),
                     CameraThreadState::getCallingUid());
     switch (type) {
         case CAMERA_TYPE_BACKWARD_COMPATIBLE:
@@ -760,9 +845,8 @@
         return STATUS_ERROR(ERROR_DISCONNECTED,
                 "Camera subsystem is not available");
     }
-    bool hasSystemCameraPermissions =
-            hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
-                    CameraThreadState::getCallingUid());
+    bool hasSystemCameraPermissions = hasPermissionsForSystemCamera(String8::format("%d", cameraId),
+            CameraThreadState::getCallingPid(), CameraThreadState::getCallingUid());
     int cameraIdBound = mNumberOfCamerasWithoutSystemCamera;
     if (hasSystemCameraPermissions) {
         cameraIdBound = mNumberOfCameras;
@@ -791,13 +875,11 @@
     const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
     auto callingPid = CameraThreadState::getCallingPid();
     auto callingUid = CameraThreadState::getCallingUid();
-    permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
-    bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
-                sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+    bool checkPermissionForSystemCamera = checkPermission(String8::format("%d", cameraIdInt),
+                sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE);
     if (checkPermissionForSystemCamera || getpid() == callingPid) {
         deviceIds = &mNormalDeviceIds;
     }
@@ -869,13 +951,11 @@
     // If it's not calling from cameraserver, check the permission only if
     // android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
     // it would've already been checked in shouldRejectSystemCameraConnection.
-    permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
-    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+    bool checkPermissionForCamera = checkPermission(String8(cameraId), sCameraPermission,
+            attributionSource, String16(), AppOpsManager::OP_NONE);
     if ((callingPid != getpid()) &&
             (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
             !checkPermissionForCamera) {
@@ -1154,13 +1234,12 @@
 Status CameraService::initializeShimMetadata(int cameraId) {
     int uid = CameraThreadState::getCallingUid();
 
-    String16 internalPackageName("cameraserver");
     String8 id = String8::format("%d", cameraId);
     Status ret = Status::ok();
     sp<Client> tmp = nullptr;
     if (!(ret = connectHelper<ICameraClient,Client>(
             sp<ICameraClient>{nullptr}, id, cameraId,
-            internalPackageName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
+            kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
             API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
             /*targetSdkVersion*/ __ANDROID_API_FUTURE__, /*overrideToPortrait*/ true,
             /*forceSlowJpegMode*/false, /*out*/ tmp)
@@ -1314,7 +1393,6 @@
 Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
         const String8& clientName8, int& clientUid, int& clientPid,
         /*out*/int& originalClientPid) const {
-    permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
 
     int callingPid = CameraThreadState::getCallingPid();
@@ -1366,9 +1444,8 @@
     attributionSource.pid = clientPid;
     attributionSource.uid = clientUid;
     attributionSource.packageName = clientName8;
-    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+    bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission, attributionSource,
+            String16(), AppOpsManager::OP_NONE);
     if (callingPid != getpid() &&
                 (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
         ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
@@ -1389,8 +1466,13 @@
                 callingUid, procState);
     }
 
-    // If sensor privacy is enabled then prevent access to the camera
-    if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+
+    // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
+    // such as rear view and surround view cannot be disabled and are exempt from sensor privacy
+    // policy. In all other cases,if sensor privacy is enabled then prevent access to the camera.
+    if ((!isAutomotivePrivilegedClient(callingUid) ||
+            !isAutomotiveExteriorSystemCamera(cameraId)) &&
+            mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
         ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled");
         return STATUS_ERROR_FMT(ERROR_DISABLED,
                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy "
@@ -1508,33 +1590,6 @@
             }
         }
 
-        // Get current active client PIDs
-        std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
-        ownerPids.push_back(clientPid);
-
-        std::vector<int> priorityScores(ownerPids.size());
-        std::vector<int> states(ownerPids.size());
-
-        // Get priority scores of all active PIDs
-        status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
-                ownerPids.size(), &ownerPids[0], /*out*/&states[0],
-                /*out*/&priorityScores[0]);
-        if (err != OK) {
-            ALOGE("%s: Priority score query failed: %d",
-                  __FUNCTION__, err);
-            return err;
-        }
-
-        // Update all active clients' priorities
-        std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
-        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
-            pidToPriorityMap.emplace(ownerPids[i],
-                    resource_policy::ClientPriority(priorityScores[i], states[i],
-                            /* isVendorClient won't get copied over*/ false,
-                            /* oomScoreOffset won't get copied over*/ 0));
-        }
-        mActiveClientManager.updatePriorities(pidToPriorityMap);
-
         // Get state for the given cameraId
         auto state = getCameraState(cameraId);
         if (state == nullptr) {
@@ -1544,16 +1599,57 @@
             return BAD_VALUE;
         }
 
-        int32_t actualScore = priorityScores[priorityScores.size() - 1];
-        int32_t actualState = states[states.size() - 1];
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder = sm->checkService(String16(kProcessInfoServiceName));
+        if (!binder && isAutomotivePrivilegedClient(CameraThreadState::getCallingUid())) {
+            // If processinfo service is not available and the client is automotive privileged
+            // client used for safety critical uses cases such as rear-view and surround-view which
+            // needs to be available before android boot completes, then use the hardcoded values
+            // for the process state and priority score. As this scenario is before android system
+            // services are up and client is native client, hence using NATIVE_ADJ as the priority
+            // score and state as PROCESS_STATE_BOUND_TOP as such automotive apps need to be
+            // visible on the top.
+            clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
+                    sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
+                    state->getConflicting(), resource_policy::NATIVE_ADJ, clientPid,
+                    ActivityManager::PROCESS_STATE_BOUND_TOP, oomScoreOffset, systemNativeClient);
+        } else {
+            // Get current active client PIDs
+            std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
+            ownerPids.push_back(clientPid);
 
-        // Make descriptor for incoming client. We store the oomScoreOffset
-        // since we might need it later on new handleEvictionsLocked and
-        // ProcessInfoService would not take that into account.
-        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
-                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
-                state->getConflicting(), actualScore, clientPid, actualState,
-                oomScoreOffset, systemNativeClient);
+            std::vector<int> priorityScores(ownerPids.size());
+            std::vector<int> states(ownerPids.size());
+
+            // Get priority scores of all active PIDs
+            status_t err = ProcessInfoService::getProcessStatesScoresFromPids(ownerPids.size(),
+                    &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]);
+            if (err != OK) {
+                ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err);
+                return err;
+            }
+
+            // Update all active clients' priorities
+            std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
+            for (size_t i = 0; i < ownerPids.size() - 1; i++) {
+                pidToPriorityMap.emplace(ownerPids[i],
+                        resource_policy::ClientPriority(priorityScores[i], states[i],
+                        /* isVendorClient won't get copied over*/ false,
+                        /* oomScoreOffset won't get copied over*/ 0));
+            }
+            mActiveClientManager.updatePriorities(pidToPriorityMap);
+
+            int32_t actualScore = priorityScores[priorityScores.size() - 1];
+            int32_t actualState = states[states.size() - 1];
+
+            // Make descriptor for incoming client. We store the oomScoreOffset
+            // since we might need it later on new handleEvictionsLocked and
+            // ProcessInfoService would not take that into account.
+            clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
+                    sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
+                    state->getConflicting(), actualScore, clientPid, actualState,
+                    oomScoreOffset, systemNativeClient);
+        }
 
         resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
 
@@ -1729,7 +1825,7 @@
     //      have android.permission.SYSTEM_CAMERA permissions.
     if (!isVendorListener && (systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA ||
             (systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
-            !hasPermissionsForSystemCamera(clientPid, clientUid)))) {
+            !hasPermissionsForSystemCamera(String8(), clientPid, clientUid)))) {
         return true;
     }
     return false;
@@ -1769,7 +1865,7 @@
     //     characteristics) even if clients don't have android.permission.CAMERA. We do not want the
     //     same behavior for system camera devices.
     if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
-            !hasPermissionsForSystemCamera(cPid, cUid)) {
+            !hasPermissionsForSystemCamera(cameraId, cPid, cUid)) {
         ALOGW("Rejecting access to system only camera %s, inadequete permissions",
                 cameraId.c_str());
         return true;
@@ -1817,7 +1913,10 @@
         clientUserId = multiuser_get_user_id(callingUid);
     }
 
-    if (mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
+    // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
+    // such as rear view and surround view cannot be disabled.
+    if ((!isAutomotivePrivilegedClient(callingUid) || !isAutomotiveExteriorSystemCamera(id)) &&
+            mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
         String8 msg =
                 String8::format("Camera disabled by device policy");
         ALOGE("%s: %s", __FUNCTION__, msg.string());
@@ -1826,7 +1925,7 @@
 
     // enforce system camera permissions
     if (oomScoreOffset > 0 &&
-            !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid()) &&
+            !hasPermissionsForSystemCamera(id, callingPid, CameraThreadState::getCallingUid()) &&
             !isTrustedCallingUid(CameraThreadState::getCallingUid())) {
         String8 msg =
                 String8::format("Cannot change the priority of a client %s pid %d for "
@@ -1915,6 +2014,8 @@
 
     bool isNonSystemNdk = false;
     String16 clientPackageName;
+    int packageUid = (clientUid == USE_CALLING_UID) ?
+            CameraThreadState::getCallingUid() : clientUid;
     if (clientPackageNameMaybe.size() <= 0) {
         // NDK calls don't come with package names, but we need one for various cases.
         // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
@@ -1922,8 +2023,6 @@
         // same permissions, so picking any associated package name is sufficient. For some
         // other cases, this may give inaccurate names for clients in logs.
         isNonSystemNdk = true;
-        int packageUid = (clientUid == USE_CALLING_UID) ?
-            CameraThreadState::getCallingUid() : clientUid;
         clientPackageName = getPackageNameFromUid(packageUid);
     } else {
         clientPackageName = clientPackageNameMaybe;
@@ -2119,32 +2218,38 @@
                     clientPackageName));
         }
 
-        // Set camera muting behavior
-        bool isCameraPrivacyEnabled =
-                mSensorPrivacyPolicy->isCameraPrivacyEnabled();
-        if (client->supportsCameraMute()) {
-            client->setCameraMute(
-                    mOverrideCameraMuteMode || isCameraPrivacyEnabled);
-        } else if (isCameraPrivacyEnabled) {
-            // no camera mute supported, but privacy is on! => disconnect
-            ALOGI("Camera mute not supported for package: %s, camera id: %s",
-                    String8(client->getPackageName()).string(), cameraId.string());
-            // Do not hold mServiceLock while disconnecting clients, but
-            // retain the condition blocking other clients from connecting
-            // in mServiceLockWrapper if held.
-            mServiceLock.unlock();
-            // Clear caller identity temporarily so client disconnect PID
-            // checks work correctly
-            int64_t token = CameraThreadState::clearCallingIdentity();
-            // Note AppOp to trigger the "Unblock" dialog
-            client->noteAppOp();
-            client->disconnect();
-            CameraThreadState::restoreCallingIdentity(token);
-            // Reacquire mServiceLock
-            mServiceLock.lock();
+        // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use
+        // cases such as rear view and surround view cannot be disabled and are exempt from camera
+        // privacy policy.
+        if ((!isAutomotivePrivilegedClient(packageUid) ||
+                !isAutomotiveExteriorSystemCamera(cameraId))) {
+            // Set camera muting behavior.
+            bool isCameraPrivacyEnabled =
+                    mSensorPrivacyPolicy->isCameraPrivacyEnabled();
+            if (client->supportsCameraMute()) {
+                client->setCameraMute(
+                        mOverrideCameraMuteMode || isCameraPrivacyEnabled);
+            } else if (isCameraPrivacyEnabled) {
+                // no camera mute supported, but privacy is on! => disconnect
+                ALOGI("Camera mute not supported for package: %s, camera id: %s",
+                        String8(client->getPackageName()).string(), cameraId.string());
+                // Do not hold mServiceLock while disconnecting clients, but
+                // retain the condition blocking other clients from connecting
+                // in mServiceLockWrapper if held.
+                mServiceLock.unlock();
+                // Clear caller identity temporarily so client disconnect PID
+                // checks work correctly
+                int64_t token = CameraThreadState::clearCallingIdentity();
+                // Note AppOp to trigger the "Unblock" dialog
+                client->noteAppOp();
+                client->disconnect();
+                CameraThreadState::restoreCallingIdentity(token);
+                // Reacquire mServiceLock
+                mServiceLock.lock();
 
-            return STATUS_ERROR_FMT(ERROR_DISABLED,
-                    "Camera \"%s\" disabled due to camera mute", cameraId.string());
+                return STATUS_ERROR_FMT(ERROR_DISABLED,
+                        "Camera \"%s\" disabled due to camera mute", cameraId.string());
+            }
         }
 
         if (shimUpdateOnly) {
@@ -2747,13 +2852,11 @@
     // Check for camera permissions
     int callingPid = CameraThreadState::getCallingPid();
     int callingUid = CameraThreadState::getCallingUid();
-    permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
-    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+    bool checkPermissionForCamera = checkPermission(String8(),
+                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE);
     if ((callingPid != getpid()) && !checkPermissionForCamera) {
         ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
         return STATUS_ERROR(ERROR_PERMISSION_DENIED,
@@ -2801,13 +2904,13 @@
 
     auto clientUid = CameraThreadState::getCallingUid();
     auto clientPid = CameraThreadState::getCallingPid();
-    permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
     attributionSource.uid = clientUid;
     attributionSource.pid = clientPid;
-    bool openCloseCallbackAllowed = permissionChecker.checkPermissionForPreflight(
+
+   bool openCloseCallbackAllowed = checkPermission(String8(),
             sCameraOpenCloseListenerPermission, attributionSource, String16(),
-            AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+            AppOpsManager::OP_NONE);
 
     Mutex::Autolock lock(mServiceLock);
 
@@ -3926,7 +4029,7 @@
             | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE
             | ActivityManager::UID_OBSERVER_PROC_OOM_ADJ,
             ActivityManager::PROCESS_STATE_UNKNOWN,
-            String16("cameraserver"), emptyUidArray, 0, mObserverToken);
+            kServiceName, emptyUidArray, 0, mObserverToken);
     if (res == OK) {
         mRegistered = true;
         ALOGV("UidPolicy: Registered with ActivityManager");
@@ -4069,7 +4172,7 @@
         monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ;
         monitoredUid.refCount = 1;
         it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first;
-        status_t res = mAm.addUidToObserver(mObserverToken, String16("cameraserver"), uid);
+        status_t res = mAm.addUidToObserver(mObserverToken, kServiceName, uid);
         if (res != OK) {
             ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res);
         }
@@ -4090,7 +4193,7 @@
         it->second.refCount--;
         if (it->second.refCount == 0) {
             mMonitoredUids.erase(it);
-            status_t res = mAm.removeUidFromObserver(mObserverToken, String16("cameraserver"), uid);
+            status_t res = mAm.removeUidFromObserver(mObserverToken, kServiceName, uid);
             if (res != OK) {
                 ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res);
             }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3214d4c..38336ee 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
+#include <android/content/AttributionSourceState.h>
 #include <android/hardware/BnCameraService.h>
 #include <android/hardware/BnSensorPrivacyListener.h>
 #include <android/hardware/ICameraServiceListener.h>
@@ -607,6 +608,13 @@
     int32_t updateAudioRestrictionLocked();
 
 private:
+    /**
+     * Returns true if the device is an automotive device and cameraId is system
+     * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
+     * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+     * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
+     */
+    bool isAutomotiveExteriorSystemCamera(const String8& cameraId) const;
 
     // TODO: b/263304156 update this to make use of a death callback for more
     // robust/fault tolerant logging
@@ -623,6 +631,22 @@
     }
 
     /**
+     * Pre-grants the permission if the attribution source uid is for an automotive
+     * privileged client. Otherwise uses system service permission checker to check
+     * for the appropriate permission. If this function is called for accessing a specific
+     * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
+     * privileged client so that permission is pre-granted only to access system camera device
+     * which is located outside of the vehicle body frame because camera located inside the vehicle
+     * cabin would need user permission.
+     */
+    bool checkPermission(const String8& cameraId, const String16& permission,
+            const content::AttributionSourceState& attributionSource,const String16& message,
+            int32_t attributedOpCode) const;
+
+    bool hasPermissionsForSystemCamera(const String8& cameraId, int callingPid, int callingUid)
+            const;
+
+   /**
      * Typesafe version of device status, containing both the HAL-layer and the service interface-
      * layer values.
      */
@@ -885,7 +909,7 @@
     // Should a device status update be skipped for a particular camera device ? (this can happen
     // under various conditions. For example if a camera device is advertised as
     // system only or hidden secure camera, amongst possible others.
-    static bool shouldSkipStatusUpdates(SystemCameraKind systemCameraKind, bool isVendorListener,
+    bool shouldSkipStatusUpdates(SystemCameraKind systemCameraKind, bool isVendorListener,
             int clientPid, int clientUid);
 
     // Gets the kind of camera device (i.e public, hidden secure or system only)
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 61c3298..4487970 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -60,9 +60,9 @@
 #include "device3/Camera3InputStream.h"
 #include "device3/Camera3OutputStream.h"
 #include "device3/Camera3SharedOutputStream.h"
-#include "mediautils/SchedulingPolicyService.h"
 #include "utils/CameraThreadState.h"
 #include "utils/CameraTraces.h"
+#include "utils/SchedulingPolicyUtils.h"
 #include "utils/SessionConfigurationUtils.h"
 #include "utils/TraceHFR.h"
 
@@ -2625,8 +2625,8 @@
     if (disableFifo != 1) {
         // Boost priority of request thread to SCHED_FIFO.
         pid_t requestThreadTid = mRequestThread->getTid();
-        res = requestPriority(getpid(), requestThreadTid,
-                kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
+        res = SchedulingPolicyUtils::requestPriorityDirect(getpid(), requestThreadTid,
+                kRequestThreadPriority);
         if (res != OK) {
             ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
                     strerror(-res), res);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f742a6d..a2a9d04 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -260,7 +260,7 @@
 
     auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
     if (mapper != states.rotateAndCropMappers.end()) {
-        const auto& remappedKeys = iter->second.getRemappedKeys();
+        const auto& remappedKeys = mapper->second.getRemappedKeys();
         keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
     }
 
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 5e2a3fb..b035edd 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -31,11 +31,14 @@
         "libmedia_headers",
     ],
 
+    defaults: [
+        "libcameraservice_deps",
+    ],
+
     shared_libs: [
         "libbase",
         "libbinder",
         "libcutils",
-        "libcameraservice",
         "libhidlbase",
         "liblog",
         "libcamera_client",
@@ -45,11 +48,6 @@
         "libjpeg",
         "libexif",
         "android.hardware.camera.common@1.0",
-        "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.provider@2.5",
-        "android.hardware.camera.provider@2.6",
-        "android.hardware.camera.provider@2.7",
-        "android.hardware.camera.provider-V2-ndk",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
@@ -58,6 +56,12 @@
     ],
 
     static_libs: [
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.provider@2.6",
+        "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V2-ndk",
+        "libcameraservice",
         "libgmock",
     ],
 
diff --git a/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp
new file mode 100644
index 0000000..92a1030
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SchedulingPolicyUtils.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+
+#include "CameraThreadState.h"
+#include <private/android_filesystem_config.h>
+#include <processgroup/processgroup.h>
+#include <processgroup/sched_policy.h>
+#include <procinfo/process.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace camera3 {
+namespace SchedulingPolicyUtils {
+
+int requestPriorityDirect(int pid, int tid, int prio) {
+    android::procinfo::ProcessInfo processInfo;
+    static const int kMinPrio = 1;
+    static const int kMaxPrio = 3;
+
+    if (!android::procinfo::GetProcessInfo(tid, &processInfo)) {
+       ALOGE("%s: Error getting process info", __FUNCTION__);
+       return -EPERM;
+    }
+
+    if (prio < kMinPrio || prio > kMaxPrio || processInfo.pid != pid) {
+        ALOGE("%s: Invalid parameter prio=%d pid=%d procinfo.pid=%d", __FUNCTION__, prio, pid,
+                processInfo.pid);
+        return -EPERM;
+    }
+
+    // Set the thread group as audio system thread group in consistent with the
+    // implementation in SchedulingPolicyService.java when isApp is false in
+    // requestPriority method.
+    if (!SetTaskProfiles(tid, {get_sched_policy_profile_name(SP_AUDIO_SYS)},
+            /*use_fd_cache*/ true)) {
+        ALOGE("%s:Error in  SetTaskProfiles", __FUNCTION__);
+        return -EPERM;
+    }
+
+    struct sched_param param;
+    param.sched_priority = prio;
+    return sched_setscheduler(tid, SCHED_FIFO | SCHED_RESET_ON_FORK, &param);
+}
+
+} // namespace SchedulingPolicyUtils
+} // namespace camera3
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h
new file mode 100644
index 0000000..f71fddf
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVICE_CAMERA_SCHEDULING_POLICY_UTILS_H
+#define ANDROID_SERVICE_CAMERA_SCHEDULING_POLICY_UTILS_H
+
+namespace android {
+namespace camera3 {
+namespace SchedulingPolicyUtils {
+
+/**
+ * Request elevated priority for thread tid, whose thread group leader must be pid.
+ * Instead of using scheduling policy service, this method uses direct system calls.
+ * The priority parameter is currently restricted from 1 to 3 matching
+ * scheduling policy service implementation.
+ */
+int requestPriorityDirect(int pid, int tid, int prio);
+
+} // SchedulingPolicyUtils
+} // camera3
+} // android
+
+#endif
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 53cc431..23b23cc 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -133,7 +133,7 @@
 }
 
 static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
-        MediaResourceParcel resource) {
+        const MediaResourceParcel& resource) {
     if (type != resource.type) {
       return false;
     }
diff --git a/services/mediaresourcemanager/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index d98974f..f38a085 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -27,21 +27,18 @@
     default_applicable_licenses: ["frameworks_av_license"],
 }
 
-cc_fuzz {
-    name: "mediaresourcemanager_fuzzer",
-    srcs: [
-        "mediaresourcemanager_fuzzer.cpp",
+cc_defaults {
+    name: "mediaresourcemanager_fuzzer_defaults",
+    defaults: [
+        "service_fuzzer_defaults",
     ],
     static_libs: [
         "liblog",
         "libresourcemanagerservice",
     ],
     shared_libs: [
-        "libbinder",
-        "libbinder_ndk",
         "libmedia",
         "libmediautils",
-        "libutils",
         "libstats_media_metrics",
         "libstatspull",
         "libstatssocket",
@@ -54,3 +51,39 @@
         componentid: 155276,
     },
 }
+
+cc_fuzz {
+    name: "mediaresourcemanager_fuzzer",
+    defaults: [
+        "mediaresourcemanager_fuzzer_defaults",
+    ],
+    srcs: [
+        "mediaresourcemanager_fuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "resourcemanager_service_fuzzer",
+    defaults: [
+        "mediaresourcemanager_fuzzer_defaults",
+    ],
+    srcs: [
+        "resourcemanager_service_fuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "resourceobserver_service_fuzzer",
+    defaults: [
+        "mediaresourcemanager_fuzzer_defaults",
+    ],
+    static_libs: [
+        "resourceobserver_aidl_interface-V1-ndk",
+    ],
+    srcs: [
+        "resourceobserver_service_fuzzer.cpp",
+    ],
+    fuzz_config: {
+        triage_assignee: "waghpawan@google.com",
+    },
+}
diff --git a/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
new file mode 100644
index 0000000..ca10d20
--- /dev/null
+++ b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "ResourceManagerService.h"
+
+using android::fuzzService;
+using android::ResourceManagerService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+   auto service = SharedRefBase::make<ResourceManagerService>();
+   fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+   return 0;
+}
diff --git a/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp
new file mode 100644
index 0000000..e69368d
--- /dev/null
+++ b/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "ResourceObserverService.h"
+
+using android::fuzzService;
+using android::ResourceObserverService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+   auto service = SharedRefBase::make<ResourceObserverService>();
+   fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+   return 0;
+}
diff --git a/services/oboeservice/AAudioThread.cpp b/services/oboeservice/AAudioThread.cpp
index 549fa59..502d773 100644
--- a/services/oboeservice/AAudioThread.cpp
+++ b/services/oboeservice/AAudioThread.cpp
@@ -75,7 +75,9 @@
 
 aaudio_result_t AAudioThread::stop() {
     if (!mHasThread) {
-        ALOGE("stop() but no thread running");
+        // There can be cases that the thread is just created but not started.
+        // Logging as warning to attract attention but not too serious.
+        ALOGW("stop() but no thread running");
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index c5080a4..3521979 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -78,12 +78,38 @@
 
 ]
 
+cc_defaults {
+    name: "libaaudioservice_dependencies",
 
-cc_library {
+    shared_libs: [
+        "libaaudio_internal",
+        "libaudioclient",
+        "libaudioutils",
+        "libmedia_helper",
+        "libmediametrics",
+        "libmediautils",
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "aaudio-aidl-cpp",
+        "framework-permission-aidl-cpp",
+        "libaudioclient_aidl_conversion",
+        "packagemanager_aidl-cpp",
+    ],
+
+    static_libs: [
+        "libaudioflinger",
+    ]
+}
+
+cc_library_static {
 
     name: "libaaudioservice",
 
     defaults: [
+        "libaaudioservice_dependencies",
         "latest_android_media_audio_common_types_cpp_shared",
     ],
 
@@ -116,25 +142,6 @@
         "-Werror",
     ],
 
-    shared_libs: [
-        "libaaudio_internal",
-        "libaudioclient",
-        "libaudioflinger",
-        "libaudioutils",
-        "libmedia_helper",
-        "libmediametrics",
-        "libmediautils",
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "aaudio-aidl-cpp",
-        "framework-permission-aidl-cpp",
-        "libaudioclient_aidl_conversion",
-        "packagemanager_aidl-cpp",
-    ],
-
     export_shared_lib_headers: [
         "libaaudio_internal",
         "framework-permission-aidl-cpp",
diff --git a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
index f047065..f5c2e6c 100644
--- a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
+++ b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
@@ -403,13 +403,6 @@
 
     request.getConfiguration().setBufferCapacity(fdp.ConsumeIntegral<int32_t>());
 
-    request.getConfiguration().setHardwareSampleRate(fdp.ConsumeIntegral<int32_t>());
-    request.getConfiguration().setHardwareSamplesPerFrame(fdp.ConsumeIntegral<int32_t>());
-    request.getConfiguration().setHardwareFormat((audio_format_t)(
-        fdp.ConsumeBool()
-            ? fdp.ConsumeIntegral<int32_t>()
-            : kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
-
     auto streamHandleInfo = mClient->openStream(request, configurationOutput);
     if (streamHandleInfo.getHandle() < 0) {
         // invalid request, stream not opened.