Merge Android U (ab/10368041)

Bug: 291102124
Merged-In: Ied8e295ae059db07463ba06d3e6d747659b2757f
Change-Id: Ib79234b765308e957b682871b2178b66769f5660
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 2244682..35b8e21 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -19,7 +19,6 @@
 #define LOG_TAG "Camera"
 #include <utils/Log.h>
 #include <utils/threads.h>
-#include <utils/String16.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/IMemory.h>
@@ -70,7 +69,7 @@
     // deadlock if we call any method of ICamera here.
 }
 
-sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
+sp<Camera> Camera::connect(int cameraId, const std::string& clientPackageName,
         int clientUid, int clientPid, int targetSdkVersion, bool overrideToPortrait,
         bool forceSlowJpegMode)
 {
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 9ae4607..1af899d 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -31,6 +31,7 @@
 
 #include <camera/CameraBase.h>
 #include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
 
 // needed to instantiate
 #include <camera/Camera.h>
@@ -58,7 +59,7 @@
 }
 
 status_t CameraStatus::writeToParcel(android::Parcel* parcel) const {
-    auto res = parcel->writeString16(String16(cameraId));
+    auto res = parcel->writeString16(toString16(cameraId));
     if (res != OK) return res;
 
     res = parcel->writeInt32(status);
@@ -66,12 +67,12 @@
 
     std::vector<String16> unavailablePhysicalIds16;
     for (auto& id8 : unavailablePhysicalIds) {
-        unavailablePhysicalIds16.push_back(String16(id8));
+        unavailablePhysicalIds16.push_back(toString16(id8));
     }
     res = parcel->writeString16Vector(unavailablePhysicalIds16);
     if (res != OK) return res;
 
-    res = parcel->writeString16(String16(clientPackage));
+    res = parcel->writeString16(toString16(clientPackage));
     return res;
 }
 
@@ -79,7 +80,7 @@
     String16 tempCameraId;
     auto res = parcel->readString16(&tempCameraId);
     if (res != OK) return res;
-    cameraId = String8(tempCameraId);
+    cameraId = toString8(tempCameraId);
 
     res = parcel->readInt32(&status);
     if (res != OK) return res;
@@ -88,13 +89,13 @@
     res = parcel->readString16Vector(&unavailablePhysicalIds16);
     if (res != OK) return res;
     for (auto& id16 : unavailablePhysicalIds16) {
-        unavailablePhysicalIds.push_back(String8(id16));
+        unavailablePhysicalIds.push_back(toStdString(id16));
     }
 
     String16 tempClientPackage;
     res = parcel->readString16(&tempClientPackage);
     if (res != OK) return res;
-    clientPackage = String8(tempClientPackage);
+    clientPackage = toStdString(tempClientPackage);
 
     return res;
 }
@@ -142,7 +143,7 @@
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
         do {
-            binder = sm->getService(String16(kCameraServiceName));
+            binder = sm->getService(toString16(kCameraServiceName));
             if (binder != 0) {
                 break;
             }
@@ -161,7 +162,7 @@
 
 template <typename TCam, typename TCamTraits>
 sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
-                                               const String16& clientPackageName,
+                                               const std::string& clientPackageName,
                                                int clientUid, int clientPid, int targetSdkVersion,
                                                bool overrideToPortrait, bool forceSlowJpegMode)
 {
@@ -184,7 +185,7 @@
         c->mStatus = NO_ERROR;
     } else {
         ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
-                (cs == nullptr) ? "Service not available" : ret.toString8().string());
+                (cs == nullptr) ? "Service not available" : ret.toString8().c_str());
         c.clear();
     }
     return c;
@@ -269,7 +270,7 @@
             &count);
     if (!res.isOk()) {
         ALOGE("Error reading number of cameras: %s",
-                res.toString8().string());
+                res.toString8().c_str());
         count = 0;
     }
     return count;
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index a4ae71b..2e808d1 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -289,7 +289,7 @@
         return res;
     }
     // string.size() doesn't count the null termination character.
-    return updateImpl(tag, (const void*)string.string(), string.size() + 1);
+    return updateImpl(tag, (const void*)string.c_str(), string.size() + 1);
 }
 
 status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
@@ -809,7 +809,7 @@
     for (size_t i = 0; i < totalSectionCount; ++i) {
 
         const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
-                (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
+                (*vendorSections)[i - ANDROID_SECTION_COUNT].c_str();
 
         ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
 
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index e95c91c..272b113 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -205,7 +205,7 @@
 
 void CameraParameters::unflatten(const String8 &params)
 {
-    const char *a = params.string();
+    const char *a = params.c_str();
     const char *b;
 
     mMap.clear();
@@ -271,7 +271,7 @@
     String8 v = mMap.valueFor(String8(key));
     if (v.length() == 0)
         return 0;
-    return v.string();
+    return v.c_str();
 }
 
 int CameraParameters::getInt(const char *key) const
@@ -463,7 +463,7 @@
         String8 k, v;
         k = mMap.keyAt(i);
         v = mMap.valueAt(i);
-        ALOGD("%s: %s\n", k.string(), v.string());
+        ALOGD("%s: %s\n", k.c_str(), v.c_str());
     }
 }
 
@@ -478,10 +478,10 @@
         String8 k, v;
         k = mMap.keyAt(i);
         v = mMap.valueAt(i);
-        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        snprintf(buffer, 255, "\t%s: %s\n", k.c_str(), v.c_str());
         result.append(buffer);
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
diff --git a/camera/CameraParameters2.cpp b/camera/CameraParameters2.cpp
index a1cf355..1ccad08 100644
--- a/camera/CameraParameters2.cpp
+++ b/camera/CameraParameters2.cpp
@@ -52,14 +52,14 @@
             flattened += ";";
     }
 
-    ALOGV("%s: Flattened params = %s", __FUNCTION__, flattened.string());
+    ALOGV("%s: Flattened params = %s", __FUNCTION__, flattened.c_str());
 
     return flattened;
 }
 
 void CameraParameters2::unflatten(const String8 &params)
 {
-    const char *a = params.string();
+    const char *a = params.c_str();
     const char *b;
 
     mMap.clear();
@@ -128,7 +128,7 @@
     if (idx < 0) {
         return NULL;
     } else {
-        return mMap.valueAt(idx).string();
+        return mMap.valueAt(idx).c_str();
     }
 }
 
@@ -305,7 +305,7 @@
 void CameraParameters2::setPreviewFpsRange(int min_fps, int max_fps)
 {
     String8 str = String8::format("%d,%d", min_fps, max_fps);
-    set(CameraParameters::KEY_PREVIEW_FPS_RANGE, str.string());
+    set(CameraParameters::KEY_PREVIEW_FPS_RANGE, str.c_str());
 }
 
 void CameraParameters2::setPreviewFormat(const char *format)
@@ -357,7 +357,7 @@
         String8 k, v;
         k = mMap.keyAt(i);
         v = mMap.valueAt(i);
-        ALOGD("%s: %s\n", k.string(), v.string());
+        ALOGD("%s: %s\n", k.c_str(), v.c_str());
     }
 }
 
@@ -373,10 +373,10 @@
         String8 k, v;
         k = mMap.keyAt(i);
         v = mMap.valueAt(i);
-        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        snprintf(buffer, 255, "\t%s: %s\n", k.c_str(), v.c_str());
         result.append(buffer);
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 9e9793d..36bf24c 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -20,6 +20,7 @@
 #include <utils/String16.h>
 
 #include <camera/CameraSessionStats.h>
+#include <camera/StringUtils.h>
 
 #include <binder/Parcel.h>
 
@@ -282,8 +283,8 @@
         mSessionIndex(0),
         mCameraExtensionSessionStats() {}
 
-CameraSessionStats::CameraSessionStats(const String16& cameraId,
-        int facing, int newCameraState, const String16& clientName,
+CameraSessionStats::CameraSessionStats(const std::string& cameraId,
+        int facing, int newCameraState, const std::string& clientName,
         int apiLevel, bool isNdk, int32_t latencyMs, int64_t logId) :
                 mCameraId(cameraId),
                 mFacing(facing),
@@ -425,10 +426,10 @@
         return err;
     }
 
-    mCameraId = id;
+    mCameraId = toStdString(id);
     mFacing = facing;
     mNewCameraState = newCameraState;
-    mClientName = clientName;
+    mClientName = toStdString(clientName);
     mApiLevel = apiLevel;
     mIsNdk = isNdk;
     mLatencyMs = latencyMs;
@@ -440,7 +441,7 @@
     mResultErrorCount = resultErrorCount;
     mDeviceError = deviceError;
     mStreamStats = std::move(streamStats);
-    mUserTag = userTag;
+    mUserTag = toStdString(userTag);
     mVideoStabilizationMode = videoStabilizationMode;
     mSessionIndex = sessionIdx;
     mCameraExtensionSessionStats = extStats;
@@ -456,7 +457,7 @@
 
     status_t err = OK;
 
-    if ((err = parcel->writeString16(mCameraId)) != OK) {
+    if ((err = parcel->writeString16(toString16(mCameraId))) != OK) {
         ALOGE("%s: Failed to write camera id!", __FUNCTION__);
         return err;
     }
@@ -471,7 +472,7 @@
         return err;
     }
 
-    if ((err = parcel->writeString16(mClientName)) != OK) {
+    if ((err = parcel->writeString16(toString16(mClientName))) != OK) {
         ALOGE("%s: Failed to write client name!", __FUNCTION__);
         return err;
     }
@@ -531,7 +532,7 @@
         return err;
     }
 
-    if ((err = parcel->writeString16(mUserTag)) != OK) {
+    if ((err = parcel->writeString16(toString16(mUserTag))) != OK) {
         ALOGE("%s: Failed to write user tag!", __FUNCTION__);
         return err;
     }
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index bb880d1..9ff2578 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -18,6 +18,7 @@
 #include <utils/Log.h>
 
 #include <camera/CaptureResult.h>
+#include <camera/StringUtils.h>
 #include <binder/Parcel.h>
 
 namespace android {
@@ -47,7 +48,7 @@
             ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
             return res;
         }
-        errorPhysicalCameraId = cameraId;
+        errorPhysicalCameraId = toStdString(cameraId);
     }
     parcel->readInt64(&lastCompletedRegularFrameNumber);
     parcel->readInt64(&lastCompletedReprocessFrameNumber);
@@ -75,7 +76,7 @@
     if (errorPhysicalCameraId.size() > 0) {
         parcel->writeBool(true);
         status_t res = OK;
-        if ((res = parcel->writeString16(errorPhysicalCameraId)) != OK) {
+        if ((res = parcel->writeString16(toString16(errorPhysicalCameraId))) != OK) {
             ALOGE("%s: Failed to write physical camera ID to parcel: %d", __FUNCTION__, res);
             return res;
         }
@@ -96,13 +97,15 @@
 status_t PhysicalCaptureResultInfo::readFromParcel(const android::Parcel* parcel) {
     status_t res;
 
-    mPhysicalCameraId.setTo(u"");
+    mPhysicalCameraId = "";
     mPhysicalCameraMetadata.clear();
 
-    if ((res = parcel->readString16(&mPhysicalCameraId)) != OK) {
+    String16 physicalCameraId;
+    if ((res = parcel->readString16(&physicalCameraId)) != OK) {
         ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
         return res;
     }
+    mPhysicalCameraId = toStdString(physicalCameraId);
 
     if ((res = mPhysicalCameraMetadata.readFromParcel(parcel)) != OK) {
         ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
@@ -113,7 +116,7 @@
 
 status_t PhysicalCaptureResultInfo::writeToParcel(android::Parcel* parcel) const {
     status_t res;
-    if ((res = parcel->writeString16(mPhysicalCameraId)) != OK) {
+    if ((res = parcel->writeString16(toString16(mPhysicalCameraId))) != OK) {
         ALOGE("%s: Failed to write physical camera ID to parcel: %d",
                 __FUNCTION__, res);
         return res;
@@ -187,7 +190,8 @@
             return res;
         }
 
-        mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), cameraId, physicalMetadata);
+        mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), toStdString(cameraId),
+                physicalMetadata);
     }
     ALOGV("%s: Read physical metadata from parcel", __FUNCTION__);
 
@@ -228,7 +232,7 @@
         return BAD_VALUE;
     }
     for (const auto& physicalMetadata : mPhysicalMetadatas) {
-        if ((res = parcel->writeString16(physicalMetadata.mPhysicalCameraId)) != OK) {
+        if ((res = parcel->writeString16(toString16(physicalMetadata.mPhysicalCameraId))) != OK) {
             ALOGE("%s: Failed to write physical camera ID to parcel: %d",
                     __FUNCTION__, res);
             return res;
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp
index 151b653..ecf8a91 100644
--- a/camera/VendorTagDescriptor.cpp
+++ b/camera/VendorTagDescriptor.cpp
@@ -237,7 +237,7 @@
     if (index < 0) {
         return VENDOR_SECTION_NAME_ERR;
     }
-    return mSections[mTagToSectionMap.valueAt(index)].string();
+    return mSections[mTagToSectionMap.valueAt(index)].c_str();
 }
 
 const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
@@ -245,7 +245,7 @@
     if (index < 0) {
         return VENDOR_TAG_NAME_ERR;
     }
-    return mTagToNameMap.valueAt(index).string();
+    return mTagToNameMap.valueAt(index).c_str();
 }
 
 int VendorTagDescriptor::getTagType(uint32_t tag) const {
@@ -299,13 +299,13 @@
 status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const {
     ssize_t index = mReverseMapping.indexOfKey(section);
     if (index < 0) {
-        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
+        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.c_str());
         return BAD_VALUE;
     }
 
     ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
     if (nameIndex < 0) {
-        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
+        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.c_str());
         return BAD_VALUE;
     }
 
@@ -344,7 +344,7 @@
         const char* typeName = (type >= 0 && type < NUM_TYPES) ?
                 camera_metadata_type_names[type] : "UNKNOWN";
         dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
-            "", tag, name.string(), type, typeName, sectionName.string());
+            "", tag, name.c_str(), type, typeName, sectionName.c_str());
     }
 
 }
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index f8e1631..ed37b2d 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -82,7 +82,7 @@
      */
     ICamera connect(ICameraClient client,
             int cameraId,
-            String opPackageName,
+            @utf8InCpp String opPackageName,
             int clientUid, int clientPid,
             int targetSdkVersion,
             boolean overrideToPortrait,
@@ -93,9 +93,9 @@
      * Only supported for device HAL versions >= 3.2
      */
     ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,
-            String cameraId,
-            String opPackageName,
-            @nullable String featureId,
+            @utf8InCpp String cameraId,
+            @utf8InCpp String opPackageName,
+            @nullable @utf8InCpp String featureId,
             int clientUid, int oomScoreOffset,
             int targetSdkVersion,
             boolean overrideToPortrait);
@@ -139,7 +139,7 @@
      * Read the static camera metadata for a camera device.
      * Only supported for device HAL versions >= 3.2
      */
-    CameraMetadataNative getCameraCharacteristics(String cameraId, int targetSdkVersion,
+    CameraMetadataNative getCameraCharacteristics(@utf8InCpp String cameraId, int targetSdkVersion,
             boolean overrideToPortrait);
 
     /**
@@ -160,7 +160,7 @@
     /**
      * Read the legacy camera1 parameters into a String
      */
-    String getLegacyParameters(int cameraId);
+    @utf8InCpp String getLegacyParameters(int cameraId);
 
     /**
      * apiVersion constants for supportsCameraApi
@@ -169,21 +169,21 @@
     const int API_VERSION_2 = 2;
 
     // Determines if a particular API version is supported directly for a cameraId.
-    boolean supportsCameraApi(String cameraId, int apiVersion);
+    boolean supportsCameraApi(@utf8InCpp String cameraId, int apiVersion);
     // Determines if a cameraId is a hidden physical camera of a logical multi-camera.
-    boolean isHiddenPhysicalCamera(String cameraId);
+    boolean isHiddenPhysicalCamera(@utf8InCpp String cameraId);
     // Inject the external camera to replace the internal camera session.
-    ICameraInjectionSession injectCamera(String packageName, String internalCamId,
-            String externalCamId, in ICameraInjectionCallback CameraInjectionCallback);
+    ICameraInjectionSession injectCamera(@utf8InCpp String packageName, @utf8InCpp String internalCamId,
+            @utf8InCpp String externalCamId, in ICameraInjectionCallback CameraInjectionCallback);
 
-    void setTorchMode(String cameraId, boolean enabled, IBinder clientBinder);
+    void setTorchMode(@utf8InCpp String cameraId, boolean enabled, IBinder clientBinder);
 
     // Change the brightness level of the flash unit associated with cameraId to strengthLevel.
     // If the torch is in OFF state and strengthLevel > 0 then the torch will also be turned ON.
-    void turnOnTorchWithStrengthLevel(String cameraId, int strengthLevel, IBinder clientBinder);
+    void turnOnTorchWithStrengthLevel(@utf8InCpp String cameraId, int strengthLevel, IBinder clientBinder);
 
     // Get the brightness level of the flash unit associated with cameraId.
-    int getTorchStrengthLevel(String cameraId);
+    int getTorchStrengthLevel(@utf8InCpp String cameraId);
 
     /**
      * Notify the camera service of a system event.  Should only be called from system_server.
@@ -233,7 +233,7 @@
      *
      * @return the key that must be used to report updates to previously reported stats.
      */
-    String reportExtensionSessionStats(in CameraExtensionSessionStats stats);
+    @utf8InCpp String reportExtensionSessionStats(in CameraExtensionSessionStats stats);
 
     // Bitfield constants for notifyDeviceStateChange
     // All bits >= 32 are for custom vendor states
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index 5f17f5b..23a87d3 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -51,13 +51,14 @@
     // Use to initialize variables only
     const int STATUS_UNKNOWN          = -1;
 
-    oneway void onStatusChanged(int status, String cameraId);
+    oneway void onStatusChanged(int status, @utf8InCpp String cameraId);
 
     /**
      * Notify registered client about status changes for a physical camera backing
      * a logical camera.
      */
-    oneway void onPhysicalCameraStatusChanged(int status, String cameraId, String physicalCameraId);
+    oneway void onPhysicalCameraStatusChanged(int status, @utf8InCpp String cameraId,
+            @utf8InCpp String physicalCameraId);
 
     /**
      * The torch mode status of a camera.
@@ -81,9 +82,9 @@
     // Use to initialize variables only
     const int TORCH_STATUS_UNKNOWN = -1;
 
-    oneway void onTorchStatusChanged(int status, String cameraId);
+    oneway void onTorchStatusChanged(int status, @utf8InCpp String cameraId);
 
-    oneway void onTorchStrengthLevelChanged(String cameraId, int newTorchStrength);
+    oneway void onTorchStrengthLevelChanged(@utf8InCpp String cameraId, int newTorchStrength);
 
     /**
      * Notify registered clients about camera access priority changes.
@@ -97,6 +98,6 @@
      * Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission
      * will receive such callbacks.
      */
-    oneway void onCameraOpened(String cameraId, String clientPackageId);
-    oneway void onCameraClosed(String cameraId);
+    oneway void onCameraOpened(@utf8InCpp String cameraId, @utf8InCpp String clientPackageId);
+    oneway void onCameraClosed(@utf8InCpp String cameraId);
 }
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 4faa6b4..dcd69b0 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -44,14 +44,14 @@
      * {@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_180},
      * {@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_270}).
      */
-    int getRotateAndCropOverride(String packageName, int lensFacing, int userId);
+    int getRotateAndCropOverride(@utf8InCpp String packageName, int lensFacing, int userId);
 
     /**
      * Returns the necessary autoframing override for the top activity which
      * will be one of ({@link android.hardware.camera2.CameraMetadata#AUTOFRAMING_FALSE},
      * {@link android.hardware.camera2.CameraMetadata#AUTOFRAMING_TRUE}).
      */
-    int getAutoframingOverride(String packageName);
+    int getAutoframingOverride(@utf8InCpp String packageName);
 
     /**
      * Checks if the camera has been disabled via device policy.
diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp
index 7a8a4ba..071f34e 100644
--- a/camera/camera2/CaptureRequest.cpp
+++ b/camera/camera2/CaptureRequest.cpp
@@ -21,6 +21,7 @@
 #include <utils/String16.h>
 
 #include <camera/camera2/CaptureRequest.h>
+#include <camera/StringUtils.h>
 
 #include <binder/Parcel.h>
 #include <gui/Surface.h>
@@ -74,7 +75,7 @@
             return err;
         }
         ALOGV("%s: Read metadata from parcel", __FUNCTION__);
-        mPhysicalCameraSettings.push_back({std::string(String8(id).string()), settings});
+        mPhysicalCameraSettings.push_back({toStdString(id), settings});
     }
 
     int isReprocess = 0;
@@ -157,7 +158,7 @@
             ALOGE("%s: Failed to read user tag!", __FUNCTION__);
             return BAD_VALUE;
         }
-        mUserTag = String8(userTag).c_str();
+        mUserTag = toStdString(userTag);
     }
 
     return OK;
@@ -179,7 +180,7 @@
     }
 
     for (const auto &it : mPhysicalCameraSettings) {
-        if ((err = parcel->writeString16(String16(it.id.c_str()))) != OK) {
+        if ((err = parcel->writeString16(toString16(it.id))) != OK) {
             ALOGE("%s: Failed to camera id!", __FUNCTION__);
             return err;
         }
@@ -232,7 +233,7 @@
         parcel->writeInt32(0);
     } else {
         parcel->writeInt32(1);
-        parcel->writeString16(String16(mUserTag.c_str()));
+        parcel->writeString16(toString16(mUserTag));
     }
 
     return OK;
diff --git a/camera/camera2/ConcurrentCamera.cpp b/camera/camera2/ConcurrentCamera.cpp
index 01a695c..67aa876 100644
--- a/camera/camera2/ConcurrentCamera.cpp
+++ b/camera/camera2/ConcurrentCamera.cpp
@@ -20,6 +20,7 @@
 #include <utils/String16.h>
 
 #include <camera/camera2/ConcurrentCamera.h>
+#include <camera/StringUtils.h>
 
 #include <binder/Parcel.h>
 
@@ -53,7 +54,7 @@
             ALOGE("%s: Failed to read camera id!", __FUNCTION__);
             return err;
         }
-        mConcurrentCameraIds.push_back(std::string(String8(id).string()));
+        mConcurrentCameraIds.push_back(toStdString(id));
     }
     return OK;
 }
@@ -73,7 +74,7 @@
     }
 
     for (const auto &it : mConcurrentCameraIds) {
-        if ((err = parcel->writeString16(String16(it.c_str()))) != OK) {
+        if ((err = parcel->writeString16(toString16(it))) != OK) {
             ALOGE("%s: Failed to write the camera id string to parcel: %d", __FUNCTION__, err);
             return err;
         }
@@ -99,7 +100,7 @@
         ALOGE("%s: Failed to read sessionConfiguration!", __FUNCTION__);
         return err;
     }
-    mCameraId = std::string(String8(id).string());
+    mCameraId = toStdString(id);
     return OK;
 }
 
@@ -111,7 +112,7 @@
     }
 
     status_t err = OK;
-    if ((err = parcel->writeString16(String16(mCameraId.c_str()))) != OK) {
+    if ((err = parcel->writeString16(toString16(mCameraId))) != OK) {
         ALOGE("%s: Failed to write camera id!", __FUNCTION__);
         return err;
     }
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index da4484a..73b153c 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -21,6 +21,7 @@
 #include <utils/Log.h>
 
 #include <camera/camera2/OutputConfiguration.h>
+#include <camera/StringUtils.h>
 #include <binder/Parcel.h>
 #include <gui/view/Surface.h>
 #include <system/camera_metadata.h>
@@ -65,7 +66,7 @@
     return mIsShared;
 }
 
-String16 OutputConfiguration::getPhysicalCameraId() const {
+std::string OutputConfiguration::getPhysicalCameraId() const {
     return mPhysicalCameraId;
 }
 
@@ -183,7 +184,9 @@
         return err;
     }
 
-    parcel->readString16(&mPhysicalCameraId);
+    String16 physicalCameraId;
+    parcel->readString16(&physicalCameraId);
+    mPhysicalCameraId = toStdString(physicalCameraId);
 
     int isMultiResolution = 0;
     if ((err = parcel->readInt32(&isMultiResolution)) != OK) {
@@ -246,7 +249,7 @@
     for (auto& surface : surfaceShims) {
         ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
                 surface.graphicBufferProducer.get(),
-                String8(surface.name).string());
+                toString8(surface.name).c_str());
         mGbps.push_back(surface.graphicBufferProducer);
     }
 
@@ -258,14 +261,14 @@
           " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %" PRId64
           ", timestampBase = %d, mirrorMode = %d, useReadoutTimestamp = %d",
           __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType,
-          String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase,
+          mPhysicalCameraId.c_str(), mIsMultiResolution, mStreamUseCase, timestampBase,
           mMirrorMode, mUseReadoutTimestamp);
 
     return err;
 }
 
 OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
-        const String16& physicalId,
+        const std::string& physicalId,
         int surfaceSetID, bool isShared) {
     mGbps.push_back(gbp);
     mRotation = rotation;
@@ -284,7 +287,7 @@
 
 OutputConfiguration::OutputConfiguration(
         const std::vector<sp<IGraphicBufferProducer>>& gbps,
-    int rotation, const String16& physicalCameraId, int surfaceSetID,  int surfaceType,
+    int rotation, const std::string& physicalCameraId, int surfaceSetID,  int surfaceType,
     int width, int height, bool isShared)
   : mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType),
     mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
@@ -331,7 +334,8 @@
     err = parcel->writeParcelableVector(surfaceShims);
     if (err != OK) return err;
 
-    err = parcel->writeString16(mPhysicalCameraId);
+    String16 physicalCameraId = toString16(mPhysicalCameraId);
+    err = parcel->writeString16(physicalCameraId);
     if (err != OK) return err;
 
     err = parcel->writeInt32(mIsMultiResolution ? 1 : 0);
diff --git a/camera/include/camera/Camera.h b/camera/include/camera/Camera.h
index 21b57af..6655f82 100644
--- a/camera/include/camera/Camera.h
+++ b/camera/include/camera/Camera.h
@@ -56,9 +56,9 @@
     typedef CameraListener                     TCamListener;
     typedef ::android::hardware::ICamera       TCamUser;
     typedef ::android::hardware::ICameraClient TCamCallbacks;
-    typedef ::android::binder::Status(::android::hardware::ICameraService::*TCamConnectService)
+    typedef ::android::binder::Status (::android::hardware::ICameraService::*TCamConnectService)
         (const sp<::android::hardware::ICameraClient>&,
-        int, const String16&, int, int, int, bool, bool,
+        int, const std::string&, int, int, int, bool, bool,
         /*out*/
         sp<::android::hardware::ICamera>*);
     static TCamConnectService     fnConnectService;
@@ -80,7 +80,7 @@
             // construct a camera client from an existing remote
     static  sp<Camera>  create(const sp<::android::hardware::ICamera>& camera);
     static  sp<Camera>  connect(int cameraId,
-                                const String16& clientPackageName,
+                                const std::string& clientPackageName,
                                 int clientUid, int clientPid, int targetSdkVersion,
                                 bool overrideToPortrait, bool forceSlowJpegMode);
 
diff --git a/camera/include/camera/CameraBase.h b/camera/include/camera/CameraBase.h
index b20dc1b..6af7f2a 100644
--- a/camera/include/camera/CameraBase.h
+++ b/camera/include/camera/CameraBase.h
@@ -73,7 +73,7 @@
     /**
      * The name of the camera device
      */
-    String8 cameraId;
+    std::string cameraId;
 
     /**
      * Its current status, one of the ICameraService::STATUS_* fields
@@ -83,18 +83,18 @@
     /**
      * Unavailable physical camera names for a multi-camera device
      */
-    std::vector<String8> unavailablePhysicalIds;
+    std::vector<std::string> unavailablePhysicalIds;
 
     /**
      * Client package name if camera is open, otherwise not applicable
      */
-    String8 clientPackage;
+    std::string clientPackage;
 
     virtual status_t writeToParcel(android::Parcel* parcel) const;
     virtual status_t readFromParcel(const android::Parcel* parcel);
 
-    CameraStatus(String8 id, int32_t s, const std::vector<String8>& unavailSubIds,
-            const String8& clientPkg) : cameraId(id), status(s),
+    CameraStatus(std::string id, int32_t s, const std::vector<std::string>& unavailSubIds,
+            const std::string& clientPkg) : cameraId(id), status(s),
             unavailablePhysicalIds(unavailSubIds), clientPackage(clientPkg) {}
     CameraStatus() : status(ICameraServiceListener::STATUS_PRESENT) {}
 };
@@ -118,7 +118,7 @@
     typedef typename TCamTraits::TCamConnectService TCamConnectService;
 
     static sp<TCam>      connect(int cameraId,
-                                 const String16& clientPackageName,
+                                 const std::string& clientPackageName,
                                  int clientUid, int clientPid, int targetSdkVersion,
                                  bool overrideToPortrait, bool forceSlowJpegMode);
     virtual void         disconnect();
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 071bc73..70ca0b3 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
 #define ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
 
+#include <string>
+
 #include <binder/Parcelable.h>
 
 #include <camera/CameraMetadata.h>
@@ -121,10 +123,10 @@
     static const int CAMERA_API_LEVEL_1;
     static const int CAMERA_API_LEVEL_2;
 
-    String16 mCameraId;
+    std::string mCameraId;
     int mFacing;
     int mNewCameraState;
-    String16 mClientName;
+    std::string mClientName;
     int mApiLevel;
     bool mIsNdk;
     // latency in ms for camera open, close, or session creation.
@@ -157,7 +159,7 @@
     // Whether the device runs into an error state
     bool mDeviceError;
     std::vector<CameraStreamStats> mStreamStats;
-    String16 mUserTag;
+    std::string mUserTag;
     int mVideoStabilizationMode;
     int mSessionIndex;
 
@@ -165,8 +167,8 @@
 
     // Constructors
     CameraSessionStats();
-    CameraSessionStats(const String16& cameraId, int facing, int newCameraState,
-                       const String16& clientName, int apiLevel, bool isNdk, int32_t latencyMs,
+    CameraSessionStats(const std::string& cameraId, int facing, int newCameraState,
+                       const std::string& clientName, int apiLevel, bool isNdk, int32_t latencyMs,
                        int64_t logId);
 
     virtual status_t readFromParcel(const android::Parcel* parcel) override;
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index de534ab..e08c9ca 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -74,7 +74,7 @@
      * a reference to physical camera device.
      * Empty otherwise.
      */
-    String16  errorPhysicalCameraId;
+    std::string errorPhysicalCameraId;
 
     // The last completed frame numbers shouldn't be checked in onResultReceived() and notifyError()
     // because the output buffers could be arriving after onResultReceived() and
@@ -150,13 +150,13 @@
         : mPhysicalCameraId(),
           mPhysicalCameraMetadata() {
     }
-    PhysicalCaptureResultInfo(const String16& cameraId,
+    PhysicalCaptureResultInfo(const std::string& cameraId,
             const CameraMetadata& cameraMetadata)
             : mPhysicalCameraId(cameraId),
               mPhysicalCameraMetadata(cameraMetadata) {
     }
 
-    String16  mPhysicalCameraId;
+    std::string mPhysicalCameraId;
     CameraMetadata mPhysicalCameraMetadata;
 
     virtual status_t                readFromParcel(const android::Parcel* parcel) override;
diff --git a/camera/include/camera/StringUtils.h b/camera/include/camera/StringUtils.h
new file mode 100644
index 0000000..547750f
--- /dev/null
+++ b/camera/include/camera/StringUtils.h
@@ -0,0 +1,82 @@
+/*
+ * 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_SERVERS_CAMERA_STRINGUTILS_H
+#define ANDROID_SERVERS_CAMERA_STRINGUTILS_H
+
+#include <codecvt>
+#include <locale>
+#include <memory>
+#include <optional>
+#include <string>
+
+#include <fmt/printf.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+    inline String8 toString8(const std::string &str) {
+        return String8(str.c_str());
+    }
+
+    inline String8 toString8(const String16 &str) {
+        return String8(str);
+    }
+
+    inline String8 toString8(const char *str) {
+        return String8(str);
+    }
+
+    inline String16 toString16(const std::string &str) {
+        return String16(str.c_str());
+    }
+
+    inline String16 toString16(const String8 &str) {
+        return String16(str);
+    }
+
+    inline String16 toString16(const char *str) {
+        return String16(str);
+    }
+
+    inline std::optional<String16> toString16(std::optional<std::string> str) {
+        if (str.has_value()) {
+            return std::optional<String16>(toString16(str.value()));
+        }
+
+        return std::nullopt;
+    }
+
+    inline std::string toStdString(const String8 &str) {
+        return std::string(str.c_str());
+    }
+
+    inline std::string toStdString(const String16 &str) {
+        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+        return convert.to_bytes(str.c_str());
+    }
+
+    /**
+     * Convert a non-null-terminated UTF16 string to a UTF8 string (i.e. in jni functions)
+     * len is the number of characters.
+     */
+    inline std::string toStdString(const char16_t *str, size_t len) {
+        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+        return convert.to_bytes(str, str + len);
+    }
+} // namespace android
+
+#endif // ANDROID_SERVERS_CAMERA_STRINGUTILS_H
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index 16fddb5..3f74b4a 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
 #define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
 
+#include <string>
+
 #include <gui/IGraphicBufferProducer.h>
 #include <binder/Parcelable.h>
 
@@ -63,7 +65,7 @@
     int32_t                    getColorSpace() const;
     bool                       isDeferred() const;
     bool                       isShared() const;
-    String16                   getPhysicalCameraId() const;
+    std::string                getPhysicalCameraId() const;
     bool                       isMultiResolution() const;
     int64_t                    getStreamUseCase() const;
     int                        getTimestampBase() const;
@@ -90,11 +92,11 @@
     OutputConfiguration(const android::Parcel& parcel);
 
     OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
-            const String16& physicalCameraId,
+            const std::string& physicalCameraId,
             int surfaceSetID = INVALID_SET_ID, bool isShared = false);
 
     OutputConfiguration(const std::vector<sp<IGraphicBufferProducer>>& gbps,
-                        int rotation, const String16& physicalCameraId,
+                        int rotation, const std::string& physicalCameraId,
                         int surfaceSetID = INVALID_SET_ID,
                         int surfaceType = OutputConfiguration::SURFACE_TYPE_UNKNOWN, int width = 0,
                         int height = 0, bool isShared = false);
@@ -192,7 +194,7 @@
     int                        mHeight;
     bool                       mIsDeferred;
     bool                       mIsShared;
-    String16                   mPhysicalCameraId;
+    std::string                mPhysicalCameraId;
     bool                       mIsMultiResolution;
     std::vector<int32_t>       mSensorPixelModesUsed;
     int64_t                    mDynamicRangeProfile;
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index bfd02b3..24a11e3 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -165,11 +165,6 @@
     include_dirs: [
         "system/media/private/camera/include",
     ],
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-    },
 }
 
 cc_test {
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 1dae0f9..024ed20 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -21,6 +21,7 @@
 #include <inttypes.h>
 #include <android/hardware/ICameraService.h>
 #include <gui/Surface.h>
+#include <camera/StringUtils.h>
 #include "ACameraDevice.h"
 #include "ACameraMetadata.h"
 #include "ACaptureRequest.h"
@@ -162,7 +163,7 @@
             templateId);
         return ACAMERA_ERROR_INVALID_PARAMETER;
     } else if (!remoteRet.isOk()) {
-        ALOGE("Create capture request failed: %s", remoteRet.toString8().string());
+        ALOGE("Create capture request failed: %s", remoteRet.toString8().c_str());
         return ACAMERA_ERROR_UNKNOWN;
     }
     ACaptureRequest* outReq = new ACaptureRequest();
@@ -234,8 +235,7 @@
             return ret;
         }
 
-        String16 physicalId16(output.mPhysicalCameraId.c_str());
-        OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
+        OutputConfiguration outConfig(iGBP, output.mRotation, output.mPhysicalCameraId,
                 OutputConfiguration::INVALID_SET_ID, true);
 
         for (auto& anw : output.mSharedWindows) {
@@ -299,8 +299,7 @@
         return ret;
     }
 
-    String16 physicalId16(output->mPhysicalCameraId.c_str());
-    OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
+    OutputConfiguration outConfig(iGBP, output->mRotation, output->mPhysicalCameraId,
             OutputConfiguration::INVALID_SET_ID, true);
 
     for (auto& anw : output->mSharedWindows) {
@@ -318,22 +317,22 @@
         switch (remoteRet.serviceSpecificErrorCode()) {
             case hardware::ICameraService::ERROR_INVALID_OPERATION:
                 ALOGE("Camera device %s invalid operation: %s", getId(),
-                        remoteRet.toString8().string());
+                        remoteRet.toString8().c_str());
                 return ACAMERA_ERROR_INVALID_OPERATION;
                 break;
             case hardware::ICameraService::ERROR_ALREADY_EXISTS:
                 ALOGE("Camera device %s output surface already exists: %s", getId(),
-                        remoteRet.toString8().string());
+                        remoteRet.toString8().c_str());
                 return ACAMERA_ERROR_INVALID_PARAMETER;
                 break;
             case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
                 ALOGE("Camera device %s invalid input argument: %s", getId(),
-                        remoteRet.toString8().string());
+                        remoteRet.toString8().c_str());
                 return ACAMERA_ERROR_INVALID_PARAMETER;
                 break;
             default:
                 ALOGE("Camera device %s failed to add shared output: %s", getId(),
-                        remoteRet.toString8().string());
+                        remoteRet.toString8().c_str());
                 return ACAMERA_ERROR_UNKNOWN;
         }
     }
@@ -547,7 +546,7 @@
             ALOGV("Repeating request is already stopped.");
             return ACAMERA_OK;
         } else if (!remoteRet.isOk()) {
-            ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
+            ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().c_str());
             return ACAMERA_ERROR_UNKNOWN;
         }
         checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
@@ -599,7 +598,7 @@
     int64_t lastFrameNumber;
     binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
     if (!remoteRet.isOk()) {
-        ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
+        ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().c_str());
         return ACAMERA_ERROR_UNKNOWN;
     }
     if (mRepeatingSequenceId != REQUEST_ID_NONE) {
@@ -623,7 +622,7 @@
 
     binder::Status remoteRet = mRemote->waitUntilIdle();
     if (!remoteRet.isOk()) {
-        ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().string());
+        ALOGE("Camera device %s waitUntilIdle failed: %s", getId(), remoteRet.toString8().c_str());
         // TODO: define a function to convert status_t -> camera_status_t
         return ACAMERA_ERROR_UNKNOWN;
     }
@@ -683,9 +682,8 @@
         if (ret != ACAMERA_OK) {
             return ret;
         }
-        String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
         outputSet.insert(std::make_pair(
-                anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
+                anw, OutputConfiguration(iGBP, outConfig.mRotation, outConfig.mPhysicalCameraId,
                         OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
     }
     auto addSet = outputSet;
@@ -734,7 +732,7 @@
 
     binder::Status remoteRet = mRemote->beginConfigure();
     if (!remoteRet.isOk()) {
-        ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().string());
+        ALOGE("Camera device %s begin configure failed: %s", getId(), remoteRet.toString8().c_str());
         return ACAMERA_ERROR_UNKNOWN;
     }
 
@@ -743,7 +741,7 @@
         remoteRet = mRemote->deleteStream(streamId);
         if (!remoteRet.isOk()) {
             ALOGE("Camera device %s failed to remove stream %d: %s", getId(), streamId,
-                    remoteRet.toString8().string());
+                    remoteRet.toString8().c_str());
             return ACAMERA_ERROR_UNKNOWN;
         }
         mConfiguredOutputs.erase(streamId);
@@ -755,7 +753,7 @@
         remoteRet = mRemote->createStream(outputPair.second, &streamId);
         if (!remoteRet.isOk()) {
             ALOGE("Camera device %s failed to create stream: %s", getId(),
-                    remoteRet.toString8().string());
+                    remoteRet.toString8().c_str());
             return ACAMERA_ERROR_UNKNOWN;
         }
         mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
@@ -770,10 +768,10 @@
             ns2ms(startTimeNs), &offlineStreamIds);
     if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
         ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
-                remoteRet.toString8().string());
+                remoteRet.toString8().c_str());
         return ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
     } else if (!remoteRet.isOk()) {
-        ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().string());
+        ALOGE("Camera device %s end configure failed: %s", getId(), remoteRet.toString8().c_str());
         return ACAMERA_ERROR_UNKNOWN;
     }
 
@@ -919,8 +917,8 @@
         msg->setObject(kSessionSpKey, session);
         if (cbh.mIsLogicalCameraCallback) {
             if (resultExtras.errorPhysicalCameraId.size() > 0) {
-                String8 cameraId(resultExtras.errorPhysicalCameraId);
-                msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
+                String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
+                msg->setString(kFailingPhysicalCameraId, cameraId.c_str(), cameraId.size());
             }
             msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
         } else {
@@ -1215,7 +1213,7 @@
                     std::vector<std::string> physicalCameraIds;
                     std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
                     for (size_t i = 0; i < physicalResultInfo.size(); i++) {
-                        String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
+                        String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
                         physicalCameraIds.push_back(physicalId8.c_str());
 
                         CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 382d6ce..4658d18 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -66,7 +66,7 @@
                   ACameraDevice* wrapper);
     ~CameraDevice();
 
-    inline const char* getId() const { return mCameraId.string(); }
+    inline const char* getId() const { return mCameraId.c_str(); }
 
     camera_status_t createCaptureRequest(
             ACameraDevice_request_template templateId,
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 837b5be..5d3b65b 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -25,6 +25,7 @@
 #include <cutils/properties.h>
 #include <stdlib.h>
 #include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
 #include <camera/VendorTagDescriptor.h>
 
 using namespace android::acam;
@@ -84,7 +85,7 @@
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
         do {
-            binder = sm->getService(String16(kCameraServiceName));
+            binder = sm->getService(toString16(kCameraServiceName));
             if (binder != nullptr) {
                 break;
             }
@@ -165,7 +166,7 @@
                 } else {
                     VendorTagDescriptorCache::clearGlobalVendorTagCache();
                     ALOGE("%s: Failed to setup vendor tag cache: %s",
-                            __FUNCTION__, res.toString8().string());
+                            __FUNCTION__, res.toString8().c_str());
                 }
             }
         } else if (ret.serviceSpecificErrorCode() ==
@@ -175,7 +176,7 @@
             VendorTagDescriptor::clearGlobalVendorTagDescriptor();
         } else {
             ALOGE("%s: Failed to get vendor tag descriptors: %s",
-                    __FUNCTION__, ret.toString8().string());
+                    __FUNCTION__, ret.toString8().c_str());
         }
     }
     ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
@@ -188,12 +189,12 @@
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
     if (cm != nullptr) {
         AutoMutex lock(cm->mLock);
-        std::vector<String8> cameraIdList;
+        std::vector<std::string> cameraIdList;
         for (auto& pair : cm->mDeviceStatusMap) {
             cameraIdList.push_back(pair.first);
         }
 
-        for (String8 cameraId : cameraIdList) {
+        for (const std::string& cameraId : cameraIdList) {
             cm->onStatusChangedLocked(
                     CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
         }
@@ -259,7 +260,7 @@
     // Send initial callbacks if callback is newly registered
     if (pair.second) {
         for (auto& pair : mDeviceStatusMap) {
-            const String8& cameraId = pair.first;
+            const std::string& cameraId = pair.first;
             int32_t status = pair.second.getStatus();
             // Don't send initial callbacks for camera ids which don't support
             // camera2
@@ -273,12 +274,12 @@
                     cb.mAvailable : cb.mUnavailable;
             msg->setPointer(kCallbackFpKey, (void *) cbFunc);
             msg->setPointer(kContextKey, cb.mContext);
-            msg->setString(kCameraIdKey, AString(cameraId));
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
             mPendingCallbackCnt++;
             msg->post();
 
             // Physical camera unavailable callback
-            std::set<String8> unavailablePhysicalCameras =
+            std::set<std::string> unavailablePhysicalCameras =
                     pair.second.getUnavailablePhysicalIds();
             for (const auto& physicalCameraId : unavailablePhysicalCameras) {
                 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
@@ -286,8 +287,8 @@
                         cb.mPhysicalCamUnavailable;
                 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
                 msg->setPointer(kContextKey, cb.mContext);
-                msg->setString(kCameraIdKey, AString(cameraId));
-                msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+                msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+                msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
                 mPendingCallbackCnt++;
                 msg->post();
             }
@@ -295,11 +296,11 @@
     }
 }
 
-bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
+bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
     bool camera2Support = false;
     auto cs = getCameraServiceLocked();
     binder::Status serviceRet =
-        cs->supportsCameraApi(String16(cameraId),
+        cs->supportsCameraApi(cameraId,
                 hardware::ICameraService::API_VERSION_2, &camera2Support);
     if (!serviceRet.isOk()) {
         ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId  %s",
@@ -309,7 +310,7 @@
     return camera2Support;
 }
 
-void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
+void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) {
     // Ensure that we have initialized/refreshed the list of available devices
     Mutex::Autolock _l(mLock);
     // Needed to make sure we're connected to cameraservice
@@ -459,10 +460,10 @@
 }
 
 binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
-        int32_t status, const String16& cameraId) {
+        int32_t status, const std::string& cameraId) {
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
     if (cm != nullptr) {
-        cm->onStatusChanged(status, String8(cameraId));
+        cm->onStatusChanged(status, cameraId);
     } else {
         ALOGE("Cannot deliver status change. Global camera manager died");
     }
@@ -470,10 +471,10 @@
 }
 
 binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
-        int32_t status, const String16& cameraId, const String16& physicalCameraId) {
+        int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
     if (cm != nullptr) {
-        cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
+        cm->onStatusChanged(status, cameraId, physicalCameraId);
     } else {
         ALOGE("Cannot deliver physical camera status change. Global camera manager died");
     }
@@ -495,13 +496,13 @@
 }
 
 void CameraManagerGlobal::onStatusChanged(
-        int32_t status, const String8& cameraId) {
+        int32_t status, const std::string& cameraId) {
     Mutex::Autolock _l(mLock);
     onStatusChangedLocked(status, cameraId);
 }
 
 void CameraManagerGlobal::onStatusChangedLocked(
-        int32_t status, const String8& cameraId) {
+        int32_t status, const std::string& cameraId) {
     if (!validStatus(status)) {
         ALOGE("%s: Invalid status %d", __FUNCTION__, status);
         return;
@@ -534,7 +535,7 @@
                     cb.mAvailable : cb.mUnavailable;
             msg->setPointer(kCallbackFpKey, (void *) cbFp);
             msg->setPointer(kContextKey, cb.mContext);
-            msg->setString(kCameraIdKey, AString(cameraId));
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
             mPendingCallbackCnt++;
             msg->post();
         }
@@ -545,13 +546,13 @@
 }
 
 void CameraManagerGlobal::onStatusChanged(
-        int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+        int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
     Mutex::Autolock _l(mLock);
     onStatusChangedLocked(status, cameraId, physicalCameraId);
 }
 
 void CameraManagerGlobal::onStatusChangedLocked(
-        int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+        int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
     if (!validStatus(status)) {
         ALOGE("%s: Invalid status %d", __FUNCTION__, status);
         return;
@@ -567,7 +568,7 @@
     if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
             logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
         ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
-                __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
+                __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
         return;
     }
 
@@ -588,8 +589,8 @@
                     cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
             msg->setPointer(kCallbackFpKey, (void *) cbFp);
             msg->setPointer(kContextKey, cb.mContext);
-            msg->setString(kCameraIdKey, AString(cameraId));
-            msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+            msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
             mPendingCallbackCnt++;
             msg->post();
         }
@@ -607,20 +608,20 @@
 }
 
 bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
-        const String8& physicalCameraId) {
+        const std::string& physicalCameraId) {
     std::lock_guard<std::mutex> lock(mLock);
     auto result = unavailablePhysicalIds.insert(physicalCameraId);
     return result.second;
 }
 
 bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
-        const String8& physicalCameraId) {
+        const std::string& physicalCameraId) {
     std::lock_guard<std::mutex> lock(mLock);
     auto count = unavailablePhysicalIds.erase(physicalCameraId);
     return count > 0;
 }
 
-std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
+std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
     std::lock_guard<std::mutex> lock(mLock);
     return unavailablePhysicalIds;
 }
@@ -635,7 +636,7 @@
 ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
     Mutex::Autolock _l(mLock);
 
-    std::vector<String8> idList;
+    std::vector<std::string> idList;
     CameraManagerGlobal::getInstance()->getCameraIdList(&idList);
 
     int numCameras = idList.size();
@@ -652,7 +653,7 @@
         return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
     }
     for (int i = 0; i < numCameras; i++) {
-        const char* src = idList[i].string();
+        const char* src = idList[i].c_str();
         size_t dstSize = strlen(src) + 1;
         char* dst = new char[dstSize];
         if (!dst) {
@@ -694,7 +695,7 @@
 
     CameraMetadata rawMetadata;
     int targetSdkVersion = android_get_application_target_sdk_version();
-    binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr),
+    binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
             targetSdkVersion, /*overrideToPortrait*/false, &rawMetadata);
     if (!serviceRet.isOk()) {
         switch(serviceRet.serviceSpecificErrorCode()) {
@@ -706,7 +707,7 @@
                 return ACAMERA_ERROR_INVALID_PARAMETER;
             default:
                 ALOGE("Get camera characteristics from camera service failed: %s",
-                        serviceRet.toString8().string());
+                        serviceRet.toString8().c_str());
                 return ACAMERA_ERROR_UNKNOWN; // should not reach here
         }
     }
@@ -745,12 +746,12 @@
     // No way to get package name from native.
     // Send a zero length package name and let camera service figure it out from UID
     binder::Status serviceRet = cs->connectDevice(
-            callbacks, String16(cameraId), String16(""), {},
+            callbacks, cameraId, "", {},
             hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
             targetSdkVersion, /*overrideToPortrait*/false, /*out*/&deviceRemote);
 
     if (!serviceRet.isOk()) {
-        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
+        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
         // Convert serviceRet to camera_status_t
         switch(serviceRet.serviceSpecificErrorCode()) {
             case hardware::ICameraService::ERROR_DISCONNECTED:
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 0dd79da..c135d0f 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -62,7 +62,7 @@
     /**
      * Return camera IDs that support camera2
      */
-    void getCameraIdList(std::vector<String8> *cameraIds);
+    void getCameraIdList(std::vector<std::string> *cameraIds);
 
   private:
     sp<hardware::ICameraService> mCameraService;
@@ -87,23 +87,23 @@
     class CameraServiceListener final : public hardware::BnCameraServiceListener {
       public:
         explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
-        virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId);
+        virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId);
         virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
-                const String16& cameraId, const String16& physicalCameraId);
+                const std::string& cameraId, const std::string& physicalCameraId);
 
         // Torch API not implemented yet
-        virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
+        virtual binder::Status onTorchStatusChanged(int32_t, const std::string&) {
             return binder::Status::ok();
         }
-        virtual binder::Status onTorchStrengthLevelChanged(const String16&, int32_t) {
+        virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t) {
             return binder::Status::ok();
         }
 
         virtual binder::Status onCameraAccessPrioritiesChanged();
-        virtual binder::Status onCameraOpened(const String16&, const String16&) {
+        virtual binder::Status onCameraOpened(const std::string&, const std::string&) {
             return binder::Status::ok();
         }
-        virtual binder::Status onCameraClosed(const String16&) {
+        virtual binder::Status onCameraClosed(const std::string&) {
             return binder::Status::ok();
         }
 
@@ -203,20 +203,20 @@
 
     sp<hardware::ICameraService> getCameraServiceLocked();
     void onCameraAccessPrioritiesChanged();
-    void onStatusChanged(int32_t status, const String8& cameraId);
-    void onStatusChangedLocked(int32_t status, const String8& cameraId);
-    void onStatusChanged(int32_t status, const String8& cameraId, const String8& physicalCameraId);
-    void onStatusChangedLocked(int32_t status, const String8& cameraId,
-           const String8& physicalCameraId);
+    void onStatusChanged(int32_t status, const std::string& cameraId);
+    void onStatusChangedLocked(int32_t status, const std::string& cameraId);
+    void onStatusChanged(int32_t status, const std::string& cameraId, const std::string& physicalCameraId);
+    void onStatusChangedLocked(int32_t status, const std::string& cameraId,
+           const std::string& physicalCameraId);
     // Utils for status
     static bool validStatus(int32_t status);
     static bool isStatusAvailable(int32_t status);
-    bool supportsCamera2ApiLocked(const String8 &cameraId);
+    bool supportsCamera2ApiLocked(const std::string &cameraId);
 
     // The sort logic must match the logic in
     // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
     struct CameraIdComparator {
-        bool operator()(const String8& a, const String8& b) const {
+        bool operator()(const std::string& a, const std::string& b) const {
             uint32_t aUint = 0, bUint = 0;
             bool aIsUint = base::ParseUint(a.c_str(), &aUint);
             bool bIsUint = base::ParseUint(b.c_str(), &bUint);
@@ -238,22 +238,22 @@
       private:
         int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
         mutable std::mutex mLock;
-        std::set<String8> unavailablePhysicalIds;
+        std::set<std::string> unavailablePhysicalIds;
       public:
         const bool supportsHAL3 = false;
         StatusAndHAL3Support(int32_t st, bool HAL3support):
                 status(st), supportsHAL3(HAL3support) { };
         StatusAndHAL3Support() = default;
 
-        bool addUnavailablePhysicalId(const String8& physicalCameraId);
-        bool removeUnavailablePhysicalId(const String8& physicalCameraId);
+        bool addUnavailablePhysicalId(const std::string& physicalCameraId);
+        bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
         int32_t getStatus();
         void updateStatus(int32_t newStatus);
-        std::set<String8> getUnavailablePhysicalIds();
+        std::set<std::string> getUnavailablePhysicalIds();
     };
 
     // Map camera_id -> status
-    std::map<String8, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
+    std::map<std::string, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
 
     // For the singleton instance
     static Mutex sLock;
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index 4995dc4..365ac5c 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -142,7 +142,7 @@
         if (ids[i] == '\0') {
             if (start != i) {
                 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
-                mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().string());
+                mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().c_str());
             }
             start = i+1;
         }
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 1af5637..bb963ab 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -43,6 +43,7 @@
 #include <camera/camera2/OutputConfiguration.h>
 #include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/SubmitInfo.h>
+#include <camera/StringUtils.h>
 
 #include <gui/BufferItemConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
@@ -68,15 +69,15 @@
 
 // Stub listener implementation
 class TestCameraServiceListener : public hardware::BnCameraServiceListener {
-    std::map<String16, int32_t> mCameraTorchStatuses;
-    std::map<String16, int32_t> mCameraStatuses;
+    std::map<std::string, int32_t> mCameraTorchStatuses;
+    std::map<std::string, int32_t> mCameraStatuses;
     mutable Mutex mLock;
     mutable Condition mCondition;
     mutable Condition mTorchCondition;
 public:
     virtual ~TestCameraServiceListener() {};
 
-    virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId) {
+    virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId) override {
         Mutex::Autolock l(mLock);
         mCameraStatuses[cameraId] = status;
         mCondition.broadcast();
@@ -84,36 +85,37 @@
     };
 
     virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
-            const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+            const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) override {
         // No op
         return binder::Status::ok();
     };
 
-    virtual binder::Status onTorchStatusChanged(int32_t status, const String16& cameraId) {
+    virtual binder::Status onTorchStatusChanged(int32_t status,
+            const std::string& cameraId) override {
         Mutex::Autolock l(mLock);
         mCameraTorchStatuses[cameraId] = status;
         mTorchCondition.broadcast();
         return binder::Status::ok();
     };
 
-    virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
-            int32_t /*torchStrength*/) {
+    virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
+            int32_t /*torchStrength*/) override {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraAccessPrioritiesChanged() {
+    virtual binder::Status onCameraAccessPrioritiesChanged() override {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
-            const String16& /*clientPackageName*/) {
+    virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+            const std::string& /*clientPackageName*/) {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+    virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) override {
         // No op
         return binder::Status::ok();
     }
@@ -136,7 +138,7 @@
     bool waitForTorchState(int32_t status, int32_t cameraId) const {
         Mutex::Autolock l(mLock);
 
-        const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+        const auto& iter = mCameraTorchStatuses.find(std::to_string(cameraId));
         if (iter != mCameraTorchStatuses.end() && iter->second == status) {
             return true;
         }
@@ -147,7 +149,7 @@
                 return false;
             }
             const auto& iter =
-                    mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+                    mCameraTorchStatuses.find(std::to_string(cameraId));
             foundStatus = (iter != mCameraTorchStatuses.end() && iter->second == status);
         }
         return true;
@@ -155,14 +157,14 @@
 
     int32_t getTorchStatus(int32_t cameraId) const {
         Mutex::Autolock l(mLock);
-        const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+        const auto& iter = mCameraTorchStatuses.find(std::to_string(cameraId));
         if (iter == mCameraTorchStatuses.end()) {
             return hardware::ICameraServiceListener::TORCH_STATUS_UNKNOWN;
         }
         return iter->second;
     };
 
-    int32_t getStatus(const String16& cameraId) const {
+    int32_t getStatus(const std::string& cameraId) const {
         Mutex::Autolock l(mLock);
         const auto& iter = mCameraStatuses.find(cameraId);
         if (iter == mCameraStatuses.end()) {
@@ -352,11 +354,11 @@
 
     EXPECT_EQ(numCameras, static_cast<const int>(statuses.size()));
     for (const auto &it : statuses) {
-        listener->onStatusChanged(it.status, String16(it.cameraId));
+        listener->onStatusChanged(it.status, it.cameraId);
     }
 
     for (int32_t i = 0; i < numCameras; i++) {
-        String16 cameraId = String16(String8::format("%d", i));
+        std::string cameraId = std::to_string(i);
         bool isSupported = false;
         res = service->supportsCameraApi(cameraId,
                 hardware::ICameraService::API_VERSION_2, &isSupported);
@@ -384,7 +386,7 @@
         // Check connect binder calls
         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
         sp<hardware::camera2::ICameraDeviceUser> device;
-        res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
+        res = service->connectDevice(callbacks, cameraId, "meeeeeeeee!",
                 {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
                 /*overrideToPortrait*/false, /*out*/&device);
@@ -423,12 +425,12 @@
     sp<TestCameraServiceListener> serviceListener;
 
     std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>
-            openNewDevice(const String16& deviceId) {
+            openNewDevice(const std::string& deviceId) {
         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
         sp<hardware::camera2::ICameraDeviceUser> device;
         {
             SCOPED_TRACE("openNewDevice");
-            binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
+            binder::Status res = service->connectDevice(callbacks, deviceId, "meeeeeeeee!",
                     {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
                     /*targetSdkVersion*/__ANDROID_API_FUTURE__,
                     /*overrideToPortrait*/false, /*out*/&device);
@@ -464,7 +466,7 @@
         std::vector<hardware::CameraStatus> statuses;
         service->addListener(serviceListener, &statuses);
         for (const auto &it : statuses) {
-            serviceListener->onStatusChanged(it.status, String16(it.cameraId));
+            serviceListener->onStatusChanged(it.status, it.cameraId);
         }
         service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
                 &numCameras);
@@ -484,9 +486,8 @@
     ASSERT_NOT_NULL(service);
     EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras));
     for (int32_t i = 0; i < numCameras; i++) {
-        String8 cameraId8 = String8::format("%d", i);
+        std::string cameraId = std::to_string(i);
         // Make sure we're available, or skip device tests otherwise
-        String16 cameraId(cameraId8);
         int32_t s = serviceListener->getStatus(cameraId);
         EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s);
         if (s != hardware::ICameraServiceListener::STATUS_PRESENT) {
@@ -513,7 +514,7 @@
 
         sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
 
-        String16 noPhysicalId;
+        std::string noPhysicalId;
         OutputConfiguration output(gbProducer, /*rotation*/0, noPhysicalId);
 
         // Can we configure?
@@ -550,7 +551,7 @@
         EXPECT_TRUE(res.isOk()) << res;
 
         hardware::camera2::CaptureRequest request;
-        request.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+        request.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
         request.mSurfaceList.add(surface);
         request.mIsReprocess = false;
         int64_t lastFrameNumber = 0;
@@ -577,7 +578,7 @@
                 /*out*/&requestTemplate);
         EXPECT_TRUE(res.isOk()) << res;
         hardware::camera2::CaptureRequest request2;
-        request2.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+        request2.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
         request2.mSurfaceList.add(surface);
         request2.mIsReprocess = false;
         callbacks->clearStatus();
@@ -610,10 +611,10 @@
         EXPECT_TRUE(res.isOk()) << res;
         android::hardware::camera2::CaptureRequest request3;
         android::hardware::camera2::CaptureRequest request4;
-        request3.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+        request3.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
         request3.mSurfaceList.add(surface);
         request3.mIsReprocess = false;
-        request4.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate2});
+        request4.mPhysicalCameraSettings.push_back({cameraId, requestTemplate2});
         request4.mSurfaceList.add(surface);
         request4.mIsReprocess = false;
         std::vector<hardware::camera2::CaptureRequest> requestList;
diff --git a/camera/tests/CameraCharacteristicsPermission.cpp b/camera/tests/CameraCharacteristicsPermission.cpp
index f2fa48c..1de7cb4 100644
--- a/camera/tests/CameraCharacteristicsPermission.cpp
+++ b/camera/tests/CameraCharacteristicsPermission.cpp
@@ -62,7 +62,7 @@
 TEST_F(CameraCharacteristicsPermission, TestCameraPermission) {
     for (int32_t cameraId = 0; cameraId < numCameras; cameraId++) {
 
-        String16 cameraIdStr = String16(String8::format("%d", cameraId));
+        std::string cameraIdStr = std::to_string(cameraId);
         bool isSupported = false;
         auto rc = mCameraService->supportsCameraApi(cameraIdStr,
                 hardware::ICameraService::API_VERSION_2, &isSupported);
diff --git a/camera/tests/CameraZSLTests.cpp b/camera/tests/CameraZSLTests.cpp
index 6423709..3ae7659 100644
--- a/camera/tests/CameraZSLTests.cpp
+++ b/camera/tests/CameraZSLTests.cpp
@@ -27,6 +27,7 @@
 #include <camera/CameraParameters.h>
 #include <camera/CameraMetadata.h>
 #include <camera/Camera.h>
+#include <camera/StringUtils.h>
 #include <android/hardware/ICameraService.h>
 
 using namespace android;
@@ -169,7 +170,7 @@
         sp<SurfaceControl> surfaceControl;
         sp<ICamera> cameraDevice;
 
-        String16 cameraIdStr = String16(String8::format("%d", cameraId));
+        std::string cameraIdStr = std::to_string(cameraId);
         bool isSupported = false;
         rc = mCameraService->supportsCameraApi(cameraIdStr,
                 hardware::ICameraService::API_VERSION_1, &isSupported);
@@ -208,7 +209,7 @@
         }
 
         rc = mCameraService->connect(this, cameraId,
-                String16("ZSLTest"), hardware::ICameraService::USE_CALLING_UID,
+                "ZSLTest", hardware::ICameraService::USE_CALLING_UID,
                 hardware::ICameraService::USE_CALLING_PID,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
                 /*overrideToPortrait*/false, /*forceSlowJpegMode*/false, &cameraDevice);
diff --git a/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp b/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
index 45b3526..07efc20 100644
--- a/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <fuzzer/FuzzedDataProvider.h>
 #include <utils/String16.h>
+#include <camera/StringUtils.h>
 
 using namespace std;
 using namespace android;
@@ -77,7 +78,7 @@
         } else {
             params = mFDP->ConsumeRandomLengthString();
         }
-        *obj = new type(String8(params.c_str()));
+        *obj = new type(toString8(params));
     }
 }
 
diff --git a/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp b/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
index 2f2ad77..c9bb20c 100644
--- a/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
@@ -17,6 +17,7 @@
 #include <CameraSessionStats.h>
 #include <binder/Parcel.h>
 #include <fuzzer/FuzzedDataProvider.h>
+#include <camera/StringUtils.h>
 #include "camera2common.h"
 
 using namespace std;
@@ -100,10 +101,9 @@
     if (fdp.ConsumeBool()) {
         cameraSessionStats = new CameraSessionStats();
     } else {
-        string camId = fdp.ConsumeRandomLengthString();
-        String16 cameraId(camId.c_str());
+        string cameraId = fdp.ConsumeRandomLengthString();
         if (fdp.ConsumeBool()) {
-            parcelCamSessionStats.writeString16(cameraId);
+            parcelCamSessionStats.writeString16(toString16(cameraId));
         }
         int32_t facing = fdp.ConsumeIntegral<int32_t>();
         if (fdp.ConsumeBool()) {
@@ -113,10 +113,9 @@
         if (fdp.ConsumeBool()) {
             parcelCamSessionStats.writeInt32(newCameraState);
         }
-        string name = fdp.ConsumeRandomLengthString();
-        String16 clientName(name.c_str());
+        string clientName = fdp.ConsumeRandomLengthString();
         if (fdp.ConsumeBool()) {
-            parcelCamSessionStats.writeString16(clientName);
+            parcelCamSessionStats.writeString16(toString16(clientName));
         }
         int32_t apiLevel = fdp.ConsumeIntegral<int32_t>();
         if (fdp.ConsumeBool()) {
diff --git a/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp b/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
index 06215a5..494ec1b 100644
--- a/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <CameraMetadata.h>
+#include <camera/StringUtils.h>
 #include <camera2/CaptureRequest.h>
 #include <fuzzer/FuzzedDataProvider.h>
 #include <gui/Surface.h>
@@ -45,7 +46,7 @@
     for (size_t idx = 0; idx < physicalCameraSettingsSize; ++idx) {
         string id = fdp.ConsumeRandomLengthString();
         if (fdp.ConsumeBool()) {
-            parcelCamCaptureReq.writeString16(String16(id.c_str()));
+            parcelCamCaptureReq.writeString16(toString16(id));
         }
         CameraMetadata cameraMetadata;
         if (fdp.ConsumeBool()) {
diff --git a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
index 51ac4e8..2fe9a94 100644
--- a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
@@ -38,8 +38,7 @@
         outputConfiguration = new OutputConfiguration();
     } else {
         int32_t rotation = fdp.ConsumeIntegral<int32_t>();
-        string phyCameraId = fdp.ConsumeRandomLengthString();
-        String16 physicalCameraId(phyCameraId.c_str());
+        string physicalCameraId = fdp.ConsumeRandomLengthString();
         int32_t surfaceSetID = fdp.ConsumeIntegral<int32_t>();
         bool isShared = fdp.ConsumeBool();
 
diff --git a/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp b/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
index b2de95d..7cd0e59 100644
--- a/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
@@ -65,8 +65,7 @@
             surface.clear();
         }
         int32_t rotation = fdp.ConsumeIntegral<int32_t>();
-        string phyCameraId = fdp.ConsumeRandomLengthString();
-        String16 physicalCameraId(phyCameraId.c_str());
+        string physicalCameraId = fdp.ConsumeRandomLengthString();
         int32_t surfaceSetID = fdp.ConsumeIntegral<int32_t>();
         bool isShared = fdp.ConsumeBool();
         outputConfiguration =
diff --git a/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp b/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
index 1396431..dd857d4 100644
--- a/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
@@ -32,8 +32,7 @@
     if (fdp.ConsumeBool()) {
         physicalCaptureResultInfo = new PhysicalCaptureResultInfo();
     } else {
-        string camId = fdp.ConsumeRandomLengthString();
-        String16 cameraId(camId.c_str());
+        string cameraId = fdp.ConsumeRandomLengthString();
         CameraMetadata cameraMetadata = CameraMetadata();
         physicalCaptureResultInfo = new PhysicalCaptureResultInfo(cameraId, cameraMetadata);
     }
@@ -47,9 +46,7 @@
     }
     if (fdp.ConsumeBool()) {
         captureResult->mResultExtras = CaptureResultExtras();
-        string errCamId = fdp.ConsumeRandomLengthString();
-        String16 errCameraId(errCamId.c_str());
-        captureResult->mResultExtras.errorPhysicalCameraId = errCameraId;
+        captureResult->mResultExtras.errorPhysicalCameraId = fdp.ConsumeRandomLengthString();
         captureResult->mResultExtras.isValid();
         invokeReadWriteNullParcel<CaptureResultExtras>(&(captureResult->mResultExtras));
     }
diff --git a/camera/tests/fuzzer/camera_fuzzer.cpp b/camera/tests/fuzzer/camera_fuzzer.cpp
index f9ef98e..d09a6dd 100644
--- a/camera/tests/fuzzer/camera_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_fuzzer.cpp
@@ -149,7 +149,7 @@
     sp<IBinder> binder = sm->getService(String16("media.camera"));
     mCameraService = interface_cast<ICameraService>(binder);
     mCameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
-                            String16("CAMERAFUZZ"), hardware::ICameraService::USE_CALLING_UID,
+                            "CAMERAFUZZ", hardware::ICameraService::USE_CALLING_UID,
                             hardware::ICameraService::USE_CALLING_PID,
                             /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
                             /*overrideToPortrait*/false, /*forceSlowJpegMode*/false, &cameraDevice);
@@ -294,18 +294,15 @@
         cameraStatus = new CameraStatus();
     } else {
         string cid = mFDP->ConsumeRandomLengthString();
-        String8 id(cid.c_str());
         int32_t status = mFDP->ConsumeIntegral<int32_t>();
         size_t unavailSubIdsSize = mFDP->ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
-        vector<String8> unavailSubIds;
+        vector<std::string> unavailSubIds;
         for (size_t idx = 0; idx < unavailSubIdsSize; ++idx) {
             string subId = mFDP->ConsumeRandomLengthString();
-            String8 unavailSubId(subId.c_str());
-            unavailSubIds.push_back(unavailSubId);
+            unavailSubIds.push_back(subId);
         }
-        string clientPkg = mFDP->ConsumeRandomLengthString();
-        String8 clientPackage(clientPkg.c_str());
-        cameraStatus = new CameraStatus(id, status, unavailSubIds, clientPackage);
+        string clientPackage = mFDP->ConsumeRandomLengthString();
+        cameraStatus = new CameraStatus(cid, status, unavailSubIds, clientPackage);
     }
 
     invokeReadWriteParcel<CameraStatus>(cameraStatus);
diff --git a/cmds/screenrecord/TextRenderer.cpp b/cmds/screenrecord/TextRenderer.cpp
index 01f73e0..cd27bb5 100644
--- a/cmds/screenrecord/TextRenderer.cpp
+++ b/cmds/screenrecord/TextRenderer.cpp
@@ -153,7 +153,7 @@
     // just convert to char* -- but String8 doesn't document what it does
     // with values outside 0-255.  So just convert to char* and use strlen()
     // to see what we get.
-    const char* str = str8.string();
+    const char* str = str8.c_str();
     return computeScaledStringWidth(str, strlen(str));
 }
 
@@ -180,13 +180,13 @@
 
 void TextRenderer::drawString(const Program& program, const float* texMatrix,
         float x, float y, const String8& str8) const {
-    ALOGV("drawString %.3f,%.3f '%s' (scale=%.3f)", x, y, str8.string(),mScale);
+    ALOGV("drawString %.3f,%.3f '%s' (scale=%.3f)", x, y, str8.c_str(),mScale);
     initOnce();
 
     // We want to draw the entire string with a single GLES call.  We
     // generate two arrays, one with screen coordinates, one with texture
     // coordinates.  Need two triangles per character.
-    const char* str = str8.string();
+    const char* str = str8.c_str();
     size_t len = strlen(str);       // again, unsure about String8 handling
 
     const size_t quadCoords =
@@ -252,7 +252,7 @@
 
 float TextRenderer::drawWrappedString(const Program& texRender,
         float xpos, float ypos, const String8& str) {
-    ALOGV("drawWrappedString %.3f,%.3f '%s'", xpos, ypos, str.string());
+    ALOGV("drawWrappedString %.3f,%.3f '%s'", xpos, ypos, str.c_str());
     initOnce();
 
     if (mScreenWidth == 0 || mScreenHeight == 0) {
@@ -283,7 +283,7 @@
     } else {
         // We need to break the string into pieces, ideally at whitespace
         // boundaries.
-        char* mangle = strdup(str.string());
+        char* mangle = strdup(str.c_str());
         char* start = mangle;
         while (start != NULL) {
             float xposAdj = (start == mangle) ? xpos : xpos + indentWidth;
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index f53fc0a..55bfbd8 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -1096,7 +1096,7 @@
             "-a",
             "android.intent.action.MEDIA_SCANNER_SCAN_FILE",
             "-d",
-            fileUrl.string(),
+            fileUrl.c_str(),
             NULL
     };
     if (gVerbose) {
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 2edc0fe..989b127 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -106,6 +106,12 @@
     decodeTimesUs->sort(CompareIncreasing);
 
     size_t n = decodeTimesUs->size();
+
+    if (n == 0) {
+        printf("no decode histogram to display\n");
+        return;
+    }
+
     int64_t minUs = decodeTimesUs->itemAt(0);
     int64_t maxUs = decodeTimesUs->itemAt(n - 1);
 
@@ -149,7 +155,7 @@
 }
 
 static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
-    FILE *out = fopen(filename.string(), "wb");
+    FILE *out = fopen(filename.c_str(), "wb");
 
     CHECK_EQ((status_t)OK, source->start());
 
@@ -532,9 +538,9 @@
         Vector<sp<MediaSource> > &sources, bool syncInfoPresent) {
 #if 0
     sp<MPEG4Writer> writer =
-        new MPEG4Writer(gWriteMP4Filename.string());
+        new MPEG4Writer(gWriteMP4Filename.c_str());
 #else
-    int fd = open(gWriteMP4Filename.string(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+    int fd = open(gWriteMP4Filename.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
     if (fd < 0) {
         fprintf(stderr, "couldn't open file");
         return;
@@ -828,7 +834,7 @@
             case 'd':
             {
                 dumpStream = true;
-                dumpStreamFilename.setTo(optarg);
+                dumpStreamFilename = optarg;
                 break;
             }
 
@@ -836,13 +842,13 @@
             {
                 dumpPCMStream = true;
                 audioOnly = true;
-                dumpStreamFilename.setTo(optarg);
+                dumpStreamFilename = optarg;
                 break;
             }
 
             case 'N':
             {
-                gComponentNameOverride.setTo(optarg);
+                gComponentNameOverride = optarg;
                 break;
             }
 
@@ -880,7 +886,7 @@
             case 'w':
             {
                 gWriteMP4 = true;
-                gWriteMP4Filename.setTo(optarg);
+                gWriteMP4Filename = optarg;
                 break;
             }
 
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index 584c6a6..6294f50 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -50,7 +50,7 @@
     for (size_t i = 0; i < mMimeTypeVector.size(); i++) {
         const String8 item = mMimeTypeVector.itemAt(i);
 
-        if (!strcasecmp(item.string(), mimeType.string())) {
+        if (!strcasecmp(item.c_str(), mimeType.c_str())) {
             return true;
         }
     }
@@ -61,7 +61,7 @@
     for (size_t i = 0; i < mFileSuffixVector.size(); i++) {
         const String8 item = mFileSuffixVector.itemAt(i);
 
-        if (!strcasecmp(item.string(), fileType.string())) {
+        if (!strcasecmp(item.c_str(), fileType.c_str())) {
             return true;
         }
     }
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index a6d33b0..1b49be1 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -303,8 +303,8 @@
         const String8 value = drmInforequest->get(key);
         if (key == String8("FileDescriptorKey")) {
             int fd = -1;
-            if (sscanf(value.string(), "FileDescriptor[%d]", &fd) != 1) {
-                sscanf(value.string(), "%d", &fd);
+            if (sscanf(value.c_str(), "FileDescriptor[%d]", &fd) != 1) {
+                sscanf(value.c_str(), "%d", &fd);
             }
             data.writeFileDescriptor(fd);
         } else {
@@ -1330,7 +1330,7 @@
         const String8 mime = data.readString8();
 
         sp<DecryptHandle> handle
-            = openDecryptSession(uniqueId, fd, offset, length, mime.string());
+            = openDecryptSession(uniqueId, fd, offset, length, mime.c_str());
 
         if (NULL != handle.get()) {
             writeDecryptHandleToParcelData(handle.get(), reply);
@@ -1349,7 +1349,7 @@
         const String8 uri = data.readString8();
         const String8 mime = data.readString8();
 
-        sp<DecryptHandle> handle = openDecryptSession(uniqueId, uri.string(), mime.string());
+        sp<DecryptHandle> handle = openDecryptSession(uniqueId, uri.c_str(), mime.c_str());
 
         if (NULL != handle.get()) {
             writeDecryptHandleToParcelData(handle.get(), reply);
diff --git a/drm/common/ReadWriteUtils.cpp b/drm/common/ReadWriteUtils.cpp
index 16b5b34..97c3716 100644
--- a/drm/common/ReadWriteUtils.cpp
+++ b/drm/common/ReadWriteUtils.cpp
@@ -34,7 +34,7 @@
 
 String8 ReadWriteUtils::readBytes(const String8& filePath) {
     FILE* file = NULL;
-    file = fopen(filePath.string(), "r");
+    file = fopen(filePath.c_str(), "r");
 
     String8 string("");
     if (NULL != file) {
@@ -56,7 +56,7 @@
 
 int ReadWriteUtils::readBytes(const String8& filePath, char** buffer) {
     FILE* file = NULL;
-    file = fopen(filePath.string(), "r");
+    file = fopen(filePath.c_str(), "r");
     off64_t length = 0;
 
     if (NULL != file) {
@@ -77,15 +77,15 @@
 
 void ReadWriteUtils::writeToFile(const String8& filePath, const String8& data) {
     FILE* file = NULL;
-    file = fopen(filePath.string(), "w+");
+    file = fopen(filePath.c_str(), "w+");
 
     if (NULL != file) {
         int fd = fileno(file);
 
         int size = data.size();
         if (FAILURE != ftruncate(fd, size)) {
-            if (size != write(fd, data.string(), size)) {
-                ALOGE("Failed to write the data to: %s", filePath.string());
+            if (size != write(fd, data.c_str(), size)) {
+                ALOGE("Failed to write the data to: %s", filePath.c_str());
             }
         }
         fclose(file);
@@ -94,14 +94,14 @@
 
 void ReadWriteUtils::appendToFile(const String8& filePath, const String8& data) {
     FILE* file = NULL;
-    file = fopen(filePath.string(), "a+");
+    file = fopen(filePath.c_str(), "a+");
 
     if (NULL != file) {
         int fd = fileno(file);
 
         int size = data.size();
-        if (size != write(fd, data.string(), size)) {
-            ALOGE("Failed to write the data to: %s", filePath.string());
+        if (size != write(fd, data.c_str(), size)) {
+            ALOGE("Failed to write the data to: %s", filePath.c_str());
         }
         fclose(file);
     }
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index c830c6e..98eba2a 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -373,7 +373,7 @@
         (void)args;
 #endif
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
diff --git a/drm/drmserver/PlugInManager.h b/drm/drmserver/PlugInManager.h
index 466844d..df40476 100644
--- a/drm/drmserver/PlugInManager.h
+++ b/drm/drmserver/PlugInManager.h
@@ -137,7 +137,7 @@
 
         PlugInContainer* pPlugInContainer = new PlugInContainer();
 
-        pPlugInContainer->hHandle = dlopen(rsPlugInPath.string(), RTLD_LAZY);
+        pPlugInContainer->hHandle = dlopen(rsPlugInPath.c_str(), RTLD_LAZY);
 
         if (NULL == pPlugInContainer->hHandle) {
             delete pPlugInContainer;
@@ -201,7 +201,7 @@
      */
     Vector<String8> getPlugInPathList(const String8& rsDirPath) {
         Vector<String8> fileList;
-        DIR* pDir = opendir(rsDirPath.string());
+        DIR* pDir = opendir(rsDirPath.c_str());
         struct dirent* pEntry;
 
         while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
diff --git a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
index 3b1566f..d47a9d9 100644
--- a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
+++ b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
@@ -128,7 +128,7 @@
     struct MimeGroup* pGroup;
     struct MimeTypeList* pMimeItem;
     int len;
-    pMimeType = mimeType.string();
+    pMimeType = mimeType.c_str();
     if (NULL != pMimeType) {
         if ((0 == strncmp(pMimeType, mime_group_audio, (sizeof mime_group_audio) - 1)) ||
             (0 == strncmp(pMimeType, mime_group_video, (sizeof mime_group_video) - 1))) {
@@ -159,7 +159,7 @@
             result = String8(mime_type_unsupported);
         }
         LOG_DEBUG("convertMimeType got mimetype %s, converted into mimetype %s",
-                pMimeType, result.string());
+                pMimeType, result.c_str());
     }
     return result;
 }
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 769de0c..1d8c724 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -544,7 +544,7 @@
         String8 uriTag = String8(uri);
         uriTag.toLower();
 
-        if (0 == strncmp(uriTag.string(), fileTag, sizeof(fileTag) - 1)) {
+        if (0 == strncmp(uriTag.c_str(), fileTag, sizeof(fileTag) - 1)) {
             const char *filePath = strchr(uri + sizeof(fileTag) - 1, '/');
             if (NULL != filePath && onCanHandle(uniqueId, String8(filePath))) {
                 int fd = open(filePath, O_RDONLY);
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
index 0fa3478..44b4438 100644
--- a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -64,7 +64,7 @@
     String8 value("dummy_available_time");
     char* charValue = NULL;
     charValue = new char[value.length() + 1];
-    strncpy(charValue, value.string(), value.length());
+    strncpy(charValue, value.c_str(), value.length());
     charValue[value.length()] = '\0';
 
     //Just add dummy available time for verification
@@ -95,7 +95,7 @@
             const int bufferSize = licenseString.size();
             char* data = NULL;
             data = new char[bufferSize];
-            memcpy(data, licenseString.string(), bufferSize);
+            memcpy(data, licenseString.c_str(), bufferSize);
             const DrmBuffer* buffer = new DrmBuffer(data, bufferSize);
             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
                     DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, buffer, drmInfo->getMimeType());
@@ -150,7 +150,7 @@
         int length = dataString.length();
         char* data = NULL;
         data = new char[length];
-        memcpy(data, dataString.string(), length);
+        memcpy(data, dataString.c_str(), length);
         drmInfo = new DrmInfo(drmInfoRequest->getInfoType(),
             DrmBuffer(data, length), drmInfoRequest->getMimeType());
     }
@@ -158,7 +158,7 @@
 }
 
 bool DrmPassthruPlugIn::onCanHandle(int /*uniqueId*/, const String8& path) {
-    ALOGV("DrmPassthruPlugIn::canHandle: %s ", path.string());
+    ALOGV("DrmPassthruPlugIn::canHandle: %s ", path.c_str());
     String8 extension = path.getPathExtension();
     extension.toLower();
     return (String8(".passthru") == extension);
diff --git a/drm/libmediadrm/DrmHalAidl.cpp b/drm/libmediadrm/DrmHalAidl.cpp
index 5ec7337..9e30708 100644
--- a/drm/libmediadrm/DrmHalAidl.cpp
+++ b/drm/libmediadrm/DrmHalAidl.cpp
@@ -117,7 +117,7 @@
 }
 
 static std::string toStdString(const String8& string8) {
-    return std::string(string8.string());
+    return std::string(string8.c_str());
 }
 
 static std::vector<KeyValue> toKeyValueVector(const KeyedVector<String8, String8>& keyedVector) {
@@ -415,7 +415,7 @@
     *isSupported = false;
     Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
     SecurityLevel levelAidl = toAidlSecurityLevel(level);
-    std::string mimeTypeStr = mimeType.string();
+    std::string mimeTypeStr = mimeType.c_str();
 
     for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
         CryptoSchemes schemes{};
diff --git a/drm/libmediadrm/DrmHalHidl.cpp b/drm/libmediadrm/DrmHalHidl.cpp
index 00ea004..9d2638d 100644
--- a/drm/libmediadrm/DrmHalHidl.cpp
+++ b/drm/libmediadrm/DrmHalHidl.cpp
@@ -121,7 +121,7 @@
 }
 
 static hidl_string toHidlString(const String8& string) {
-    return hidl_string(string.string());
+    return hidl_string(string.c_str());
 }
 
 static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
@@ -353,7 +353,7 @@
 
     sp<IDrmPlugin> plugin;
     Return<void> hResult = factory->createPlugin(
-            uuid, appPackageName.string(), [&](Status status, const sp<IDrmPlugin>& hPlugin) {
+            uuid, appPackageName.c_str(), [&](Status status, const sp<IDrmPlugin>& hPlugin) {
                 if (status != Status::OK) {
                     DrmUtils::LOG2BE(uuid, "Failed to make drm plugin: %d", status);
                     return;
@@ -517,7 +517,7 @@
             return DrmStatus(OK);
         }
         // isCryptoSchemeSupported(uuid, mimeType)
-        auto hResult = factory->isContentTypeSupported(mimeType.string());
+        auto hResult = factory->isContentTypeSupported(mimeType.c_str());
         if (!hResult.isOk()) {
             return DrmStatus(DEAD_OBJECT);
         }
@@ -531,7 +531,7 @@
     if (factoryV1_2 == NULL) {
         return DrmStatus(ERROR_UNSUPPORTED);
     } else {
-        auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
+        auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.c_str(),
                                                                 toHidlSecurityLevel(level));
         if (!hResult.isOk()) {
             return DrmStatus(DEAD_OBJECT);
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
index ce4d730..7d600cb 100644
--- a/drm/libmediadrm/DrmMetricsLogger.cpp
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -151,7 +151,7 @@
     if (status == OK) {
         String8 version8;
         if (getPropertyString(String8("version"), version8) == OK) {
-            mVersion = version8.string();
+            mVersion = version8.c_str();
         }
         reportMediaDrmCreated();
     } else {
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 301538f..989a597 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));
     }
 }
 
@@ -129,7 +172,7 @@
         const std::shared_ptr<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
     uid_t uid = AIBinder_getCallingUid();
     ALOGV("addSession(pid %d, uid %d, drm %p, sessionId %s)", pid, uid, drm.get(),
-            GetSessionIdString(sessionId).string());
+            GetSessionIdString(sessionId).c_str());
 
     Mutex::Autolock lock(mLock);
     if (mService == NULL) {
@@ -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++};
@@ -145,7 +188,7 @@
 }
 
 void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
-    ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
+    ALOGV("useSession(%s)", GetSessionIdString(sessionId).c_str());
 
     Mutex::Autolock lock(mLock);
     auto it = mSessionMap.find(toStdVec(sessionId));
@@ -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};
@@ -161,7 +205,7 @@
 }
 
 void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
-    ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
+    ALOGV("removeSession(%s)", GetSessionIdString(sessionId).c_str());
 
     Mutex::Autolock lock(mLock);
     auto it = mSessionMap.find(toStdVec(sessionId));
@@ -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/SharedLibrary.cpp b/drm/libmediadrm/SharedLibrary.cpp
index b2d635d..97d5653 100644
--- a/drm/libmediadrm/SharedLibrary.cpp
+++ b/drm/libmediadrm/SharedLibrary.cpp
@@ -25,7 +25,7 @@
 namespace android {
 
     SharedLibrary::SharedLibrary(const String8 &path) {
-        mLibHandle = dlopen(path.string(), RTLD_NOW);
+        mLibHandle = dlopen(path.c_str(), RTLD_NOW);
     }
 
     SharedLibrary::~SharedLibrary() {
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/drm/libmediadrmrkp/Android.bp b/drm/libmediadrmrkp/Android.bp
new file mode 100644
index 0000000..f13eb62
--- /dev/null
+++ b/drm/libmediadrmrkp/Android.bp
@@ -0,0 +1,53 @@
+cc_library {
+    name: "libmediadrmrkp",
+    vendor_available: true,
+    srcs: [
+        "src/**/*.cpp",
+    ],
+    export_include_dirs: [
+        "include"
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcrypto",
+        "liblog",
+    ],
+    static_libs: [
+        "android.hardware.common-V2-ndk",
+        "android.hardware.drm-V1-ndk",
+        "android.hardware.security.rkp-V3-ndk",
+        "libbase",
+        "libcppbor_external",
+    ],
+    defaults: [
+        "keymint_use_latest_hal_aidl_ndk_shared",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
+
+cc_binary {
+    name: "test_libmediadrmrkp",
+    srcs: [
+        "test/*",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+    ],
+    static_libs: [
+        "android.hardware.common-V2-ndk",
+        "android.hardware.drm-V1-ndk",
+        "android.hardware.security.rkp-V3-ndk",
+        "libbase",
+        "libcppbor_external",
+        "libmediadrmrkp",
+    ],
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
new file mode 100644
index 0000000..f046785
--- /dev/null
+++ b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
@@ -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.
+ */
+
+#ifndef DRM_RKP_COMPONENT_H_
+#define DRM_RKP_COMPONENT_H_
+
+#include <aidl/android/hardware/drm/IDrmPlugin.h>
+#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
+#include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
+#include <cppbor.h>
+
+namespace android::mediadrm {
+
+using ::aidl::android::hardware::drm::IDrmPlugin;
+using ::aidl::android::hardware::security::keymint::BnRemotelyProvisionedComponent;
+using ::aidl::android::hardware::security::keymint::DeviceInfo;
+using ::aidl::android::hardware::security::keymint::MacedPublicKey;
+using ::aidl::android::hardware::security::keymint::ProtectedData;
+using ::aidl::android::hardware::security::keymint::RpcHardwareInfo;
+using ::ndk::ScopedAStatus;
+
+class DrmRemotelyProvisionedComponent : public BnRemotelyProvisionedComponent {
+  public:
+    DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm, std::string drmVendor,
+                                    std::string drmDesc, std::vector<uint8_t> bcc);
+    ScopedAStatus getHardwareInfo(RpcHardwareInfo* info) override;
+
+    ScopedAStatus generateEcdsaP256KeyPair(bool testMode, MacedPublicKey* macedPublicKey,
+                                           std::vector<uint8_t>* privateKeyHandle) override;
+
+    ScopedAStatus generateCertificateRequest(bool testMode,
+                                             const std::vector<MacedPublicKey>& keysToSign,
+                                             const std::vector<uint8_t>& endpointEncCertChain,
+                                             const std::vector<uint8_t>& challenge,
+                                             DeviceInfo* deviceInfo, ProtectedData* protectedData,
+                                             std::vector<uint8_t>* keysToSignMac) override;
+
+    ScopedAStatus generateCertificateRequestV2(const std::vector<MacedPublicKey>& keysToSign,
+                                               const std::vector<uint8_t>& challenge,
+                                               std::vector<uint8_t>* csr) override;
+
+  private:
+    ScopedAStatus getVerifiedDeviceInfo(cppbor::Map& deviceInfoMap);
+    ScopedAStatus getDeviceInfo(std::vector<uint8_t>* deviceInfo);
+
+    std::shared_ptr<IDrmPlugin> mDrm;
+    std::string mDrmVendor;
+    std::string mDrmDesc;
+    std::vector<uint8_t> mBcc;
+};
+}  // namespace android::mediadrm
+
+#endif  // DRM_RKP_COMPONENT_H_
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/include/DrmRkpAdapter.h b/drm/libmediadrmrkp/include/DrmRkpAdapter.h
new file mode 100644
index 0000000..0554f6a
--- /dev/null
+++ b/drm/libmediadrmrkp/include/DrmRkpAdapter.h
@@ -0,0 +1,31 @@
+/*
+ * 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 DRM_RKP_ADAPTER_H_
+#define DRM_RKP_ADAPTER_H_
+
+#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
+#include <map>
+#include <string>
+
+namespace android::mediadrm {
+using IRemotelyProvisionedComponent =
+        ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>
+getDrmRemotelyProvisionedComponents();
+}  // namespace android::mediadrm
+
+#endif  // DRM_RKP_ADAPTER_H_
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
new file mode 100644
index 0000000..440be79
--- /dev/null
+++ b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DrmRemotelyProvisionedComponent"
+#include "DrmRemotelyProvisionedComponent.h"
+
+#include <android-base/properties.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <log/log.h>
+#include <map>
+#include <string>
+
+namespace android::mediadrm {
+DrmRemotelyProvisionedComponent::DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm,
+                                                                 std::string drmVendor,
+                                                                 std::string drmDesc,
+                                                                 std::vector<uint8_t> bcc)
+    : mDrm(std::move(drm)),
+      mDrmVendor(std::move(drmVendor)),
+      mDrmDesc(std::move(drmDesc)),
+      mBcc(std::move(bcc)) {}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::getHardwareInfo(RpcHardwareInfo* info) {
+    info->versionNumber = 3;
+    info->rpcAuthorName = mDrmVendor;
+    info->supportedEekCurve = RpcHardwareInfo::CURVE_NONE;
+    info->supportedNumKeysInCsr = RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR;
+    info->uniqueId = mDrmDesc;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::generateEcdsaP256KeyPair(bool, MacedPublicKey*,
+                                                                        std::vector<uint8_t>*) {
+    return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+            IRemotelyProvisionedComponent::STATUS_REMOVED,
+            "generateEcdsaP256KeyPair not supported."));
+}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::generateCertificateRequest(
+        bool, const std::vector<MacedPublicKey>&, const std::vector<uint8_t>&,
+        const std::vector<uint8_t>&, DeviceInfo*, ProtectedData*, std::vector<uint8_t>*) {
+    return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+            IRemotelyProvisionedComponent::STATUS_REMOVED,
+            "generateCertificateRequest not supported."));
+}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::getVerifiedDeviceInfo(cppbor::Map& deviceInfoMap) {
+    std::vector<uint8_t> verifiedDeviceInfo;
+    auto status = mDrm->getPropertyByteArray("verifiedDeviceInfo", &verifiedDeviceInfo);
+    if (!status.isOk()) {
+        ALOGE("getPropertyByteArray verifiedDeviceInfo failed. Details: [%s].",
+              status.getDescription().c_str());
+        return status;
+    }
+
+    auto [parsed, _, err] = cppbor::parse(
+            reinterpret_cast<const uint8_t*>(verifiedDeviceInfo.data()), verifiedDeviceInfo.size());
+
+    if (!parsed || !parsed->asMap()) {
+        ALOGE("Failed to parse the verified device info cbor: %s", err.c_str());
+        return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IRemotelyProvisionedComponent::STATUS_FAILED,
+                "Failed to parse the verified device info cbor."));
+    }
+
+    const cppbor::Map* verifiedDeviceInfoMap = parsed->asMap();
+    for (size_t i = 0; i < verifiedDeviceInfoMap->size(); i++) {
+        auto& [keyItem, valueItem] = (*verifiedDeviceInfoMap)[i];
+        ALOGI("Found device info %s", keyItem->asTstr()->value().data());
+        if (valueItem != nullptr && valueItem->asTstr() != nullptr &&
+            valueItem->asTstr()->value().empty()) {
+            ALOGI("Value is empty. Skip");
+            continue;
+        }
+        deviceInfoMap.add(keyItem->clone(), valueItem->clone());
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::getDeviceInfo(std::vector<uint8_t>* deviceInfo) {
+    auto deviceInfoMap = cppbor::Map();
+    auto status = getVerifiedDeviceInfo(deviceInfoMap);
+    if (!status.isOk()) {
+        ALOGE("getVerifiedDeviceInfo failed. Details: [%s].", status.getDescription().c_str());
+        return status;
+    }
+    const std::map<std::string, std::string> keyToProp{{"brand", "ro.product.brand"},
+                                                       {"manufacturer", "ro.product.manufacturer"},
+                                                       {"model", "ro.product.model"},
+                                                       {"device", "ro.product.device"},
+                                                       {"product", "ro.product.name"}};
+    for (auto i : keyToProp) {
+        auto key = i.first;
+        auto prop = i.second;
+        const auto& val= deviceInfoMap.get(key);
+        if (val == nullptr || val->asTstr()->value().empty()) {
+            std::string propValue = android::base::GetProperty(prop, "");
+            if (propValue.empty()) {
+                ALOGE("Failed to get OS property %s", prop.c_str());
+                return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IRemotelyProvisionedComponent::STATUS_FAILED,
+                        "Failed to get OS property."));
+            }
+            deviceInfoMap.add(cppbor::Tstr(key), cppbor::Tstr(propValue));
+            ALOGI("use OS property %s: %s", prop.c_str(), propValue.c_str());
+        } else {
+            ALOGI("use verified key %s: %s", key.c_str(), val->asTstr()->value().data());
+        }
+    }
+    deviceInfoMap.canonicalize();
+    *deviceInfo = deviceInfoMap.encode();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus DrmRemotelyProvisionedComponent::generateCertificateRequestV2(
+        const std::vector<MacedPublicKey>&, const std::vector<uint8_t>& challenge,
+        std::vector<uint8_t>* out) {
+    // access csr input/output via setPropertyByteArray/getPropertyByteArray
+    auto status = mDrm->setPropertyByteArray("certificateSigningRequestChallenge", challenge);
+    if (!status.isOk()) {
+        ALOGE("setPropertyByteArray certificateSigningRequestChallenge failed. Details: [%s].",
+              status.getDescription().c_str());
+        return status;
+    }
+
+    std::vector<uint8_t> deviceInfo;
+    status = getDeviceInfo(&deviceInfo);
+    if (!status.isOk()) {
+        ALOGE("getDeviceInfo failed. Details: [%s].", status.getDescription().c_str());
+        return status;
+    }
+
+    status = mDrm->setPropertyByteArray("deviceInfo", deviceInfo);
+    if (!status.isOk()) {
+        ALOGE("setPropertyByteArray deviceInfo failed. Details: [%s].",
+              status.getDescription().c_str());
+        return status;
+    }
+
+    std::vector<uint8_t> deviceSignedCsrPayload;
+    status = mDrm->getPropertyByteArray("deviceSignedCsrPayload", &deviceSignedCsrPayload);
+    if (!status.isOk()) {
+        ALOGE("getPropertyByteArray deviceSignedCsrPayload failed. Details: [%s].",
+              status.getDescription().c_str());
+        return status;
+    }
+
+    // assemble AuthenticatedRequest (definition in IRemotelyProvisionedComponent.aidl)
+    *out = cppbor::Array()
+                   .add(1 /* version */)
+                   .add(cppbor::Map() /* UdsCerts */)
+                   .add(cppbor::EncodedItem(mBcc))
+                   .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)))
+                   .encode();
+    return ScopedAStatus::ok();
+}
+}  // namespace android::mediadrm
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
new file mode 100644
index 0000000..515d157
--- /dev/null
+++ b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DrmRkpAdapter"
+#include "DrmRkpAdapter.h"
+#include <aidl/android/hardware/drm/IDrmFactory.h>
+#include <aidl/android/hardware/drm/IDrmPlugin.h>
+#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
+#include <android/binder_manager.h>
+#include <log/log.h>
+#include "DrmRemotelyProvisionedComponent.h"
+
+namespace android::mediadrm {
+using CryptoSchemes = ::aidl::android::hardware::drm::CryptoSchemes;
+using IDrmFactory = ::aidl::android::hardware::drm::IDrmFactory;
+using IDrmPlugin = ::aidl::android::hardware::drm::IDrmPlugin;
+
+std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>
+getDrmRemotelyProvisionedComponents() {
+    std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>> comps;
+    AServiceManager_forEachDeclaredInstance(
+            IDrmFactory::descriptor, &comps, [](const char* instance, void* context) {
+                auto fullName = std::string(IDrmFactory::descriptor) + "/" + std::string(instance);
+                auto factory = IDrmFactory::fromBinder(
+                        ::ndk::SpAIBinder(AServiceManager_waitForService(fullName.c_str())));
+                if (factory == nullptr) {
+                    ALOGE("not found IDrmFactory. Instance name:[%s]", fullName.c_str());
+                    return;
+                }
+
+                ALOGI("found IDrmFactory. Instance name:[%s]", fullName.c_str());
+                CryptoSchemes schemes{};
+                auto status = factory->getSupportedCryptoSchemes(&schemes);
+                if (!status.isOk()) {
+                    ALOGE("getSupportedCryptoSchemes failed.Detail: [%s].",
+                          status.getDescription().c_str());
+                    return;
+                }
+
+                if (schemes.uuids.empty()) {
+                    ALOGW("IDrmFactory Instance [%s] has empty supported schemes",
+                          fullName.c_str());
+                    return;
+                }
+
+                std::shared_ptr<IDrmPlugin> mDrm;
+                status = factory->createDrmPlugin(schemes.uuids[0], "DrmRkpAdapter", &mDrm);
+                if (!status.isOk()) {
+                    ALOGE("createDrmPlugin failed.Detail: [%s].", status.getDescription().c_str());
+                    return;
+                }
+
+                std::string drmVendor;
+                status = mDrm->getPropertyString("vendor", &drmVendor);
+                if (!status.isOk()) {
+                    ALOGE("mDrm->getPropertyString(\"vendor\") failed.Detail: [%s].",
+                          status.getDescription().c_str());
+                    return;
+                }
+
+                std::string drmDesc;
+                status = mDrm->getPropertyString("description", &drmDesc);
+                if (!status.isOk()) {
+                    ALOGE("mDrm->getPropertyString(\"description\") failed.Detail: [%s].",
+                          status.getDescription().c_str());
+                    return;
+                }
+
+                std::vector<uint8_t> bcc;
+                status = mDrm->getPropertyByteArray("bootCertificateChain", &bcc);
+                if (!status.isOk()) {
+                    ALOGE("mDrm->getPropertyByteArray(\"bootCertificateChain\") failed."
+                          "Detail: [%s].",
+                          status.getDescription().c_str());
+                    return;
+                }
+
+                std::string compName(instance);
+                auto comps = static_cast<
+                        std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>*>(
+                        context);
+                (*comps)[compName] = ::ndk::SharedRefBase::make<DrmRemotelyProvisionedComponent>(
+                        mDrm, drmVendor, drmDesc, bcc);
+            });
+    return comps;
+}
+}  // namespace android::mediadrm
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/test/test_main.cpp b/drm/libmediadrmrkp/test/test_main.cpp
new file mode 100644
index 0000000..d23dc3b
--- /dev/null
+++ b/drm/libmediadrmrkp/test/test_main.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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 "DrmRkpAdapter.h"
+
+using ::aidl::android::hardware::security::keymint::MacedPublicKey;
+int main() {
+    std::vector<uint8_t> challenge(16);
+    std::vector<uint8_t> csr;
+    std::vector<MacedPublicKey> k;
+    for (auto const& e : android::mediadrm::getDrmRemotelyProvisionedComponents()) {
+        auto status = e.second.get()->generateCertificateRequestV2(k, challenge, &csr);
+        printf("%s calls generateCertificateRequestV2() gets status.isOk():%d\n",
+               e.first.c_str(), status.isOk());
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index af7c367..37051d5 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -157,7 +157,7 @@
 }
 
 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
-    ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string());
+    ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).c_str());
     std::shared_ptr<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session.get() == nullptr) {
@@ -171,7 +171,7 @@
 status_t ClearKeyCasPlugin::setSessionPrivateData(
         const CasSessionId &sessionId, const CasData & /*data*/) {
     ALOGV("setSessionPrivateData: sessionId=%s",
-            sessionIdToString(sessionId).string());
+            sessionIdToString(sessionId).c_str());
     std::shared_ptr<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session.get() == nullptr) {
@@ -182,7 +182,7 @@
 
 status_t ClearKeyCasPlugin::processEcm(
         const CasSessionId &sessionId, const CasEcm& ecm) {
-    ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string());
+    ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).c_str());
     std::shared_ptr<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
     if (session.get() == nullptr) {
@@ -220,7 +220,7 @@
         const CasSessionId &sessionId, int32_t event,
         int arg, const CasData &eventData) {
     ALOGV("sendSessionEvent: sessionId=%s, event=%d, arg=%d",
-          sessionIdToString(sessionId).string(), event, arg);
+          sessionIdToString(sessionId).c_str(), event, arg);
     // Echo the received event to the callback.
     // Clear key plugin doesn't use any event, echo'ing for testing only.
     if (mCallbackExt != NULL) {
@@ -232,12 +232,12 @@
 }
 
 status_t ClearKeyCasPlugin::provision(const String8 &str) {
-    ALOGV("provision: provisionString=%s", str.string());
+    ALOGV("provision: provisionString=%s", str.c_str());
     Mutex::Autolock lock(mKeyFetcherLock);
 
     std::unique_ptr<ClearKeyLicenseFetcher> license_fetcher;
     license_fetcher.reset(new ClearKeyLicenseFetcher());
-    status_t err = license_fetcher->Init(str.string());
+    status_t err = license_fetcher->Init(str.c_str());
     if (err != OK) {
         ALOGE("provision: failed to init ClearKeyLicenseFetcher (err=%d)", err);
         return err;
@@ -475,7 +475,7 @@
 
 status_t ClearKeyDescramblerPlugin::setMediaCasSession(
         const CasSessionId &sessionId) {
-    ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string());
+    ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).c_str());
 
     std::shared_ptr<ClearKeyCasSession> session =
             ClearKeySessionLibrary::get()->findSession(sessionId);
@@ -503,7 +503,7 @@
     ALOGV("descramble: secure=%d, sctrl=%d, subSamples=%s, "
             "srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d",
           (int)secure, (int)scramblingControl,
-          subSamplesToString(subSamples, numSubSamples).string(),
+          subSamplesToString(subSamples, numSubSamples).c_str(),
           srcPtr, dstPtr, srcOffset, dstOffset);
 
     std::shared_ptr<ClearKeyCasSession> session = std::atomic_load(&mCASSession);
diff --git a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
index ee8dba3..a54ae47 100644
--- a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
+++ b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
@@ -80,7 +80,7 @@
         }
     }
 
-    return decodeBase64(AString(paddedText.string()));
+    return decodeBase64(AString(paddedText.c_str()));
 }
 
 bool JsonAssetLoader::findKey(const String8& jsonObject, Asset *asset) {
@@ -91,30 +91,30 @@
         return false;
     }
     findValue(kIdTag, &value);
-    ALOGV("found %s=%s", kIdTag.string(), value.string());
-    asset->set_id(atoi(value.string()));
+    ALOGV("found %s=%s", kIdTag.c_str(), value.c_str());
+    asset->set_id(atoi(value.c_str()));
 
     if (jsonObject.find(kNameTag) < 0) {
         return false;
     }
     findValue(kNameTag, &value);
-    ALOGV("found %s=%s", kNameTag.string(), value.string());
-    asset->set_name(value.string());
+    ALOGV("found %s=%s", kNameTag.c_str(), value.c_str());
+    asset->set_name(value.c_str());
 
     if (jsonObject.find(kLowerCaseOgranizationNameTag) < 0) {
         return false;
     }
     findValue(kLowerCaseOgranizationNameTag, &value);
-    ALOGV("found %s=%s", kLowerCaseOgranizationNameTag.string(), value.string());
-    asset->set_lowercase_organization_name(value.string());
+    ALOGV("found %s=%s", kLowerCaseOgranizationNameTag.c_str(), value.c_str());
+    asset->set_lowercase_organization_name(value.c_str());
 
     if (jsonObject.find(kCasTypeTag) < 0) {
         return false;
     }
     findValue(kCasTypeTag, &value);
-    ALOGV("found %s=%s", kCasTypeTag.string(), value.string());
+    ALOGV("found %s=%s", kCasTypeTag.c_str(), value.c_str());
     // Asset_CasType_CLEARKEY_CAS = 1
-    asset->set_cas_type((Asset_CasType)atoi(value.string()));
+    asset->set_cas_type((Asset_CasType)atoi(value.c_str()));
 
     return true;
 }
@@ -127,8 +127,8 @@
         if (0 == (*nextToken).compare(key)) {
             if (nextToken + 1 == mTokens.end())
                 break;
-            valueToken = (*(nextToken + 1)).string();
-            value->setTo(valueToken);
+            valueToken = (*(nextToken + 1)).c_str();
+            *value = valueToken;
             nextToken++;
             break;
         }
@@ -146,7 +146,7 @@
 
     jsmn_init(&parser);
     int numTokens = jsmn_parse(&parser,
-        jsonObject.string(), jsonObject.size(), NULL, 0);
+        jsonObject.c_str(), jsonObject.size(), NULL, 0);
     if (numTokens < 0) {
         ALOGE("Parser returns error code=%d", numTokens);
         return false;
@@ -157,7 +157,7 @@
     mJsmnTokens.setCapacity(jsmnTokensSize);
 
     jsmn_init(&parser);
-    int status = jsmn_parse(&parser, jsonObject.string(),
+    int status = jsmn_parse(&parser, jsonObject.c_str(),
         jsonObject.size(), mJsmnTokens.editArray(), numTokens);
     if (status < 0) {
         ALOGE("Parser returns error code=%d", status);
@@ -169,12 +169,12 @@
     const char *pjs;
     ALOGV("numTokens: %d", numTokens);
     for (int j = 0; j < numTokens; ++j) {
-        pjs = jsonObject.string() + mJsmnTokens[j].start;
+        pjs = jsonObject.c_str() + mJsmnTokens[j].start;
         if (mJsmnTokens[j].type == JSMN_STRING ||
                 mJsmnTokens[j].type == JSMN_PRIMITIVE) {
-            token.setTo(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start);
+            token = String8(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start);
             tokens->add(token);
-            ALOGV("add token: %s", token.string());
+            ALOGV("add token: %s", token.c_str());
         }
     }
     return true;
@@ -199,7 +199,7 @@
     // the original string.
     jsmn_init(&parser);
     int numTokens = jsmn_parse(&parser,
-            jsonAsset.string(), jsonAsset.size(), NULL, 0);
+            jsonAsset.c_str(), jsonAsset.size(), NULL, 0);
     if (numTokens < 0) {
         ALOGE("Parser returns error code=%d", numTokens);
         return false;
@@ -209,7 +209,7 @@
     mJsmnTokens.setCapacity(jsmnTokensSize);
 
     jsmn_init(&parser);
-    int status = jsmn_parse(&parser, jsonAsset.string(),
+    int status = jsmn_parse(&parser, jsonAsset.c_str(),
             jsonAsset.size(), mJsmnTokens.editArray(), numTokens);
     if (status < 0) {
         ALOGE("Parser returns error code=%d", status);
@@ -219,9 +219,9 @@
     String8 token;
     const char *pjs;
     for (int i = 0; i < numTokens; ++i) {
-        pjs = jsonAsset.string() + mJsmnTokens[i].start;
+        pjs = jsonAsset.c_str() + mJsmnTokens[i].start;
         if (mJsmnTokens[i].type == JSMN_OBJECT) {
-            token.setTo(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start);
+            token = String8(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start);
             jsonObjects->add(token);
         }
     }
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index f8bab0a..671fba1 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -135,7 +135,7 @@
 }
 
 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
-    ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string());
+    ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).c_str());
     Mutex::Autolock lock(mLock);
 
     sp<MockCasSession> session =
@@ -151,7 +151,7 @@
 status_t MockCasPlugin::setSessionPrivateData(
         const CasSessionId &sessionId, const CasData& /*data*/) {
     ALOGV("setSessionPrivateData: sessionId=%s",
-            arrayToString(sessionId).string());
+            arrayToString(sessionId).c_str());
     Mutex::Autolock lock(mLock);
 
     sp<MockCasSession> session =
@@ -164,7 +164,7 @@
 
 status_t MockCasPlugin::processEcm(
         const CasSessionId &sessionId, const CasEcm& ecm) {
-    ALOGV("processEcm: sessionId=%s", arrayToString(sessionId).string());
+    ALOGV("processEcm: sessionId=%s", arrayToString(sessionId).c_str());
     Mutex::Autolock lock(mLock);
 
     sp<MockCasSession> session =
@@ -173,7 +173,7 @@
         return BAD_VALUE;
     }
     ALOGV("ECM: size=%zu", ecm.size());
-    ALOGV("ECM: data=%s", arrayToString(ecm).string());
+    ALOGV("ECM: data=%s", arrayToString(ecm).c_str());
 
     return OK;
 }
@@ -183,7 +183,7 @@
     Mutex::Autolock lock(mLock);
 
     ALOGV("EMM: size=%zu", emm.size());
-    ALOGV("EMM: data=%s", arrayToString(emm).string());
+    ALOGV("EMM: data=%s", arrayToString(emm).c_str());
 
     return OK;
 }
@@ -200,14 +200,14 @@
         const CasSessionId &sessionId, int32_t event,
         int /*arg*/, const CasData& /*eventData*/) {
     ALOGV("sendSessionEvent: sessionId=%s, event=%d",
-          arrayToString(sessionId).string(), event);
+          arrayToString(sessionId).c_str(), event);
     Mutex::Autolock lock(mLock);
 
     return OK;
 }
 
 status_t MockCasPlugin::provision(const String8 &str) {
-    ALOGV("provision: provisionString=%s", str.string());
+    ALOGV("provision: provisionString=%s", str.c_str());
     Mutex::Autolock lock(mLock);
 
     return OK;
@@ -215,7 +215,7 @@
 
 status_t MockCasPlugin::refreshEntitlements(
         int32_t /*refreshType*/, const CasData &refreshData) {
-    ALOGV("refreshEntitlements: refreshData=%s", arrayToString(refreshData).string());
+    ALOGV("refreshEntitlements: refreshData=%s", arrayToString(refreshData).c_str());
     Mutex::Autolock lock(mLock);
 
     return OK;
@@ -256,7 +256,7 @@
     ALOGV("MockDescramblerPlugin::descramble(secure=%d, sctrl=%d,"
           "subSamples=%s, srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d)",
           (int)secure, (int)scramblingControl,
-          subSamplesToString(subSamples, numSubSamples).string(),
+          subSamplesToString(subSamples, numSubSamples).c_str(),
           srcPtr, dstPtr, srcOffset, dstOffset);
 
     return 0;
diff --git a/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
index 089eb1c..7ee8d3d 100644
--- a/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
@@ -142,7 +142,7 @@
         const String8& name, Vector<uint8_t>& value) const {
     ssize_t index = mByteArrayProperties.indexOfKey(name);
     if (index < 0) {
-        ALOGE("App requested unknown property: %s", name.string());
+        ALOGE("App requested unknown property: %s", name.c_str());
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
     value = mByteArrayProperties.valueAt(index);
@@ -154,12 +154,12 @@
 {
     UNUSED(value);
     if (0 == name.compare(kDeviceIdKey)) {
-        ALOGD("Cannot set immutable property: %s", name.string());
+        ALOGD("Cannot set immutable property: %s", name.c_str());
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
 
     // Setting of undefined properties is not supported
-    ALOGE("Failed to set property byte array, key=%s", name.string());
+    ALOGE("Failed to set property byte array, key=%s", name.c_str());
     return android::ERROR_DRM_CANNOT_HANDLE;
 }
 
@@ -167,7 +167,7 @@
         const String8& name, String8& value) const {
     ssize_t index = mStringProperties.indexOfKey(name);
     if (index < 0) {
-        ALOGE("App requested unknown property: %s", name.string());
+        ALOGE("App requested unknown property: %s", name.c_str());
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
     value = mStringProperties.valueAt(index);
@@ -178,21 +178,21 @@
         const String8& name, const String8& value) {
     String8 immutableKeys;
     immutableKeys.appendFormat("%s,%s,%s,%s",
-            kAlgorithmsKey.string(), kPluginDescriptionKey.string(),
-            kVendorKey.string(), kVersionKey.string());
-    if (immutableKeys.contains(name.string())) {
-        ALOGD("Cannot set immutable property: %s", name.string());
+            kAlgorithmsKey.c_str(), kPluginDescriptionKey.c_str(),
+            kVendorKey.c_str(), kVersionKey.c_str());
+    if (immutableKeys.contains(name.c_str())) {
+        ALOGD("Cannot set immutable property: %s", name.c_str());
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
 
     ssize_t index = mStringProperties.indexOfKey(name);
     if (index < 0) {
-        ALOGE("Cannot set undefined property string, key=%s", name.string());
+        ALOGE("Cannot set undefined property string, key=%s", name.c_str());
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
 
     if (mStringProperties.add(name, value) < 0) {
-        ALOGE("Failed to set property string, key=%s", name.string());
+        ALOGE("Failed to set property string, key=%s", name.c_str());
         return android::ERROR_DRM_UNKNOWN;
     }
     return android::OK;
diff --git a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
index 121a4e2..ca697a2 100644
--- a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
@@ -69,7 +69,7 @@
     String8 requestJson = generateRequest(keyIds);
     licenseRequest->clear();
     licenseRequest->appendArray(
-            reinterpret_cast<const uint8_t*>(requestJson.string()),
+            reinterpret_cast<const uint8_t*>(requestJson.c_str()),
             requestJson.size());
     return android::OK;
 }
diff --git a/drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp
index a2d506d..a12b1d1 100644
--- a/drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp
@@ -83,12 +83,12 @@
             }
 
             if (!decodeBase64String(encodedKeyId, &decodedKeyId)) {
-                ALOGE("Failed to decode key id(%s)", encodedKeyId.string());
+                ALOGE("Failed to decode key id(%s)", encodedKeyId.c_str());
                 continue;
             }
 
             if (!decodeBase64String(encodedKey, &decodedKey)) {
-                ALOGE("Failed to decode key(%s)", encodedKey.string());
+                ALOGE("Failed to decode key(%s)", encodedKey.c_str());
                 continue;
             }
 
@@ -119,7 +119,7 @@
     }
 
     android::sp<ABuffer> buffer =
-            android::decodeBase64(AString(paddedText.string()));
+            android::decodeBase64(AString(paddedText.c_str()));
     if (buffer == NULL) {
         ALOGE("Malformed base64 encoded content found.");
         return false;
@@ -159,8 +159,8 @@
         if (0 == (*nextToken).compare(key)) {
             if (nextToken + 1 == mTokens.end())
                 break;
-            valueToken = (*(nextToken + 1)).string();
-            value->setTo(valueToken);
+            valueToken = (*(nextToken + 1)).c_str();
+            *value = valueToken;
             nextToken++;
             break;
         }
@@ -186,7 +186,7 @@
 
     jsmn_init(&parser);
     int numTokens = jsmn_parse(&parser,
-        jsonObject.string(), jsonObject.size(), NULL, 0);
+        jsonObject.c_str(), jsonObject.size(), NULL, 0);
     if (numTokens < 0) {
         ALOGE("Parser returns error code=%d", numTokens);
         return false;
@@ -197,7 +197,7 @@
     mJsmnTokens.setCapacity(jsmnTokensSize);
 
     jsmn_init(&parser);
-    int status = jsmn_parse(&parser, jsonObject.string(),
+    int status = jsmn_parse(&parser, jsonObject.c_str(),
         jsonObject.size(), mJsmnTokens.editArray(), numTokens);
     if (status < 0) {
         ALOGE("Parser returns error code=%d", status);
@@ -208,10 +208,10 @@
     String8 token;
     const char *pjs;
     for (int j = 0; j < numTokens; ++j) {
-        pjs = jsonObject.string() + mJsmnTokens[j].start;
+        pjs = jsonObject.c_str() + mJsmnTokens[j].start;
         if (mJsmnTokens[j].type == JSMN_STRING ||
                 mJsmnTokens[j].type == JSMN_PRIMITIVE) {
-            token.setTo(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start);
+            token = String8(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start);
             tokens->add(token);
         }
     }
@@ -237,7 +237,7 @@
     // the original string.
     jsmn_init(&parser);
     int numTokens = jsmn_parse(&parser,
-            jsonWebKeySet.string(), jsonWebKeySet.size(), NULL, 0);
+            jsonWebKeySet.c_str(), jsonWebKeySet.size(), NULL, 0);
     if (numTokens < 0) {
         ALOGE("Parser returns error code=%d", numTokens);
         return false;
@@ -247,7 +247,7 @@
     mJsmnTokens.setCapacity(jsmnTokensSize);
 
     jsmn_init(&parser);
-    int status = jsmn_parse(&parser, jsonWebKeySet.string(),
+    int status = jsmn_parse(&parser, jsonWebKeySet.c_str(),
             jsonWebKeySet.size(), mJsmnTokens.editArray(), numTokens);
     if (status < 0) {
         ALOGE("Parser returns error code=%d", status);
@@ -257,9 +257,9 @@
     String8 token;
     const char *pjs;
     for (int i = 0; i < numTokens; ++i) {
-        pjs = jsonWebKeySet.string() + mJsmnTokens[i].start;
+        pjs = jsonWebKeySet.c_str() + mJsmnTokens[i].start;
         if (mJsmnTokens[i].type == JSMN_OBJECT) {
-            token.setTo(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start);
+            token = String8(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start);
             jsonObjects->add(token);
         }
     }
diff --git a/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
index 529230e..058f8ce 100644
--- a/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
@@ -50,7 +50,7 @@
     mNextSessionId += 1;
     Vector<uint8_t> sessionId;
     sessionId.appendArray(
-            reinterpret_cast<const uint8_t*>(sessionIdString.string()),
+            reinterpret_cast<const uint8_t*>(sessionIdString.c_str()),
             sessionIdString.size());
 
     mSessions.add(sessionId, new Session(sessionId));
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
index 3b4145f..db98a80 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
@@ -91,14 +91,14 @@
         }
         mSessions.add(sessionId);
 
-        ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).string());
+        ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).c_str());
         return OK;
     }
 
     status_t MockDrmPlugin::closeSession(Vector<uint8_t> const &sessionId)
     {
         Mutex::Autolock lock(mLock);
-        ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).string());
+        ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).c_str());
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
             ALOGD("Invalid sessionId");
@@ -119,8 +119,8 @@
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s"
               ", keyType=%d, optionalParameters=%s))",
-              vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(),
-              keyType, stringMapToString(optionalParameters).string());
+              vectorToString(sessionId).c_str(), vectorToString(initData).c_str(), mimeType.c_str(),
+              keyType, stringMapToString(optionalParameters).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -144,8 +144,8 @@
         String8 params;
         for (size_t i = 0; i < optionalParameters.size(); i++) {
             params.appendFormat("%s{%s,%s}", i ? "," : "",
-                                optionalParameters.keyAt(i).string(),
-                                optionalParameters.valueAt(i).string());
+                                optionalParameters.keyAt(i).c_str(),
+                                optionalParameters.valueAt(i).c_str());
         }
         mStringProperties.add(String8("mock-optparams"), params);
 
@@ -176,7 +176,7 @@
             return BAD_VALUE;
         } else {
             *keyRequestType = static_cast<KeyRequestType>(
-                atoi(mStringProperties.valueAt(index).string()));
+                atoi(mStringProperties.valueAt(index).c_str()));
         }
 
         return OK;
@@ -188,7 +188,7 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)",
-              vectorToString(sessionId).string(), vectorToString(response).string());
+              vectorToString(sessionId).c_str(), vectorToString(response).c_str());
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
             ALOGD("Invalid sessionId");
@@ -217,7 +217,7 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)",
-              vectorToString(keySetId).string());
+              vectorToString(keySetId).c_str());
 
         ssize_t index = findKeySet(keySetId);
         if (index == kNotFound) {
@@ -234,8 +234,8 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)",
-              vectorToString(sessionId).string(),
-              vectorToString(keySetId).string());
+              vectorToString(sessionId).c_str(),
+              vectorToString(keySetId).c_str());
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
             ALOGD("Invalid sessionId");
@@ -255,7 +255,7 @@
                                                KeyedVector<String8, String8> &infoMap) const
     {
         ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)",
-              vectorToString(sessionId).string());
+              vectorToString(sessionId).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -304,7 +304,7 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::provideProvisionResponse(%s)",
-              vectorToString(response).string());
+              vectorToString(response).c_str());
 
         // Properties used in mock test, set by mock plugin and verifed cts test app
         //   byte[] response            -> mock-response
@@ -367,7 +367,7 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::releaseSecureStops(%s)",
-              vectorToString(ssRelease).string());
+              vectorToString(ssRelease).c_str());
 
         // Properties used in mock test, set by mock plugin and verifed cts test app
         //   byte[] secure-stop-release  -> mock-ssrelease
@@ -385,10 +385,10 @@
 
     status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const
     {
-        ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string());
+        ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.c_str());
         ssize_t index = mStringProperties.indexOfKey(name);
         if (index < 0) {
-            ALOGD("no property for '%s'", name.string());
+            ALOGD("no property for '%s'", name.c_str());
             return BAD_VALUE;
         }
         value = mStringProperties.valueAt(index);
@@ -398,10 +398,10 @@
     status_t MockDrmPlugin::getPropertyByteArray(String8 const &name,
                                                  Vector<uint8_t> &value) const
     {
-        ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string());
+        ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.c_str());
         ssize_t index = mByteArrayProperties.indexOfKey(name);
         if (index < 0) {
-            ALOGD("no property for '%s'", name.string());
+            ALOGD("no property for '%s'", name.c_str());
             return BAD_VALUE;
         }
         value = mByteArrayProperties.valueAt(index);
@@ -413,11 +413,11 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",
-              name.string(), value.string());
+              name.c_str(), value.c_str());
 
         if (name == "mock-send-event") {
             unsigned code, extra;
-            sscanf(value.string(), "%d %d", &code, &extra);
+            sscanf(value.c_str(), "%d %d", &code, &extra);
             DrmPlugin::EventType eventType = (DrmPlugin::EventType)code;
 
             Vector<uint8_t> const *pSessionId = NULL;
@@ -438,7 +438,7 @@
             sendEvent(eventType, extra, pSessionId, pData);
         } else if (name == "mock-send-expiration-update") {
             int64_t expiryTimeMS;
-            sscanf(value.string(), "%jd", &expiryTimeMS);
+            sscanf(value.c_str(), "%jd", &expiryTimeMS);
 
             Vector<uint8_t> const *pSessionId = NULL;
             ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
@@ -504,7 +504,7 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)",
-              name.string(), vectorToString(value).string());
+              name.c_str(), vectorToString(value).c_str());
         mByteArrayProperties.add(name, value);
         return OK;
     }
@@ -515,7 +515,7 @@
         Mutex::Autolock lock(mLock);
 
         ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
-              vectorToString(sessionId).string(), algorithm.string());
+              vectorToString(sessionId).c_str(), algorithm.c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -535,7 +535,7 @@
         Mutex::Autolock lock(mLock);
 
         ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
-              vectorToString(sessionId).string(), algorithm.string());
+              vectorToString(sessionId).c_str(), algorithm.c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -557,10 +557,10 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
-              vectorToString(sessionId).string(),
-              vectorToString(keyId).string(),
-              vectorToString(input).string(),
-              vectorToString(iv).string());
+              vectorToString(sessionId).c_str(),
+              vectorToString(keyId).c_str(),
+              vectorToString(input).c_str(),
+              vectorToString(iv).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -596,10 +596,10 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
-              vectorToString(sessionId).string(),
-              vectorToString(keyId).string(),
-              vectorToString(input).string(),
-              vectorToString(iv).string());
+              vectorToString(sessionId).c_str(),
+              vectorToString(keyId).c_str(),
+              vectorToString(input).c_str(),
+              vectorToString(iv).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -634,9 +634,9 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
-              vectorToString(sessionId).string(),
-              vectorToString(keyId).string(),
-              vectorToString(message).string());
+              vectorToString(sessionId).c_str(),
+              vectorToString(keyId).c_str(),
+              vectorToString(message).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -670,10 +670,10 @@
     {
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
-              vectorToString(sessionId).string(),
-              vectorToString(keyId).string(),
-              vectorToString(message).string(),
-              vectorToString(signature).string());
+              vectorToString(sessionId).c_str(),
+              vectorToString(keyId).c_str(),
+              vectorToString(message).c_str(),
+              vectorToString(signature).c_str());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -696,7 +696,7 @@
             ALOGD("Missing 'mock-request' parameter for mock");
             return BAD_VALUE;
         } else {
-            match = atol(mStringProperties.valueAt(index).string());
+            match = atol(mStringProperties.valueAt(index).c_str());
         }
         return OK;
     }
@@ -710,11 +710,11 @@
         Mutex::Autolock lock(mLock);
         ALOGD("MockDrmPlugin::signRSA(sessionId=%s, algorithm=%s, keyId=%s, "
               "message=%s, signature=%s)",
-              vectorToString(sessionId).string(),
-              algorithm.string(),
-              vectorToString(message).string(),
-              vectorToString(wrappedKey).string(),
-              vectorToString(signature).string());
+              vectorToString(sessionId).c_str(),
+              algorithm.c_str(),
+              vectorToString(message).c_str(),
+              vectorToString(wrappedKey).c_str(),
+              vectorToString(signature).c_str());
 
         // Properties used in mock test, set by mock plugin and verifed cts test app
         //   byte[] wrappedKey         -> mock-wrappedkey
@@ -772,7 +772,7 @@
         String8 result("{ ");
         for (size_t i = 0; i < map.size(); i++) {
             result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "",
-                                map.keyAt(i).string(), map.valueAt(i).string());
+                                map.keyAt(i).c_str(), map.valueAt(i).c_str());
         }
         return result + " }";
     }
@@ -802,10 +802,10 @@
               "pattern:{encryptBlocks=%d, skipBlocks=%d} src=%p, "
               "subSamples=%s, dst=%p)",
               (int)secure,
-              arrayToString(key, DECRYPT_KEY_SIZE).string(),
-              arrayToString(iv, DECRYPT_KEY_SIZE).string(),
+              arrayToString(key, DECRYPT_KEY_SIZE).c_str(),
+              arrayToString(iv, DECRYPT_KEY_SIZE).c_str(),
               (int)mode, pattern.mEncryptBlocks, pattern.mSkipBlocks, srcPtr,
-              subSamplesToString(subSamples, numSubSamples).string(),
+              subSamplesToString(subSamples, numSubSamples).c_str(),
               dstPtr);
         return OK;
     }
diff --git a/include/media/OWNERS b/include/media/OWNERS
new file mode 100644
index 0000000..b1cfd52
--- /dev/null
+++ b/include/media/OWNERS
@@ -0,0 +1,2 @@
+per-file DataSource.h,ExtractorUtils.h,MediaExtractorPluginApi.h,MediaExtractorPluginHelper.h,MediaPlayerInterface.h,MediaTrack.h=set noparent
+per-file DataSource.h,ExtractorUtils.h,MediaExtractorPluginApi.h,MediaExtractorPluginHelper.h,MediaPlayerInterface.h,MediaTrack.h=file:platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/include/media/VolumeShaper.h b/include/media/VolumeShaper.h
index 5271e10..6208db3 100644
--- a/include/media/VolumeShaper.h
+++ b/include/media/VolumeShaper.h
@@ -1099,7 +1099,7 @@
      * internal to the VolumeHandler.
      */
     void setIdIfNecessary(const sp<VolumeShaper::Configuration> &configuration) {
-        if (configuration->getType() == VolumeShaper::Configuration::TYPE_SCALE) {
+        if (configuration && configuration->getType() == VolumeShaper::Configuration::TYPE_SCALE) {
             const int id = configuration->getId();
             if (id == -1) {
                 // Reassign to a unique id, skipping system ids.
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 4d3f9bd..7ea51ff 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -508,15 +508,6 @@
             {
                 AUDIO_DEVICE_IN_ECHO_REFERENCE, make_AudioDeviceDescription(
                         AudioDeviceType::IN_ECHO_REFERENCE)
-            },
-            {
-                AUDIO_DEVICE_IN_REMOTE_SUBMIX, make_AudioDeviceDescription(
-                         AudioDeviceType::IN_SUBMIX)
-            },
-            {
-                AUDIO_DEVICE_OUT_REMOTE_SUBMIX, make_AudioDeviceDescription(
-                        AudioDeviceType::OUT_SUBMIX,
-                        GET_DEVICE_DESC_CONNECTION(VIRTUAL))
             }
         }};
         append_AudioDeviceDescription(pairs,
@@ -592,6 +583,11 @@
                 AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_OUT_BLE_HEADSET,
                 AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
                 GET_DEVICE_DESC_CONNECTION(BT_LE));
+        append_AudioDeviceDescription(pairs,
+                AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                AudioDeviceType::IN_SUBMIX, AudioDeviceType::OUT_SUBMIX,
+                GET_DEVICE_DESC_CONNECTION(VIRTUAL));
+
         return pairs;
     }();
     return pairs;
diff --git a/media/audioaidlconversion/AidlConversionEffect.cpp b/media/audioaidlconversion/AidlConversionEffect.cpp
index 611cfab..6f55f1b 100644
--- a/media/audioaidlconversion/AidlConversionEffect.cpp
+++ b/media/audioaidlconversion/AidlConversionEffect.cpp
@@ -52,6 +52,7 @@
 using ::android::status_t;
 using ::android::base::unexpected;
 using ::android::effect::utils::EffectParamReader;
+using ::android::effect::utils::EffectParamWrapper;
 using ::android::effect::utils::EffectParamWriter;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -408,40 +409,7 @@
     }
 }
 
-/**
- * Copy the parameter area of effect_param_t to DefaultExtension::bytes.
- */
-ConversionResult<VendorExtension> legacy2aidl_EffectParameterReader_Param_VendorExtension(
-        EffectParamReader& param) {
-    size_t len = param.getParameterSize();
-    DefaultExtension defaultExt;
-    defaultExt.bytes.resize(len);
-    RETURN_IF_ERROR(param.readFromParameter(defaultExt.bytes.data(), len));
-
-    VendorExtension ext;
-    ext.extension.setParcelable(defaultExt);
-    return ext;
-}
-
-/**
- * Copy the data area of effect_param_t to DefaultExtension::bytes.
- */
-ConversionResult<VendorExtension> legacy2aidl_EffectParameterReader_Data_VendorExtension(
-        EffectParamReader& param) {
-    size_t len = param.getValueSize();
-    DefaultExtension defaultExt;
-    defaultExt.bytes.resize(len);
-    RETURN_IF_ERROR(param.readFromValue(defaultExt.bytes.data(), len));
-
-    VendorExtension ext;
-    ext.extension.setParcelable(defaultExt);
-    return ext;
-}
-
-/**
- * Copy DefaultExtension::bytes to the data area of effect_param_t.
- */
-ConversionResult<status_t> aidl2legacy_VendorExtension_EffectParameterWriter_Data(
+ConversionResult<status_t> aidl2legacy_VendorExtension_EffectParameterWriter(
         EffectParamWriter& param, VendorExtension ext) {
     std::optional<DefaultExtension> defaultExt;
     RETURN_IF_ERROR(ext.extension.getParcelable(&defaultExt));
@@ -449,26 +417,47 @@
         return unexpected(BAD_VALUE);
     }
 
-    RETURN_IF_ERROR(param.writeToValue(defaultExt->bytes.data(), defaultExt->bytes.size()));
+    // DefaultExtension defaultValue = defaultExt->get();
+    if (defaultExt->bytes.size() < sizeof(effect_param_t)) {
+        return unexpected(BAD_VALUE);
+    }
+    // verify data length with EffectParamWrapper, DefaultExtension array size should not smaller
+    // than (sizeof(effect_param_t) + paddedPSize + vSize)
+    EffectParamWrapper wrapper(*(effect_param_t*)defaultExt->bytes.data());
+    if (sizeof(effect_param_t) + wrapper.getPaddedParameterSize() + wrapper.getValueSize() >
+        defaultExt->bytes.size()) {
+        return unexpected(BAD_VALUE);
+    }
 
+    RETURN_IF_ERROR(param.overwrite(wrapper.getEffectParam()));
     return OK;
 }
 
-ConversionResult<Parameter> legacy2aidl_EffectParameterReader_ParameterExtension(
+ConversionResult<VendorExtension> legacy2aidl_EffectParameterReader_VendorExtension(
         EffectParamReader& param) {
-    VendorExtension ext =
-            VALUE_OR_RETURN(legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
-    return UNION_MAKE(Parameter, specific, UNION_MAKE(Parameter::Specific, vendorEffect, ext));
+    size_t len = param.getTotalSize();
+    DefaultExtension defaultExt;
+    defaultExt.bytes.resize(len);
+
+    std::memcpy(defaultExt.bytes.data(), (void *)&param.getEffectParam(), len);
+
+    VendorExtension ext;
+    ext.extension.setParcelable(defaultExt);
+    return ext;
 }
 
-ConversionResult<::android::status_t> aidl2legacy_ParameterExtension_EffectParameterWriter(
+ConversionResult<::android::status_t> aidl2legacy_Parameter_EffectParameterWriter(
         const ::aidl::android::hardware::audio::effect::Parameter& aidl,
         EffectParamWriter& legacy) {
     VendorExtension ext = VALUE_OR_RETURN(
             (::aidl::android::getParameterSpecific<Parameter, VendorExtension,
                                                    Parameter::Specific::vendorEffect>(aidl)));
-    return VALUE_OR_RETURN_STATUS(
-            aidl2legacy_VendorExtension_EffectParameterWriter_Data(legacy, ext));
+    return VALUE_OR_RETURN_STATUS(aidl2legacy_VendorExtension_EffectParameterWriter(legacy, ext));
+}
+
+ConversionResult<Parameter> legacy2aidl_EffectParameterReader_Parameter(EffectParamReader& param) {
+    VendorExtension ext = VALUE_OR_RETURN(legacy2aidl_EffectParameterReader_VendorExtension(param));
+    return UNION_MAKE(Parameter, specific, UNION_MAKE(Parameter::Specific, vendorEffect, ext));
 }
 
 }  // namespace android
diff --git a/media/audioaidlconversion/TEST_MAPPING b/media/audioaidlconversion/TEST_MAPPING
index 216bc12..203ed2f 100644
--- a/media/audioaidlconversion/TEST_MAPPING
+++ b/media/audioaidlconversion/TEST_MAPPING
@@ -1,8 +1,12 @@
 {
   "presubmit": [
     {
-      "name": "audio_aidl_conversion_tests",
-      "name": "audio_aidl_ndk_conversion_tests",
+      "name": "audio_aidl_conversion_tests"
+    },
+    {
+      "name": "audio_aidl_ndk_conversion_tests"
+    },
+    {
       "name": "audio_aidl_ndk_cpp_conversion_tests"
     }
   ]
diff --git a/media/audioaidlconversion/include/media/AidlConversionEffect.h b/media/audioaidlconversion/include/media/AidlConversionEffect.h
index 5e245a7..b03d06b 100644
--- a/media/audioaidlconversion/include/media/AidlConversionEffect.h
+++ b/media/audioaidlconversion/include/media/AidlConversionEffect.h
@@ -67,7 +67,7 @@
 #define VENDOR_EXTENSION_GET_AND_RETURN(_effect, _tag, _param)                                    \
     {                                                                                             \
         aidl::android::hardware::audio::effect::VendorExtension _extId = VALUE_OR_RETURN_STATUS(  \
-                aidl::android::legacy2aidl_EffectParameterReader_Param_VendorExtension(_param));  \
+                aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(_param));        \
         aidl::android::hardware::audio::effect::Parameter::Id _id =                               \
                 MAKE_EXTENSION_PARAMETER_ID(_effect, _tag##Tag, _extId);                          \
         aidl::android::hardware::audio::effect::Parameter _aidlParam;                             \
@@ -76,8 +76,7 @@
                 VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(                              \
                         _aidlParam, _effect, _tag, _effect::vendor, VendorExtension));            \
         return VALUE_OR_RETURN_STATUS(                                                            \
-                aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(_aidlParam,   \
-                                                                                    _param));     \
+                aidl::android::aidl2legacy_Parameter_EffectParameterWriter(_aidlParam, _param));  \
     }
 
 ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
@@ -157,26 +156,26 @@
 ConversionResult<::aidl::android::hardware::audio::effect::Visualizer::MeasurementMode>
 legacy2aidl_Parameter_Visualizer_uint32_MeasurementMode(uint32_t legacy);
 
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_EffectParameterReader_ParameterExtension(
-        ::android::effect::utils::EffectParamReader& param);
-ConversionResult<::android::status_t> aidl2legacy_ParameterExtension_EffectParameterWriter(
-        const ::aidl::android::hardware::audio::effect::Parameter& aidl,
-        ::android::effect::utils::EffectParamWriter& legacy);
-
-ConversionResult<::aidl::android::hardware::audio::effect::VendorExtension>
-legacy2aidl_EffectParameterReader_Param_VendorExtension(
-        ::android::effect::utils::EffectParamReader& param);
-ConversionResult<::aidl::android::hardware::audio::effect::VendorExtension>
-legacy2aidl_EffectParameterReader_Data_VendorExtension(
-        ::android::effect::utils::EffectParamReader& param);
-
+/**
+ * Read DefaultExtension from VendorExtension, and overwrite to the entire effect_param_t (both
+ * parameter and data area) with EffectParamWriter::overwrite.
+ */
 ConversionResult<::android::status_t> aidl2legacy_VendorExtension_EffectParameterWriter_Data(
         ::android::effect::utils::EffectParamWriter& param,
         ::aidl::android::hardware::audio::effect::VendorExtension ext);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_EffectParameterReader_ParameterExtension(
+/**
+ * Copy the entire effect_param_t (both parameter and data area) to DefaultExtension::bytes, and
+ * write into VendorExtension.
+ */
+ConversionResult<::aidl::android::hardware::audio::effect::VendorExtension>
+legacy2aidl_EffectParameterReader_VendorExtension(
         ::android::effect::utils::EffectParamReader& param);
 
+ConversionResult<::android::status_t> aidl2legacy_Parameter_EffectParameterWriter(
+        const ::aidl::android::hardware::audio::effect::Parameter& aidl,
+        ::android::effect::utils::EffectParamWriter& legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_EffectParameterReader_Parameter(
+        ::android::effect::utils::EffectParamReader& param);
 }  // namespace android
 }  // namespace aidl
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
index d6793e0..719962d 100644
--- a/media/codec2/fuzzer/C2Fuzzer.cpp
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -239,6 +239,7 @@
 }
 
 void Codec2Fuzzer::decodeFrames(const uint8_t* data, size_t size) {
+  static const size_t kPageSize = getpagesize();
   std::unique_ptr<BufferSource> bufferSource = std::make_unique<BufferSource>(data, size);
   if (!bufferSource) {
     return;
@@ -270,7 +271,7 @@
     work->input.ordinal.timestamp = 0;
     work->input.ordinal.frameIndex = ++numFrames;
     work->input.buffers.clear();
-    int32_t alignedSize = C2FUZZER_ALIGN(frameSize, PAGE_SIZE);
+    int32_t alignedSize = C2FUZZER_ALIGN(frameSize, kPageSize);
 
     std::shared_ptr<C2LinearBlock> block;
     status = mLinearPool->fetchLinearBlock(
diff --git a/media/codec2/hal/aidl/Android.bp b/media/codec2/hal/aidl/Android.bp
new file mode 100644
index 0000000..3bc7548
--- /dev/null
+++ b/media/codec2/hal/aidl/Android.bp
@@ -0,0 +1,150 @@
+package {
+    default_applicable_licenses: ["frameworks_av_license"],
+}
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-aidl-client-defaults instead
+cc_library {
+    name: "libcodec2_aidl_client",
+
+    srcs: [
+        "ParamTypes.cpp",
+    ],
+
+    header_libs: [
+        "libcodec2_internal", // private
+        "libgui_headers",
+    ],
+
+    shared_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "android.hardware.media.c2-V1-ndk",
+        "libbinder_ndk",
+        "libbase",
+        "libcodec2",
+        "libcodec2_hal_common",
+        "libcodec2_vndk",
+        "libcutils",
+        "liblog",
+        "libnativewindow",
+        "libutils",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "android.hardware.media.c2-V1-ndk",
+        "libcodec2",
+        "libcodec2_hal_common",
+    ],
+}
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-defaults instead
+//cc_library {
+//    name: "libcodec2_hidl@1.0",
+//    vendor_available: true,
+//    min_sdk_version: "29",
+//    apex_available: [
+//        "//apex_available:platform",
+//        "com.android.media.swcodec",
+//    ],
+//
+//    defaults: ["hidl_defaults"],
+//
+//    srcs: [
+//        "Component.cpp",
+//        "ComponentInterface.cpp",
+//        "ComponentStore.cpp",
+//        "Configurable.cpp",
+//        "InputBufferManager.cpp",
+//        "InputSurface.cpp",
+//        "InputSurfaceConnection.cpp",
+//        "types.cpp",
+//    ],
+//
+//    header_libs: [
+//        "libbinder_headers",
+//        "libcodec2_hal_common",
+//        "libcodec2_internal", // private
+//        "libsystem_headers",
+//    ],
+//
+//    shared_libs: [
+//        "android.hardware.graphics.bufferqueue@1.0",
+//        "android.hardware.graphics.bufferqueue@2.0",
+//        "android.hardware.graphics.common@1.0",
+//        "android.hardware.media@1.0",
+//        "android.hardware.media.bufferpool@2.0",
+//        "android.hardware.media.c2@1.0",
+//        "android.hardware.media.omx@1.0",
+//        "libbase",
+//        "libcodec2",
+//        "libcodec2_vndk",
+//        "libcodec2_hidl_plugin_stub",
+//        "libcutils",
+//        "libhidlbase",
+//        "liblog",
+//        "libstagefright_bufferpool@2.0.1",
+//        "libstagefright_bufferqueue_helper_novndk",
+//        "libui",
+//        "libutils",
+//    ],
+//
+//    target: {
+//        vendor: {
+//            exclude_shared_libs: [
+//                "libstagefright_bufferqueue_helper_novndk",
+//                "libcodec2_hidl_plugin_stub",
+//            ],
+//            shared_libs: [
+//                "libstagefright_bufferqueue_helper",
+//                "libcodec2_hidl_plugin",
+//            ],
+//        },
+//        apex: {
+//            exclude_shared_libs: [
+//                "libcodec2_hidl_plugin",
+//                "libcodec2_hidl_plugin_stub",
+//            ],
+//        },
+//    },
+//
+//    export_include_dirs: [
+//        "include",
+//    ],
+//
+//    export_shared_lib_headers: [
+//        "android.hardware.media.c2@1.0",
+//        "libcodec2",
+//        "libcodec2_vndk",
+//        "libhidlbase",
+//        "libstagefright_bufferpool@2.0.1",
+//        "libui",
+//    ],
+//}
+//
+//// public dependency for Codec 2.0 HAL service implementations
+//cc_defaults {
+//    name: "libcodec2-hidl-defaults@1.0",
+//    defaults: ["libcodec2-impl-defaults"],
+//
+//    shared_libs: [
+//        "android.hardware.media.c2@1.0",
+//        "libcodec2_hidl@1.0",
+//    ],
+//}
+
+// public dependency for Codec 2.0 HAL client
+cc_defaults {
+    name: "libcodec2-aidl-client-defaults",
+    min_sdk_version: "34",
+    defaults: ["libcodec2-impl-defaults"],
+
+    shared_libs: [
+        "android.hardware.media.c2-V1-ndk",
+        "libcodec2_aidl_client",
+    ],
+}
diff --git a/media/codec2/hal/aidl/BufferTypes.cpp b/media/codec2/hal/aidl/BufferTypes.cpp
new file mode 100644
index 0000000..319ba62
--- /dev/null
+++ b/media/codec2/hal/aidl/BufferTypes.cpp
@@ -0,0 +1,1928 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-types"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.0/types.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2FenceFactory.h>
+#include <C2Param.h>
+#include <C2ParamInternal.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+#include <util/C2ParamUtils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iomanip>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+using ::android::hardware::media::bufferpool::BufferPoolData;
+using ::android::hardware::media::bufferpool::V2_0::BufferStatusMessage;
+using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        ClientManager;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        TransactionId;
+
+const char* asString(Status status, const char* def) {
+    return asString(static_cast<c2_status_t>(status), def);
+}
+
+namespace /* unnamed */ {
+
+template <typename EnumClass>
+typename std::underlying_type<EnumClass>::type underlying_value(
+        EnumClass x) {
+    return static_cast<typename std::underlying_type<EnumClass>::type>(x);
+}
+
+template <typename Common, typename DstVector, typename SrcVector>
+void copyVector(DstVector* d, const SrcVector& s) {
+    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
+            "DstVector's component size does not match Common");
+    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
+            "SrcVector's component size does not match Common");
+    d->resize(s.size());
+    std::copy(
+            reinterpret_cast<const Common*>(&s[0]),
+            reinterpret_cast<const Common*>(&s[0] + s.size()),
+            reinterpret_cast<Common*>(&(*d)[0]));
+}
+
+// C2ParamField -> ParamField
+bool objcpy(ParamField *d, const C2ParamField &s) {
+    d->index = static_cast<ParamIndex>(_C2ParamInspector::GetIndex(s));
+    d->fieldId.offset = static_cast<uint32_t>(_C2ParamInspector::GetOffset(s));
+    d->fieldId.size = static_cast<uint32_t>(_C2ParamInspector::GetSize(s));
+    return true;
+}
+
+struct C2ParamFieldBuilder : public C2ParamField {
+    C2ParamFieldBuilder() : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
+    }
+    // ParamField -> C2ParamField
+    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
+            static_cast<uint32_t>(s.fieldId.offset),
+            static_cast<uint32_t>(s.fieldId.size)) {
+    }
+};
+
+// C2WorkOrdinalStruct -> WorkOrdinal
+bool objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
+    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
+    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
+    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
+    return true;
+}
+
+// WorkOrdinal -> C2WorkOrdinalStruct
+bool objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
+    d->frameIndex = c2_cntr64_t(s.frameIndex);
+    d->timestamp = c2_cntr64_t(s.timestampUs);
+    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
+    return true;
+}
+
+// C2FieldSupportedValues::range's type -> ValueRange
+bool objcpy(
+        ValueRange* d,
+        const decltype(C2FieldSupportedValues::range)& s) {
+    d->min = static_cast<PrimitiveValue>(s.min.u64);
+    d->max = static_cast<PrimitiveValue>(s.max.u64);
+    d->step = static_cast<PrimitiveValue>(s.step.u64);
+    d->num = static_cast<PrimitiveValue>(s.num.u64);
+    d->denom = static_cast<PrimitiveValue>(s.denom.u64);
+    return true;
+}
+
+// C2FieldSupportedValues -> FieldSupportedValues
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
+    switch (s.type) {
+    case C2FieldSupportedValues::EMPTY: {
+            d->empty(::android::hidl::safe_union::V1_0::Monostate{});
+            break;
+        }
+    case C2FieldSupportedValues::RANGE: {
+            ValueRange range{};
+            if (!objcpy(&range, s.range)) {
+                LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
+                d->range(range);
+                return false;
+            }
+            d->range(range);
+            break;
+        }
+    case C2FieldSupportedValues::VALUES: {
+            hidl_vec<PrimitiveValue> values;
+            copyVector<uint64_t>(&values, s.values);
+            d->values(values);
+            break;
+        }
+    case C2FieldSupportedValues::FLAGS: {
+            hidl_vec<PrimitiveValue> flags;
+            copyVector<uint64_t>(&flags, s.values);
+            d->flags(flags);
+            break;
+        }
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValues::type_t "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        return false;
+    }
+    return true;
+}
+
+// ValueRange -> C2FieldSupportedValues::range's type
+bool objcpy(
+        decltype(C2FieldSupportedValues::range)* d,
+        const ValueRange& s) {
+    d->min.u64 = static_cast<uint64_t>(s.min);
+    d->max.u64 = static_cast<uint64_t>(s.max);
+    d->step.u64 = static_cast<uint64_t>(s.step);
+    d->num.u64 = static_cast<uint64_t>(s.num);
+    d->denom.u64 = static_cast<uint64_t>(s.denom);
+    return true;
+}
+
+// FieldSupportedValues -> C2FieldSupportedValues
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
+    switch (s.getDiscriminator()) {
+    case FieldSupportedValues::hidl_discriminator::empty: {
+            d->type = C2FieldSupportedValues::EMPTY;
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::range: {
+            d->type = C2FieldSupportedValues::RANGE;
+            if (!objcpy(&d->range, s.range())) {
+                LOG(ERROR) << "Invalid FieldSupportedValues::range.";
+                return false;
+            }
+            d->values.resize(0);
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::values: {
+            d->type = C2FieldSupportedValues::VALUES;
+            copyVector<uint64_t>(&d->values, s.values());
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::flags: {
+            d->type = C2FieldSupportedValues::FLAGS;
+            copyVector<uint64_t>(&d->values, s.flags());
+            break;
+        }
+    default:
+        LOG(WARNING) << "Unrecognized FieldSupportedValues::getDiscriminator()";
+        return false;
+    }
+    return true;
+}
+
+} // unnamed namespace
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool objcpy(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s) {
+    if (!objcpy(&d->field, s.field())) {
+        LOG(ERROR) << "Invalid C2FieldSupportedValuesQuery::field.";
+        return false;
+    }
+    switch (s.type()) {
+    case C2FieldSupportedValuesQuery::POSSIBLE:
+        d->type = FieldSupportedValuesQuery::Type::POSSIBLE;
+        break;
+    case C2FieldSupportedValuesQuery::CURRENT:
+        d->type = FieldSupportedValuesQuery::Type::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValuesQuery::type_t "
+                   << "with underlying value " << underlying_value(s.type())
+                   << ".";
+        d->type = static_cast<FieldSupportedValuesQuery::Type>(s.type());
+    }
+    return true;
+}
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s) {
+    C2FieldSupportedValuesQuery::type_t dType;
+    switch (s.type) {
+    case FieldSupportedValuesQuery::Type::POSSIBLE:
+        dType = C2FieldSupportedValuesQuery::POSSIBLE;
+        break;
+    case FieldSupportedValuesQuery::Type::CURRENT:
+        dType = C2FieldSupportedValuesQuery::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized FieldSupportedValuesQuery::Type "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        dType = static_cast<C2FieldSupportedValuesQuery::type_t>(s.type);
+    }
+    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
+    return true;
+}
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool objcpy(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s) {
+    d->status = static_cast<Status>(s.status);
+    return objcpy(&d->values, s.values);
+}
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
+// C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr) {
+    if (!objcpy(d, sq)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQuery.";
+        return false;
+    }
+    d->status = static_cast<c2_status_t>(sr.status);
+    if (!objcpy(&d->values, sr.values)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQueryResult::values.";
+        return false;
+    }
+    return true;
+}
+
+// C2Component::Traits -> IComponentStore::ComponentTraits
+bool objcpy(
+        IComponentStore::ComponentTraits *d,
+        const C2Component::Traits &s) {
+    d->name = s.name;
+
+    switch (s.domain) {
+    case C2Component::DOMAIN_VIDEO:
+        d->domain = IComponentStore::ComponentTraits::Domain::VIDEO;
+        break;
+    case C2Component::DOMAIN_AUDIO:
+        d->domain = IComponentStore::ComponentTraits::Domain::AUDIO;
+        break;
+    case C2Component::DOMAIN_IMAGE:
+        d->domain = IComponentStore::ComponentTraits::Domain::IMAGE;
+        break;
+    case C2Component::DOMAIN_OTHER:
+        d->domain = IComponentStore::ComponentTraits::Domain::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::domain_t "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<IComponentStore::ComponentTraits::Domain>(
+                s.domain);
+    }
+
+    switch (s.kind) {
+    case C2Component::KIND_DECODER:
+        d->kind = IComponentStore::ComponentTraits::Kind::DECODER;
+        break;
+    case C2Component::KIND_ENCODER:
+        d->kind = IComponentStore::ComponentTraits::Kind::ENCODER;
+        break;
+    case C2Component::KIND_OTHER:
+        d->kind = IComponentStore::ComponentTraits::Kind::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::kind_t "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<IComponentStore::ComponentTraits::Kind>(
+                s.kind);
+    }
+
+    d->rank = static_cast<uint32_t>(s.rank);
+
+    d->mediaType = s.mediaType;
+
+    d->aliases.resize(s.aliases.size());
+    for (size_t ix = s.aliases.size(); ix > 0; ) {
+        --ix;
+        d->aliases[ix] = s.aliases[ix];
+    }
+    return true;
+}
+
+// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
+bool objcpy(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s) {
+    d->name = s.name.c_str();
+
+    switch (s.domain) {
+    case IComponentStore::ComponentTraits::Domain::VIDEO:
+        d->domain = C2Component::DOMAIN_VIDEO;
+        break;
+    case IComponentStore::ComponentTraits::Domain::AUDIO:
+        d->domain = C2Component::DOMAIN_AUDIO;
+        break;
+    case IComponentStore::ComponentTraits::Domain::IMAGE:
+        d->domain = C2Component::DOMAIN_IMAGE;
+        break;
+    case IComponentStore::ComponentTraits::Domain::OTHER:
+        d->domain = C2Component::DOMAIN_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Domain "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<C2Component::domain_t>(s.domain);
+    }
+
+    switch (s.kind) {
+    case IComponentStore::ComponentTraits::Kind::DECODER:
+        d->kind = C2Component::KIND_DECODER;
+        break;
+    case IComponentStore::ComponentTraits::Kind::ENCODER:
+        d->kind = C2Component::KIND_ENCODER;
+        break;
+    case IComponentStore::ComponentTraits::Kind::OTHER:
+        d->kind = C2Component::KIND_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Kind "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<C2Component::kind_t>(s.kind);
+    }
+
+    d->rank = static_cast<C2Component::rank_t>(s.rank);
+    d->mediaType = s.mediaType.c_str();
+    d->aliases.resize(s.aliases.size());
+    for (size_t i = 0; i < s.aliases.size(); ++i) {
+        d->aliases[i] = s.aliases[i];
+    }
+    return true;
+}
+
+namespace /* unnamed */ {
+
+// C2ParamFieldValues -> ParamFieldValues
+bool objcpy(ParamFieldValues *d, const C2ParamFieldValues &s) {
+    if (!objcpy(&d->paramOrField, s.paramOrField)) {
+        LOG(ERROR) << "Invalid C2ParamFieldValues::paramOrField.";
+        return false;
+    }
+    if (s.values) {
+        d->values.resize(1);
+        if (!objcpy(&d->values[0], *s.values)) {
+            LOG(ERROR) << "Invalid C2ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    }
+    d->values.resize(0);
+    return true;
+}
+
+// ParamFieldValues -> C2ParamFieldValues
+bool objcpy(C2ParamFieldValues *d, const ParamFieldValues &s) {
+    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
+    if (s.values.size() == 1) {
+        d->values = std::make_unique<C2FieldSupportedValues>();
+        if (!objcpy(d->values.get(), s.values[0])) {
+            LOG(ERROR) << "Invalid ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    } else if (s.values.size() == 0) {
+        d->values.reset();
+        return true;
+    }
+    LOG(ERROR) << "Invalid ParamFieldValues: "
+                  "Two or more FieldSupportedValues objects exist in "
+                  "ParamFieldValues. "
+                  "Only zero or one is allowed.";
+    return false;
+}
+
+} // unnamed namespace
+
+// C2SettingResult -> SettingResult
+bool objcpy(SettingResult *d, const C2SettingResult &s) {
+    switch (s.failure) {
+    case C2SettingResult::BAD_TYPE:
+        d->failure = SettingResult::Failure::BAD_TYPE;
+        break;
+    case C2SettingResult::BAD_PORT:
+        d->failure = SettingResult::Failure::BAD_PORT;
+        break;
+    case C2SettingResult::BAD_INDEX:
+        d->failure = SettingResult::Failure::BAD_INDEX;
+        break;
+    case C2SettingResult::READ_ONLY:
+        d->failure = SettingResult::Failure::READ_ONLY;
+        break;
+    case C2SettingResult::MISMATCH:
+        d->failure = SettingResult::Failure::MISMATCH;
+        break;
+    case C2SettingResult::BAD_VALUE:
+        d->failure = SettingResult::Failure::BAD_VALUE;
+        break;
+    case C2SettingResult::CONFLICT:
+        d->failure = SettingResult::Failure::CONFLICT;
+        break;
+    case C2SettingResult::UNSUPPORTED:
+        d->failure = SettingResult::Failure::UNSUPPORTED;
+        break;
+    case C2SettingResult::INFO_BAD_VALUE:
+        d->failure = SettingResult::Failure::INFO_BAD_VALUE;
+        break;
+    case C2SettingResult::INFO_CONFLICT:
+        d->failure = SettingResult::Failure::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        d->failure = static_cast<SettingResult::Failure>(s.failure);
+    }
+    if (!objcpy(&d->field, s.field)) {
+        LOG(ERROR) << "Invalid C2SettingResult::field.";
+        return false;
+    }
+    d->conflicts.resize(s.conflicts.size());
+    size_t i = 0;
+    for (const C2ParamFieldValues& sConflict : s.conflicts) {
+        ParamFieldValues &dConflict = d->conflicts[i++];
+        if (!objcpy(&dConflict, sConflict)) {
+            LOG(ERROR) << "Invalid C2SettingResult::conflicts["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+    return true;
+}
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool objcpy(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
+    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
+            .field = C2ParamFieldValues(C2ParamFieldBuilder()) });
+    if (!*d) {
+        LOG(ERROR) << "No memory for C2SettingResult.";
+        return false;
+    }
+
+    // failure
+    switch (s.failure) {
+    case SettingResult::Failure::BAD_TYPE:
+        (*d)->failure = C2SettingResult::BAD_TYPE;
+        break;
+    case SettingResult::Failure::BAD_PORT:
+        (*d)->failure = C2SettingResult::BAD_PORT;
+        break;
+    case SettingResult::Failure::BAD_INDEX:
+        (*d)->failure = C2SettingResult::BAD_INDEX;
+        break;
+    case SettingResult::Failure::READ_ONLY:
+        (*d)->failure = C2SettingResult::READ_ONLY;
+        break;
+    case SettingResult::Failure::MISMATCH:
+        (*d)->failure = C2SettingResult::MISMATCH;
+        break;
+    case SettingResult::Failure::BAD_VALUE:
+        (*d)->failure = C2SettingResult::BAD_VALUE;
+        break;
+    case SettingResult::Failure::CONFLICT:
+        (*d)->failure = C2SettingResult::CONFLICT;
+        break;
+    case SettingResult::Failure::UNSUPPORTED:
+        (*d)->failure = C2SettingResult::UNSUPPORTED;
+        break;
+    case SettingResult::Failure::INFO_BAD_VALUE:
+        (*d)->failure = C2SettingResult::INFO_BAD_VALUE;
+        break;
+    case SettingResult::Failure::INFO_CONFLICT:
+        (*d)->failure = C2SettingResult::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failure);
+    }
+
+    // field
+    if (!objcpy(&(*d)->field, s.field)) {
+        LOG(ERROR) << "Invalid SettingResult::field.";
+        return false;
+    }
+
+    // conflicts
+    (*d)->conflicts.clear();
+    (*d)->conflicts.reserve(s.conflicts.size());
+    for (const ParamFieldValues& sConflict : s.conflicts) {
+        (*d)->conflicts.emplace_back(
+                C2ParamFieldValues{ C2ParamFieldBuilder(), nullptr });
+        if (!objcpy(&(*d)->conflicts.back(), sConflict)) {
+            LOG(ERROR) << "Invalid SettingResult::conflicts.";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2ParamDescriptor -> ParamDescriptor
+bool objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
+    d->index = static_cast<ParamIndex>(s.index());
+    d->attrib = static_cast<hidl_bitfield<ParamDescriptor::Attrib>>(
+            _C2ParamInspector::GetAttrib(s));
+    d->name = s.name();
+    copyVector<uint32_t>(&d->dependencies, s.dependencies());
+    return true;
+}
+
+// ParamDescriptor -> C2ParamDescriptor
+bool objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
+    std::vector<C2Param::Index> dDependencies;
+    dDependencies.reserve(s.dependencies.size());
+    for (const ParamIndex& sDependency : s.dependencies) {
+        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
+    }
+    *d = std::make_shared<C2ParamDescriptor>(
+            C2Param::Index(static_cast<uint32_t>(s.index)),
+            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
+            C2String(s.name.c_str()),
+            std::move(dDependencies));
+    return true;
+}
+
+// C2StructDescriptor -> StructDescriptor
+bool objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
+    d->type = static_cast<ParamIndex>(s.coreIndex().coreIndex());
+    d->fields.resize(s.numFields());
+    size_t i = 0;
+    for (const auto& sField : s) {
+        FieldDescriptor& dField = d->fields[i++];
+        dField.fieldId.offset = static_cast<uint32_t>(
+                _C2ParamInspector::GetOffset(sField));
+        dField.fieldId.size = static_cast<uint32_t>(
+                _C2ParamInspector::GetSize(sField));
+        dField.type = static_cast<hidl_bitfield<FieldDescriptor::Type>>(
+                sField.type());
+        dField.extent = static_cast<uint32_t>(sField.extent());
+        dField.name = static_cast<hidl_string>(sField.name());
+        const auto& sNamedValues = sField.namedValues();
+        dField.namedValues.resize(sNamedValues.size());
+        size_t j = 0;
+        for (const auto& sNamedValue : sNamedValues) {
+            FieldDescriptor::NamedValue& dNamedValue = dField.namedValues[j++];
+            dNamedValue.name = static_cast<hidl_string>(sNamedValue.first);
+            dNamedValue.value = static_cast<PrimitiveValue>(
+                    sNamedValue.second.u64);
+        }
+    }
+    return true;
+}
+
+// StructDescriptor -> C2StructDescriptor
+bool objcpy(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
+    C2Param::CoreIndex dIndex = C2Param::CoreIndex(static_cast<uint32_t>(s.type));
+    std::vector<C2FieldDescriptor> dFields;
+    dFields.reserve(s.fields.size());
+    for (const auto &sField : s.fields) {
+        C2FieldDescriptor dField = {
+            static_cast<uint32_t>(sField.type),
+            sField.extent,
+            sField.name,
+            sField.fieldId.offset,
+            sField.fieldId.size };
+        C2FieldDescriptor::NamedValuesType namedValues;
+        namedValues.reserve(sField.namedValues.size());
+        for (const auto& sNamedValue : sField.namedValues) {
+            namedValues.emplace_back(
+                sNamedValue.name,
+                C2Value::Primitive(static_cast<uint64_t>(sNamedValue.value)));
+        }
+        _C2ParamInspector::AddNamedValues(dField, std::move(namedValues));
+        dFields.emplace_back(dField);
+    }
+    *d = std::make_unique<C2StructDescriptor>(
+            _C2ParamInspector::CreateStructDescriptor(dIndex, std::move(dFields)));
+    return true;
+}
+
+namespace /* unnamed */ {
+
+// Find or add a hidl BaseBlock object from a given C2Handle* to a list and an
+// associated map.
+// Note: The handle is not cloned.
+bool _addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!handle) {
+        LOG(ERROR) << "addBaseBlock called on a null C2Handle.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(handle);
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(handle, *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+        // This does not clone the handle.
+        dBaseBlock.nativeBlock(
+                reinterpret_cast<const native_handle_t*>(handle));
+
+    }
+    return true;
+}
+
+// Find or add a hidl BaseBlock object from a given BufferPoolData to a list and
+// an associated map.
+bool _addBaseBlock(
+        uint32_t* index,
+        const std::shared_ptr<BufferPoolData> bpData,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!bpData) {
+        LOG(ERROR) << "addBaseBlock called on a null BufferPoolData.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(bpData.get());
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(bpData.get(), *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+
+        if (bufferPoolSender) {
+            BufferStatusMessage pooledBlock;
+            ResultStatus bpStatus = bufferPoolSender->send(
+                    bpData,
+                    &pooledBlock);
+
+            if (bpStatus != ResultStatus::OK) {
+                LOG(ERROR) << "Failed to send buffer with BufferPool. Error: "
+                           << static_cast<int32_t>(bpStatus)
+                           << ".";
+                return false;
+            }
+            dBaseBlock.pooledBlock(pooledBlock);
+        }
+    }
+    return true;
+}
+
+bool addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!blockPoolData) {
+        // No BufferPoolData ==> NATIVE block.
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    }
+    switch (blockPoolData->getType()) {
+    case _C2BlockPoolData::TYPE_BUFFERPOOL: {
+            // BufferPoolData
+            std::shared_ptr<BufferPoolData> bpData;
+            if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData)
+                    || !bpData) {
+                LOG(ERROR) << "BufferPoolData unavailable in a block.";
+                return false;
+            }
+            return _addBaseBlock(
+                    index, bpData,
+                    bufferPoolSender, baseBlocks, baseBlockIndices);
+        }
+    case _C2BlockPoolData::TYPE_BUFFERQUEUE:
+        uint32_t gen;
+        uint64_t bqId;
+        int32_t bqSlot;
+        // Update handle if migration happened.
+        if (_C2BlockFactory::GetBufferQueueData(
+                blockPoolData, &gen, &bqId, &bqSlot)) {
+            android::MigrateNativeCodec2GrallocHandle(
+                    const_cast<native_handle_t*>(handle), gen, bqId, bqSlot);
+        }
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    default:
+        LOG(ERROR) << "Unknown C2BlockPoolData type.";
+        return false;
+    }
+}
+
+// C2Fence -> hidl_handle
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+bool objcpy(hidl_handle* d, const C2Fence& s) {
+    d->setTo(nullptr);
+    native_handle_t* handle = _C2FenceFactory::CreateNativeHandle(s);
+    if (handle) {
+        d->setTo(handle, true /* owns */);
+//  } else if (!s.ready()) {
+//      // TODO: we should wait for unmarshallable fences but this may not be
+//      // the best place for it. We can safely ignore here as at this time
+//      // all fences used here are marshallable.
+    }
+    return true;
+}
+
+// C2ConstLinearBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+bool objcpy(Block* d, const C2ConstLinearBlock& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetLinearBlockPoolData(s);
+    if (!addBaseBlock(&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hidl_RangeInfo dRangeInfo;
+    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
+    dRangeInfo.length = static_cast<uint32_t>(s.size());
+    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRangeInfo })) {
+        LOG(ERROR) << "Invalid range info in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstLinearBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2ConstGraphicBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+bool objcpy(Block* d, const C2ConstGraphicBlock& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetGraphicBlockPoolData(s);
+    if (!addBaseBlock(&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hidl_RectInfo dRectInfo;
+    C2Rect sRect = s.crop();
+    dRectInfo.left = static_cast<uint32_t>(sRect.left);
+    dRectInfo.top = static_cast<uint32_t>(sRect.top);
+    dRectInfo.width = static_cast<uint32_t>(sRect.width);
+    dRectInfo.height = static_cast<uint32_t>(sRect.height);
+    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRectInfo })) {
+        LOG(ERROR) << "Invalid rect info in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstGraphicBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2BufferData -> Buffer
+// This function only fills in d->blocks.
+bool objcpy(Buffer* d, const C2BufferData& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->blocks.resize(
+            s.linearBlocks().size() +
+            s.graphicBlocks().size());
+    size_t i = 0;
+    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
+        Block& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, linearBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::linearBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
+        Block& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, graphicBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::graphicBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2Buffer -> Buffer
+bool objcpy(Buffer* d, const C2Buffer& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!createParamsBlob(&d->info, s.info())) {
+        LOG(ERROR) << "Invalid C2Buffer::info.";
+        return false;
+    }
+    if (!objcpy(d, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2Buffer::data.";
+        return false;
+    }
+    return true;
+}
+
+// C2InfoBuffer -> InfoBuffer
+bool objcpy(InfoBuffer* d, const C2InfoBuffer& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->index = static_cast<ParamIndex>(s.index());
+    Buffer& dBuffer = d->buffer;
+    if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2InfoBuffer::data";
+        return false;
+    }
+    return true;
+}
+
+// C2FrameData -> FrameData
+bool objcpy(FrameData* d, const C2FrameData& s,
+        BufferPoolSender* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->flags = static_cast<hidl_bitfield<FrameData::Flags>>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid C2FrameData::ordinal.";
+        return false;
+    }
+
+    d->buffers.resize(s.buffers.size());
+    size_t i = 0;
+    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
+        Buffer& dBuffer = d->buffers[i++];
+        if (!sBuffer) {
+            // A null (pointer to) C2Buffer corresponds to a Buffer with empty
+            // info and blocks.
+            dBuffer.info.resize(0);
+            dBuffer.blocks.resize(0);
+            continue;
+        }
+        if (!objcpy(
+                &dBuffer, *sBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::buffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    if (!createParamsBlob(&d->configUpdate, s.configUpdate)) {
+        LOG(ERROR) << "Invalid C2FrameData::configUpdate.";
+        return false;
+    }
+
+    d->infoBuffers.resize(s.infoBuffers.size());
+    i = 0;
+    for (const C2InfoBuffer& sInfoBuffer : s.infoBuffers) {
+        InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
+        if (!objcpy(&dInfoBuffer, sInfoBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+} // unnamed namespace
+
+// DefaultBufferPoolSender's implementation
+
+DefaultBufferPoolSender::DefaultBufferPoolSender(
+        const sp<IClientManager>& receiverManager,
+        std::chrono::steady_clock::duration refreshInterval)
+    : mReceiverManager(receiverManager),
+      mRefreshInterval(refreshInterval) {
+}
+
+void DefaultBufferPoolSender::setReceiver(
+        const sp<IClientManager>& receiverManager,
+        std::chrono::steady_clock::duration refreshInterval) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (mReceiverManager != receiverManager) {
+        mReceiverManager = receiverManager;
+        mConnections.clear();
+    }
+    mRefreshInterval = refreshInterval;
+}
+
+ResultStatus DefaultBufferPoolSender::send(
+        const std::shared_ptr<BufferPoolData>& bpData,
+        BufferStatusMessage* bpMessage) {
+    int64_t connectionId = bpData->mConnectionId;
+    if (connectionId == 0) {
+        LOG(WARNING) << "registerSender -- invalid sender connection id (0).";
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (!mReceiverManager) {
+        LOG(ERROR) << "No access to receiver's BufferPool.";
+        return ResultStatus::NOT_FOUND;
+    }
+    if (!mSenderManager) {
+        mSenderManager = ClientManager::getInstance();
+        if (!mSenderManager) {
+            LOG(ERROR) << "Failed to retrieve local BufferPool ClientManager.";
+            return ResultStatus::CRITICAL_ERROR;
+        }
+    }
+
+    int64_t receiverConnectionId{0};
+    auto foundConnection = mConnections.find(connectionId);
+    bool isNewConnection = foundConnection == mConnections.end();
+    std::chrono::steady_clock::time_point now =
+            std::chrono::steady_clock::now();
+    if (isNewConnection ||
+            (now - foundConnection->second.lastSent > mRefreshInterval)) {
+        // Initialize the bufferpool connection.
+        ResultStatus rs =
+                mSenderManager->registerSender(mReceiverManager,
+                                               connectionId,
+                                               &receiverConnectionId);
+        if ((rs != ResultStatus::OK) && (rs != ResultStatus::ALREADY_EXISTS)) {
+            LOG(WARNING) << "registerSender -- returned error: "
+                         << static_cast<int32_t>(rs)
+                         << ".";
+            return rs;
+        } else if (receiverConnectionId == 0) {
+            LOG(WARNING) << "registerSender -- "
+                            "invalid receiver connection id (0).";
+            return ResultStatus::CRITICAL_ERROR;
+        } else {
+            if (isNewConnection) {
+                foundConnection = mConnections.try_emplace(
+                        connectionId, receiverConnectionId, now).first;
+            } else {
+                foundConnection->second.receiverConnectionId = receiverConnectionId;
+            }
+        }
+    } else {
+        receiverConnectionId = foundConnection->second.receiverConnectionId;
+    }
+
+    uint64_t transactionId;
+    int64_t timestampUs;
+    ResultStatus rs = mSenderManager->postSend(
+            receiverConnectionId, bpData, &transactionId, &timestampUs);
+    if (rs != ResultStatus::OK) {
+        LOG(ERROR) << "ClientManager::postSend -- returned error: "
+                   << static_cast<int32_t>(rs)
+                   << ".";
+        mConnections.erase(foundConnection);
+        return rs;
+    }
+    if (!bpMessage) {
+        LOG(ERROR) << "Null output parameter for BufferStatusMessage.";
+        mConnections.erase(foundConnection);
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    bpMessage->connectionId = receiverConnectionId;
+    bpMessage->bufferId = bpData->mId;
+    bpMessage->transactionId = transactionId;
+    bpMessage->timestampUs = timestampUs;
+    foundConnection->second.lastSent = now;
+    return rs;
+}
+
+// std::list<std::unique_ptr<C2Work>> -> WorkBundle
+bool objcpy(
+        WorkBundle* d,
+        const std::list<std::unique_ptr<C2Work>>& s,
+        BufferPoolSender* bufferPoolSender) {
+    // baseBlocks holds a list of BaseBlock objects that Blocks can refer to.
+    std::list<BaseBlock> baseBlocks;
+
+    // baseBlockIndices maps a raw pointer to native_handle_t or BufferPoolData
+    // inside baseBlocks to the corresponding index into baseBlocks. The keys
+    // (pointers) are used to identify blocks that have the same "base block" in
+    // s, a list of C2Work objects. Because baseBlocks will be copied into a
+    // hidl_vec eventually, the values of baseBlockIndices are zero-based
+    // integer indices instead of list iterators.
+    //
+    // Note that the pointers can be raw because baseBlockIndices has a shorter
+    // lifespan than all of base blocks.
+    std::map<const void*, uint32_t> baseBlockIndices;
+
+    d->works.resize(s.size());
+    size_t i = 0;
+    for (const std::unique_ptr<C2Work>& sWork : s) {
+        Work &dWork = d->works[i++];
+        if (!sWork) {
+            LOG(WARNING) << "Null C2Work encountered.";
+            continue;
+        }
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork->input,
+                bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2Work::input.";
+            return false;
+        }
+
+        // worklets
+        if (sWork->worklets.size() == 0) {
+            LOG(DEBUG) << "Work with no worklets.";
+        } else {
+            // Parcel the worklets.
+            hidl_vec<Worklet> &dWorklets = dWork.worklets;
+            dWorklets.resize(sWork->worklets.size());
+            size_t j = 0;
+            for (const std::unique_ptr<C2Worklet>& sWorklet : sWork->worklets)
+            {
+                if (!sWorklet) {
+                    LOG(WARNING) << "Null C2Work::worklets["
+                                 << j << "].";
+                    continue;
+                }
+                Worklet &dWorklet = dWorklets[j++];
+
+                // component id
+                dWorklet.componentId = static_cast<uint32_t>(
+                        sWorklet->component);
+
+                // tunings
+                if (!createParamsBlob(&dWorklet.tunings, sWorklet->tunings)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->tunings.";
+                    return false;
+                }
+
+                // failures
+                dWorklet.failures.resize(sWorklet->failures.size());
+                size_t k = 0;
+                for (const std::unique_ptr<C2SettingResult>& sFailure :
+                        sWorklet->failures) {
+                    if (!sFailure) {
+                        LOG(WARNING) << "Null C2Work::worklets["
+                                     << j - 1 << "]->failures["
+                                     << k << "].";
+                        continue;
+                    }
+                    if (!objcpy(&dWorklet.failures[k++], *sFailure)) {
+                        LOG(ERROR) << "Invalid C2Work::worklets["
+                                   << j - 1 << "]->failures["
+                                   << k - 1 << "].";
+                        return false;
+                    }
+                }
+
+                // output
+                if (!objcpy(&dWorklet.output, sWorklet->output,
+                        bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->output.";
+                    return false;
+                }
+            }
+        }
+
+        // worklets processed
+        dWork.workletsProcessed = sWork->workletsProcessed;
+
+        // result
+        dWork.result = static_cast<Status>(sWork->result);
+    }
+
+    // Copy std::list<BaseBlock> to hidl_vec<BaseBlock>.
+    {
+        d->baseBlocks.resize(baseBlocks.size());
+        size_t i = 0;
+        for (const BaseBlock& baseBlock : baseBlocks) {
+            d->baseBlocks[i++] = baseBlock;
+        }
+    }
+
+    return true;
+}
+
+namespace /* unnamed */ {
+
+struct C2BaseBlock {
+    enum type_t {
+        LINEAR,
+        GRAPHIC,
+    };
+    type_t type;
+    std::shared_ptr<C2LinearBlock> linear;
+    std::shared_ptr<C2GraphicBlock> graphic;
+};
+
+// hidl_handle -> C2Fence
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+bool objcpy(C2Fence* d, const hidl_handle& s) {
+    const native_handle_t* handle = s.getNativeHandle();
+    *d = _C2FenceFactory::CreateFromNativeHandle(handle);
+    return true;
+}
+
+// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool createLinearBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2LinearBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hidl_RangeInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2LinearBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hidl_RangeInfo)) {
+        LOG(ERROR) << "Invalid range info in C2LinearBlock.";
+        return false;
+    }
+    C2Hidl_RangeInfo *rangeInfo =
+            reinterpret_cast<C2Hidl_RangeInfo*>(meta[0]);
+
+    // Create C2Buffer from C2LinearBlock.
+    *buffer = C2Buffer::CreateLinearBuffer(block->share(
+            rangeInfo->offset, rangeInfo->length,
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateLinearBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool createGraphicBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2GraphicBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hidl_RectInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hidl_RectInfo)) {
+        LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
+        return false;
+    }
+    C2Hidl_RectInfo *rectInfo =
+            reinterpret_cast<C2Hidl_RectInfo*>(meta[0]);
+
+    // Create C2Buffer from C2GraphicBlock.
+    *buffer = C2Buffer::CreateGraphicBuffer(block->share(
+            C2Rect(rectInfo->width, rectInfo->height).
+            at(rectInfo->left, rectInfo->top),
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateGraphicBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+// Buffer -> C2Buffer
+// Note: The native handles will be cloned.
+bool objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    *d = nullptr;
+
+    // Currently, a non-null C2Buffer must contain exactly 1 block.
+    if (s.blocks.size() == 0) {
+        return true;
+    } else if (s.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid Buffer: "
+                      "Currently, a C2Buffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const Block &sBlock = s.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (!createLinearBuffer(d, baseBlock.linear, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::linear.";
+            return false;
+        }
+        break;
+    case C2BaseBlock::GRAPHIC:
+        if (!createGraphicBuffer(d, baseBlock.graphic, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::graphic.";
+            return false;
+        }
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type.";
+        return false;
+    }
+
+    // Parse info
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.info)) {
+        LOG(ERROR) << "Invalid Buffer::info.";
+        return false;
+    }
+    for (C2Param* param : params) {
+        if (param == nullptr) {
+            LOG(ERROR) << "Null param in Buffer::info.";
+            return false;
+        }
+        std::shared_ptr<C2Param> c2param{
+                C2Param::Copy(*param).release()};
+        if (!c2param) {
+            LOG(ERROR) << "Invalid param in Buffer::info.";
+            return false;
+        }
+        c2_status_t status =
+                (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
+        if (status != C2_OK) {
+            LOG(ERROR) << "C2Buffer::setInfo failed.";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// InfoBuffer -> C2InfoBuffer
+bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+
+    // Currently, a non-null C2InfoBufer must contain exactly 1 block.
+    if (s.buffer.blocks.size() == 0) {
+        return true;
+    } else if (s.buffer.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer "
+                      "Currently, a C2InfoBuffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const Block &sBlock = s.buffer.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
+            sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
+            C2Hidl_RangeInfo *rangeInfo =
+                    reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
+            d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
+                    s.index,
+                    baseBlock.linear->share(
+                            rangeInfo->offset, rangeInfo->length, dFence)));
+            return true;
+        }
+        LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
+        break;
+    case C2BaseBlock::GRAPHIC:
+        // It's not used now
+        LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
+        break;
+    }
+
+    return false;
+}
+
+// FrameData -> C2FrameData
+bool objcpy(C2FrameData* d, const FrameData& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid FrameData::ordinal.";
+        return false;
+    }
+    d->buffers.clear();
+    d->buffers.reserve(s.buffers.size());
+    for (const Buffer& sBuffer : s.buffers) {
+        std::shared_ptr<C2Buffer> dBuffer;
+        if (!objcpy(&dBuffer, sBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid FrameData::buffers.";
+            return false;
+        }
+        d->buffers.emplace_back(dBuffer);
+    }
+
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.configUpdate)) {
+        LOG(ERROR) << "Invalid FrameData::configUpdate.";
+        return false;
+    }
+    d->configUpdate.clear();
+    for (C2Param* param : params) {
+        d->configUpdate.emplace_back(C2Param::Copy(*param));
+        if (!d->configUpdate.back()) {
+            LOG(ERROR) << "Unexpected error while parsing "
+                          "FrameData::configUpdate.";
+            return false;
+        }
+    }
+
+    d->infoBuffers.clear();
+    if (s.infoBuffers.size() == 0) {
+        // InfoBuffer is optional
+        return true;
+    }
+    d->infoBuffers.reserve(s.infoBuffers.size());
+    for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
+        if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid Framedata::infoBuffers.";
+            return false;
+        }
+    }
+    return true;
+}
+
+// BaseBlock -> C2BaseBlock
+bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
+    switch (s.getDiscriminator()) {
+    case BaseBlock::hidl_discriminator::nativeBlock: {
+            if (s.nativeBlock() == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
+                return false;
+            }
+            native_handle_t* sHandle =
+                    native_handle_clone(s.nativeBlock());
+            if (sHandle == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock.";
+                return false;
+            }
+            const C2Handle *sC2Handle =
+                    reinterpret_cast<const C2Handle*>(sHandle);
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(sC2Handle);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(sC2Handle);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::nativeBlock.";
+            if (sHandle) {
+                native_handle_close(sHandle);
+                native_handle_delete(sHandle);
+            }
+            return false;
+        }
+    case BaseBlock::hidl_discriminator::pooledBlock: {
+            const BufferStatusMessage &bpMessage =
+                    s.pooledBlock();
+            sp<ClientManager> bp = ClientManager::getInstance();
+            std::shared_ptr<BufferPoolData> bpData;
+            native_handle_t *cHandle;
+            ResultStatus bpStatus = bp->receive(
+                    bpMessage.connectionId,
+                    bpMessage.transactionId,
+                    bpMessage.bufferId,
+                    bpMessage.timestampUs,
+                    &cHandle,
+                    &bpData);
+            if (bpStatus != ResultStatus::OK) {
+                LOG(ERROR) << "Failed to receive buffer from bufferpool -- "
+                           << "resultStatus = " << underlying_value(bpStatus)
+                           << ".";
+                return false;
+            } else if (!bpData) {
+                LOG(ERROR) << "No data in bufferpool transaction.";
+                return false;
+            }
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(cHandle, bpData);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(cHandle, bpData);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+            if (cHandle) {
+                // Though we got cloned handle, creating block failed.
+                native_handle_close(cHandle);
+                native_handle_delete(cHandle);
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
+            return false;
+        }
+    default:
+        LOG(ERROR) << "Unrecognized BaseBlock's discriminator with "
+                   << "underlying value "
+                   << underlying_value(s.getDiscriminator()) << ".";
+        return false;
+    }
+}
+
+} // unnamed namespace
+
+// WorkBundle -> std::list<std::unique_ptr<C2Work>>
+bool objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
+    // Convert BaseBlocks to C2BaseBlocks.
+    std::vector<C2BaseBlock> dBaseBlocks(s.baseBlocks.size());
+    for (size_t i = 0; i < s.baseBlocks.size(); ++i) {
+        if (!objcpy(&dBaseBlocks[i], s.baseBlocks[i])) {
+            LOG(ERROR) << "Invalid WorkBundle::baseBlocks["
+                       << i << "].";
+            return false;
+        }
+    }
+
+    d->clear();
+    for (const Work& sWork : s.works) {
+        d->emplace_back(std::make_unique<C2Work>());
+        C2Work& dWork = *d->back();
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork.input, dBaseBlocks)) {
+            LOG(ERROR) << "Invalid Work::input.";
+            return false;
+        }
+
+        // worklet(s)
+        dWork.worklets.clear();
+        for (const Worklet& sWorklet : sWork.worklets) {
+            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
+
+            // component id
+            dWorklet->component = static_cast<c2_node_id_t>(
+                    sWorklet.componentId);
+
+            // tunings
+            if (!copyParamsFromBlob(&dWorklet->tunings, sWorklet.tunings)) {
+                LOG(ERROR) << "Invalid Worklet::tunings";
+                return false;
+            }
+
+            // failures
+            dWorklet->failures.clear();
+            dWorklet->failures.reserve(sWorklet.failures.size());
+            for (const SettingResult& sFailure : sWorklet.failures) {
+                std::unique_ptr<C2SettingResult> dFailure;
+                if (!objcpy(&dFailure, sFailure)) {
+                    LOG(ERROR) << "Invalid Worklet::failures.";
+                    return false;
+                }
+                dWorklet->failures.emplace_back(std::move(dFailure));
+            }
+
+            // output
+            if (!objcpy(&dWorklet->output, sWorklet.output, dBaseBlocks)) {
+                LOG(ERROR) << "Invalid Worklet::output.";
+                return false;
+            }
+
+            dWork.worklets.emplace_back(std::move(dWorklet));
+        }
+
+        // workletsProcessed
+        dWork.workletsProcessed = sWork.workletsProcessed;
+
+        // result
+        dWork.result = static_cast<c2_status_t>(sWork.result);
+    }
+
+    return true;
+}
+
+constexpr size_t PARAMS_ALIGNMENT = 8;  // 64-bit alignment
+static_assert(PARAMS_ALIGNMENT % alignof(C2Param) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Info) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Tuning) == 0, "C2Param alignment mismatch");
+
+// Params -> std::vector<C2Param*>
+bool parseParamsBlob(std::vector<C2Param*> *params, const hidl_vec<uint8_t> &blob) {
+    // assuming blob is const here
+    size_t size = blob.size();
+    size_t ix = 0;
+    size_t old_ix = 0;
+    const uint8_t *data = blob.data();
+    C2Param *p = nullptr;
+
+    do {
+        p = C2ParamUtils::ParseFirst(data + ix, size - ix);
+        if (p) {
+            params->emplace_back(p);
+            old_ix = ix;
+            ix += p->size();
+            ix = align(ix, PARAMS_ALIGNMENT);
+            if (ix <= old_ix || ix > size) {
+                android_errorWriteLog(0x534e4554, "238083570");
+                break;
+            }
+        }
+    } while (p);
+
+    if (ix != size) {
+        LOG(ERROR) << "parseParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+namespace /* unnamed */ {
+
+/**
+ * Concatenates a list of C2Params into a params blob. T is a container type
+ * whose member type is compatible with C2Param*.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval C2_OK if the blob was successfully created
+ * \retval C2_BAD_VALUE if the blob was not successful created (this only
+ *         happens if the parameters were not const)
+ */
+template <typename T>
+bool _createParamsBlob(hidl_vec<uint8_t> *blob, const T &params) {
+    // assuming the parameter values are const
+    size_t size = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        size += p->size();
+        size = align(size, PARAMS_ALIGNMENT);
+    }
+    blob->resize(size);
+    size_t ix = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        // NEVER overwrite even if param values (e.g. size) changed
+        size_t paramSize = std::min(p->size(), size - ix);
+        std::copy(
+                reinterpret_cast<const uint8_t*>(&*p),
+                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
+                &(*blob)[ix]);
+        ix += paramSize;
+        ix = align(ix, PARAMS_ALIGNMENT);
+    }
+    blob->resize(ix);
+    if (ix != size) {
+        LOG(ERROR) << "createParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Parses a params blob and create a vector of new T objects that contain copies
+ * of the params in the blob. T is C2Param or its compatible derived class.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval C2_OK if the full blob was parsed and params was constructed
+ * \retval C2_BAD_VALUE otherwise
+ */
+template <typename T>
+bool _copyParamsFromBlob(
+        std::vector<std::unique_ptr<T>>* params,
+        Params blob) {
+
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "copyParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    params->resize(paramPointers.size());
+    size_t i = 0;
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "copyParamsFromBlob -- null paramPointer.";
+            return false;
+        }
+        (*params)[i++].reset(reinterpret_cast<T*>(
+                C2Param::Copy(*paramPointer).release()));
+    }
+    return true;
+}
+
+} // unnamed namespace
+
+// std::vector<const C2Param*> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<const C2Param*> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<C2Param*> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<C2Param*> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Param>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Tuning>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// std::vector<std::shared_ptr<const C2Info>> -> Params
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params) {
+    return _createParamsBlob(blob, params);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Param>>
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        Params blob) {
+    return _copyParamsFromBlob(params, blob);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Tuning>>
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        Params blob) {
+    return _copyParamsFromBlob(params, blob);
+}
+
+// Params -> update std::vector<std::unique_ptr<C2Param>>
+bool updateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob) {
+    std::unordered_map<uint32_t, C2Param*> index2param;
+    for (C2Param* const& param : params) {
+        if (!param) {
+            LOG(ERROR) << "updateParamsFromBlob -- null output param.";
+            return false;
+        }
+        if (index2param.find(param->index()) == index2param.end()) {
+            index2param.emplace(param->index(), param);
+        }
+    }
+
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "updateParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "updateParamsFromBlob -- null input param.";
+            return false;
+        }
+        decltype(index2param)::iterator i = index2param.find(
+                paramPointer->index());
+        if (i == index2param.end()) {
+            LOG(DEBUG) << "updateParamsFromBlob -- index "
+                       << paramPointer->index() << " not found. Skipping...";
+            continue;
+        }
+        if (!i->second->updateFrom(*paramPointer)) {
+            LOG(ERROR) << "updateParamsFromBlob -- size mismatch: "
+                       << params.size() << " vs " << paramPointer->size()
+                       << " (index = " << i->first << ").";
+            return false;
+        }
+    }
+    return true;
+}
+
+// Convert BufferPool ResultStatus to c2_status_t.
+c2_status_t toC2Status(ResultStatus rs) {
+    switch (rs) {
+    case ResultStatus::OK:
+        return C2_OK;
+    case ResultStatus::NO_MEMORY:
+        return C2_NO_MEMORY;
+    case ResultStatus::ALREADY_EXISTS:
+        return C2_DUPLICATE;
+    case ResultStatus::NOT_FOUND:
+        return C2_NOT_FOUND;
+    case ResultStatus::CRITICAL_ERROR:
+        return C2_CORRUPTED;
+    default:
+        LOG(WARNING) << "Unrecognized BufferPool ResultStatus: "
+                     << static_cast<int32_t>(rs) << ".";
+        return C2_CORRUPTED;
+    }
+}
+
+namespace /* unnamed */ {
+
+template <typename BlockProcessor>
+void forEachBlock(C2FrameData& frameData,
+                  BlockProcessor process) {
+    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
+        if (buffer) {
+            for (const C2ConstGraphicBlock& block :
+                    buffer->data().graphicBlocks()) {
+                process(block);
+            }
+        }
+    }
+}
+
+template <typename BlockProcessor>
+void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
+                  BlockProcessor process,
+                  bool processInput, bool processOutput) {
+    for (const std::unique_ptr<C2Work>& work : workList) {
+        if (!work) {
+            continue;
+        }
+        if (processInput) {
+            forEachBlock(work->input, process);
+        }
+        if (processOutput) {
+            for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+                if (worklet) {
+                    forEachBlock(worklet->output,
+                                 process);
+                }
+            }
+        }
+    }
+}
+
+} // unnamed namespace
+
+bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::BeginTransferBlockToClient(data);
+        return true;
+    }
+    return false;
+}
+
+void beginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList, beginTransferBufferQueueBlock,
+                 processInput, processOutput);
+}
+
+bool endTransferBufferQueueBlock(
+        const C2ConstGraphicBlock& block,
+        bool transfer) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::EndTransferBlockToClient(data, transfer);
+        return true;
+    }
+    return false;
+}
+
+void endTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList,
+                 std::bind(endTransferBufferQueueBlock,
+                           std::placeholders::_1, transfer),
+                 processInput, processOutput);
+}
+
+bool displayBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::DisplayBlockToBufferQueue(data);
+        return true;
+    }
+    return false;
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
diff --git a/media/codec2/hal/aidl/ParamTypes-specialization.h b/media/codec2/hal/aidl/ParamTypes-specialization.h
new file mode 100644
index 0000000..e409b34
--- /dev/null
+++ b/media/codec2/hal/aidl/ParamTypes-specialization.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
+#define CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
+
+#include <aidl/android/hardware/media/c2/FieldId.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValues.h>
+#include <aidl/android/hardware/media/c2/Params.h>
+#include <aidl/android/hardware/media/c2/Status.h>
+#include <codec2/common/ParamTypes.h>
+
+namespace android {
+
+using ::aidl::android::hardware::media::c2::FieldId;
+using ::aidl::android::hardware::media::c2::FieldSupportedValues;
+using ::aidl::android::hardware::media::c2::Params;
+using ::aidl::android::hardware::media::c2::Status;
+
+// {offset, size} -> FieldId
+template<>
+void SetFieldId(FieldId *d, uint32_t offset, uint32_t size);
+
+// FieldId -> offset
+template<>
+uint32_t GetOffsetFromFieldId(const FieldId &s);
+
+// FieldId -> size
+template<>
+uint32_t GetSizeFromFieldId(const FieldId &s);
+
+template<>
+void SetStatus(Status *dst, c2_status_t src);
+
+template<>
+c2_status_t GetStatus(const Status &status);
+
+// C2FieldSupportedValues -> FieldSupportedValues
+template<>
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s);
+
+// FieldSupportedValues -> C2FieldSupportedValues
+template<>
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s);
+
+template<>
+struct _ParamsBlobHelper<Params> { typedef std::vector<uint8_t> BlobType; };
+
+template<>
+const std::vector<uint8_t> &GetBlob<Params>(const Params &params);
+
+template<>
+std::vector<uint8_t> *GetBlob<Params>(Params *params);
+
+} // namespace android
+
+
+
+#endif  // CODEC2_AIDL_UTILS_PARAM_TYPES_SPECIALIZATIONS_H
diff --git a/media/codec2/hal/aidl/ParamTypes.cpp b/media/codec2/hal/aidl/ParamTypes.cpp
new file mode 100644
index 0000000..0a430f9
--- /dev/null
+++ b/media/codec2/hal/aidl/ParamTypes.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-AIDL-ParamTypes"
+#include <android-base/logging.h>
+
+#include <codec2/aidl/ParamTypes.h>
+#include <codec2/common/ParamTypes.h>
+
+#include "ParamTypes-specialization.h"
+
+namespace android {
+
+using ::aidl::android::hardware::media::c2::FieldId;
+using ::aidl::android::hardware::media::c2::FieldSupportedValues;
+using ::aidl::android::hardware::media::c2::Params;
+using ::aidl::android::hardware::media::c2::Status;
+using ::aidl::android::hardware::media::c2::ValueRange;
+
+// {offset, size} -> FieldId
+template<>
+void SetFieldId(FieldId *d, uint32_t offset, uint32_t size) {
+    d->offset = offset;
+    d->sizeBytes = size;
+}
+
+// FieldId -> offset
+template<>
+uint32_t GetOffsetFromFieldId(const FieldId &s) {
+    return s.offset;
+}
+
+// FieldId -> size
+template<>
+uint32_t GetSizeFromFieldId(const FieldId &s) {
+    return s.sizeBytes;
+}
+
+template<>
+void SetStatus(Status *dst, c2_status_t src) {
+    dst->status = src;
+}
+
+template<>
+c2_status_t GetStatus(const Status &status) {
+    return static_cast<c2_status_t>(status.status);
+}
+
+static constexpr FieldSupportedValues::Tag EMPTY = FieldSupportedValues::empty;
+static constexpr FieldSupportedValues::Tag RANGE = FieldSupportedValues::range;
+static constexpr FieldSupportedValues::Tag VALUES = FieldSupportedValues::values;
+static constexpr FieldSupportedValues::Tag FLAGS = FieldSupportedValues::flags;
+
+// C2FieldSupportedValues -> FieldSupportedValues
+template<>
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
+    switch (s.type) {
+    case C2FieldSupportedValues::EMPTY: {
+            d->set<EMPTY>(true);
+            break;
+        }
+    case C2FieldSupportedValues::RANGE: {
+            ValueRange range{};
+            if (!objcpy(&range, s.range)) {
+                LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
+                d->set<RANGE>(range);
+                return false;
+            }
+            d->set<RANGE>(range);
+            break;
+        }
+    case C2FieldSupportedValues::VALUES: {
+            std::vector<int64_t> values;
+            copyVector<int64_t>(&values, s.values);
+            d->set<VALUES>(values);
+            break;
+        }
+    case C2FieldSupportedValues::FLAGS: {
+            std::vector<int64_t> flags;
+            copyVector<int64_t>(&flags, s.values);
+            d->set<FLAGS>(flags);
+            break;
+        }
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValues::type_t "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        return false;
+    }
+    return true;
+}
+
+// FieldSupportedValues -> C2FieldSupportedValues
+template<>
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
+    switch (s.getTag()) {
+    case FieldSupportedValues::empty: {
+            d->type = C2FieldSupportedValues::EMPTY;
+            break;
+        }
+    case FieldSupportedValues::range: {
+            d->type = C2FieldSupportedValues::RANGE;
+            if (!objcpy(&d->range, s.get<RANGE>())) {
+                LOG(ERROR) << "Invalid FieldSupportedValues::range.";
+                return false;
+            }
+            d->values.resize(0);
+            break;
+        }
+    case FieldSupportedValues::values: {
+            d->type = C2FieldSupportedValues::VALUES;
+            copyVector<uint64_t>(&d->values, s.get<VALUES>());
+            break;
+        }
+    case FieldSupportedValues::flags: {
+            d->type = C2FieldSupportedValues::FLAGS;
+            copyVector<uint64_t>(&d->values, s.get<FLAGS>());
+            break;
+        }
+    default:
+        LOG(WARNING) << "Unrecognized FieldSupportedValues::getDiscriminator()";
+        return false;
+    }
+    return true;
+}
+
+template<>
+const std::vector<uint8_t> &GetBlob<Params>(const Params &params) {
+    return params.params;
+}
+
+template<>
+std::vector<uint8_t> *GetBlob<Params>(Params *params) {
+    return &params->params;
+}
+
+} // namespace android
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace utils {
+
+const char* asString(Status status, const char* def) {
+    return asString(static_cast<c2_status_t>(status.status), def);
+}
+
+namespace /* unnamed */ {
+
+} // unnamed namespace
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool ToAidl(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s) {
+    return ::android::objcpy(d, nullptr, s);
+}
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool FromAidl(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s) {
+    return ::android::objcpy(d, s);
+}
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool ToAidl(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s) {
+    return ::android::objcpy(nullptr, d, s);
+}
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
+// C2FieldSupportedValuesQuery
+bool FromAidl(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr) {
+    return ::android::objcpy(d, sq, sr);
+}
+
+// C2Component::Traits -> IComponentStore::ComponentTraits
+bool ToAidl(
+        IComponentStore::ComponentTraits *d,
+        const C2Component::Traits &s) {
+    return ::android::objcpy(d, s);
+}
+
+// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
+bool FromAidl(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s) {
+    return ::android::objcpy(d, s);
+}
+
+// C2SettingResult -> SettingResult
+bool ToAidl(SettingResult *d, const C2SettingResult &s) {
+    return ::android::objcpy(d, s);
+}
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool FromAidl(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
+    return ::android::objcpy(d, s);
+}
+
+// C2ParamDescriptor -> ParamDescriptor
+bool ToAidl(ParamDescriptor *d, const C2ParamDescriptor &s) {
+    return ::android::objcpy(d, s);
+}
+
+// ParamDescriptor -> C2ParamDescriptor
+bool FromAidl(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
+    return ::android::objcpy(d, s);
+}
+
+// C2StructDescriptor -> StructDescriptor
+bool ToAidl(StructDescriptor *d, const C2StructDescriptor &s) {
+    return ::android::objcpy(d, s);
+}
+
+// StructDescriptor -> C2StructDescriptor
+bool FromAidl(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
+    return ::android::objcpy(d, s);
+}
+
+// Params -> std::vector<C2Param*>
+bool ParseParamsBlob(std::vector<C2Param*> *params, const Params &blob) {
+    return ::android::parseParamsBlob(params, blob);
+}
+
+// std::vector<const C2Param*> -> Params
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<const C2Param*> &params) {
+    return ::android::_createParamsBlob(blob, params);
+}
+
+// std::vector<C2Param*> -> Params
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<C2Param*> &params) {
+    return ::android::_createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Param>> -> Params
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params) {
+    return ::android::_createParamsBlob(blob, params);
+}
+
+// std::vector<std::unique_ptr<C2Tuning>> -> Params
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params) {
+    return ::android::_createParamsBlob(blob, params);
+}
+
+// std::vector<std::shared_ptr<const C2Info>> -> Params
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params) {
+    return ::android::_createParamsBlob(blob, params);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Param>>
+bool CopyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        Params blob) {
+    return ::android::_copyParamsFromBlob(params, blob);
+}
+
+// Params -> std::vector<std::unique_ptr<C2Tuning>>
+bool CopyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        Params blob) {
+    return ::android::_copyParamsFromBlob(params, blob);
+}
+
+// Params -> update std::vector<std::unique_ptr<C2Param>>
+bool UpdateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob) {
+    return ::android::updateParamsFromBlob(params, blob);
+}
+
+}  // namespace utils
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h b/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h
new file mode 100644
index 0000000..f111f81
--- /dev/null
+++ b/media/codec2/hal/aidl/include/codec2/aidl/BufferTypes.h
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_0_UTILS_TYPES_H
+#define CODEC2_HIDL_V1_0_UTILS_TYPES_H
+
+#include <bufferpool/ClientManager.h>
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/bufferpool/2.0/types.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/types.h>
+#include <android/hidl/safe_union/1.0/types.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <C2Work.h>
+#include <util/C2Debug-base.h>
+
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::status_t;
+using ::android::sp;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        ConnectionId;
+
+// Types of metadata for Blocks.
+struct C2Hidl_Range {
+    uint32_t offset;
+    uint32_t length; // Do not use "size" because the name collides with C2Info::size().
+};
+typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo;
+
+struct C2Hidl_Rect {
+    uint32_t left;
+    uint32_t top;
+    uint32_t width;
+    uint32_t height;
+};
+typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo;
+
+// Make asString() and operator<< work with Status as well as c2_status_t.
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status);
+
+/**
+ * All objcpy() functions will return a boolean value indicating whether the
+ * conversion succeeds or not.
+ */
+
+// C2SettingResult -> SettingResult
+bool objcpy(
+        SettingResult* d,
+        const C2SettingResult& s);
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool objcpy(
+        std::unique_ptr<C2SettingResult>* d,
+        const SettingResult& s);
+
+// C2ParamDescriptor -> ParamDescriptor
+bool objcpy(
+        ParamDescriptor* d,
+        const C2ParamDescriptor& s);
+
+// ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
+bool objcpy(
+        std::shared_ptr<C2ParamDescriptor>* d,
+        const ParamDescriptor& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool objcpy(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool objcpy(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr);
+
+// C2Component::Traits -> ComponentTraits
+bool objcpy(
+        IComponentStore::ComponentTraits* d,
+        const C2Component::Traits& s);
+
+// ComponentTraits -> C2Component::Traits
+bool objcpy(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s);
+
+// C2StructDescriptor -> StructDescriptor
+bool objcpy(
+        StructDescriptor* d,
+        const C2StructDescriptor& s);
+
+// StructDescriptor -> C2StructDescriptor
+bool objcpy(
+        std::unique_ptr<C2StructDescriptor>* d,
+        const StructDescriptor& s);
+
+// Abstract class to be used in
+// objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+struct BufferPoolSender {
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            ResultStatus ResultStatus;
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            BufferStatusMessage BufferStatusMessage;
+    typedef ::android::hardware::media::bufferpool::
+            BufferPoolData BufferPoolData;
+
+    /**
+     * Send bpData and return BufferStatusMessage that can be supplied to
+     * IClientManager::receive() in the receiving process.
+     *
+     * This function will be called from within the function
+     * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+     *
+     * \param[in] bpData BufferPoolData identifying the buffer to send.
+     * \param[out] bpMessage BufferStatusMessage of the transaction. Information
+     *    inside \p bpMessage should be passed to the receiving process by some
+     *    other means so it can call receive() properly.
+     * \return ResultStatus value that determines the success of the operation.
+     *    (See the possible values of ResultStatus in
+     *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
+     */
+    virtual ResultStatus send(
+            const std::shared_ptr<BufferPoolData>& bpData,
+            BufferStatusMessage* bpMessage) = 0;
+
+    virtual ~BufferPoolSender() = default;
+};
+
+// Default implementation of BufferPoolSender.
+//
+// To use DefaultBufferPoolSender, the IClientManager instance of the receiving
+// process must be set before send() can operate. DefaultBufferPoolSender will
+// hold a strong reference to the IClientManager instance and use it to call
+// IClientManager::registerSender() to establish the bufferpool connection when
+// send() is called.
+struct DefaultBufferPoolSender : BufferPoolSender {
+    typedef ::android::hardware::media::bufferpool::V2_0::implementation::
+            ClientManager ClientManager;
+    typedef ::android::hardware::media::bufferpool::V2_0::
+            IClientManager IClientManager;
+
+    // Set the IClientManager instance of the receiving process and the refresh
+    // interval for the connection. The default interval is 4.5 seconds, which
+    // is slightly shorter than the amount of time the bufferpool will keep an
+    // inactive connection for.
+    DefaultBufferPoolSender(
+            const sp<IClientManager>& receiverManager = nullptr,
+            std::chrono::steady_clock::duration refreshInterval = 4500ms);
+
+    // Set the IClientManager instance of the receiving process and the refresh
+    // interval for the connection. The default interval is 4.5 seconds, which
+    // is slightly shorter than the amount of time the bufferpool will keep an
+    // inactive connection for.
+    void setReceiver(
+            const sp<IClientManager>& receiverManager,
+            std::chrono::steady_clock::duration refreshInterval = 4500ms);
+
+    // Implementation of BufferPoolSender::send(). send() will establish a
+    // bufferpool connection if needed, then send the bufferpool data over to
+    // the receiving process.
+    virtual ResultStatus send(
+            const std::shared_ptr<BufferPoolData>& bpData,
+            BufferStatusMessage* bpMessage) override;
+
+private:
+    std::mutex mMutex;
+    sp<ClientManager> mSenderManager;
+    sp<IClientManager> mReceiverManager;
+    std::chrono::steady_clock::duration mRefreshInterval;
+
+    struct Connection {
+        int64_t receiverConnectionId;
+        std::chrono::steady_clock::time_point lastSent;
+        Connection(int64_t receiverConnectionId,
+                   std::chrono::steady_clock::time_point lastSent)
+              : receiverConnectionId(receiverConnectionId),
+                lastSent(lastSent) {
+        }
+    };
+
+    // Map of connections.
+    //
+    // The key is the connection id. One sender-receiver pair may have multiple
+    // connections.
+    std::map<int64_t, Connection> mConnections;
+};
+
+// std::list<std::unique_ptr<C2Work>> -> WorkBundle
+// Note: If bufferpool will be used, bpSender must not be null.
+bool objcpy(
+        WorkBundle* d,
+        const std::list<std::unique_ptr<C2Work>>& s,
+        BufferPoolSender* bpSender = nullptr);
+
+// WorkBundle -> std::list<std::unique_ptr<C2Work>>
+bool objcpy(
+        std::list<std::unique_ptr<C2Work>>* d,
+        const WorkBundle& s);
+
+/**
+ * Parses a params blob and returns C2Param pointers to its params. The pointers
+ * point to locations inside the underlying buffer of \p blob. If \p blob is
+ * destroyed, the pointers become invalid.
+ *
+ * \param[out] params target vector of C2Param pointers
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed
+ * \retval false otherwise
+ */
+bool parseParamsBlob(
+        std::vector<C2Param*> *params,
+        const hidl_vec<uint8_t> &blob);
+
+/**
+ * Concatenates a list of C2Params into a params blob.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval true if the blob was successfully created
+ * \retval false if the blob was not successful (this only happens if the
+ *         parameters were not const)
+ */
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<C2Param*> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params);
+bool createParamsBlob(
+        hidl_vec<uint8_t> *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params);
+
+/**
+ * Parses a params blob and create a vector of C2Params whose members are copies
+ * of the params in the blob.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed and params was constructed
+ * \retval false otherwise
+ */
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        Params blob);
+bool copyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        Params blob);
+
+/**
+ * Parses a params blob and applies updates to params.
+ *
+ * \param[in,out] params params to be updated
+ * \param[in] blob parameter blob containing updates
+ * \retval true if the full blob was parsed and params was updated
+ * \retval false otherwise
+ */
+bool updateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob);
+
+/**
+ * Converts a BufferPool status value to c2_status_t.
+ * \param BufferPool status
+ * \return Corresponding c2_status_t
+ */
+c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0::
+        ResultStatus rs);
+
+// BufferQueue-Based Block Operations
+// ==================================
+
+// Call before transferring block to other processes.
+//
+// The given block is ready to transfer to other processes. This will guarantee
+// the given block data is not mutated by bufferqueue migration.
+bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+// Call beginTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void beginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput = false,
+        bool processOutput = true);
+
+// Call after transferring block is finished and make sure that
+// beginTransferBufferQueueBlock() is called before.
+//
+// The transfer of given block is finished. If transfer is successful the given
+// block is not owned by process anymore. Since transfer is finished the given
+// block data is OK to mutate by bufferqueue migration after this call.
+bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
+                                 bool transfer);
+
+// Call endTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void endTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput = false,
+        bool processOutput = true);
+
+// The given block is ready to be rendered. the given block is not owned by
+// process anymore. If migration is in progress, this returns false in order
+// not to render.
+bool displayBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CODEC2_HIDL_V1_0_UTILS_TYPES_H
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h b/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h
new file mode 100644
index 0000000..ff69039
--- /dev/null
+++ b/media/codec2/hal/aidl/include/codec2/aidl/ParamTypes.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_AIDL_UTILS_PARAM_TYPES_H
+#define CODEC2_AIDL_UTILS_PARAM_TYPES_H
+
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQuery.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.h>
+#include <aidl/android/hardware/media/c2/IComponentStore.h>
+#include <aidl/android/hardware/media/c2/ParamDescriptor.h>
+#include <aidl/android/hardware/media/c2/SettingResult.h>
+#include <aidl/android/hardware/media/c2/Status.h>
+#include <aidl/android/hardware/media/c2/StructDescriptor.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <util/C2Debug-base.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace utils {
+
+// Make asString() and operator<< work with Status as well as c2_status_t.
+C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status);
+
+/**
+ * All objcpy() functions will return a boolean value indicating whether the
+ * conversion succeeds or not.
+ */
+
+// C2SettingResult -> SettingResult
+bool ToAidl(
+        SettingResult* d,
+        const C2SettingResult& s);
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+bool FromAidl(
+        std::unique_ptr<C2SettingResult>* d,
+        const SettingResult& s);
+
+// C2ParamDescriptor -> ParamDescriptor
+bool ToAidl(
+        ParamDescriptor* d,
+        const C2ParamDescriptor& s);
+
+// ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
+bool FromAidl(
+        std::shared_ptr<C2ParamDescriptor>* d,
+        const ParamDescriptor& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
+bool ToAidl(
+        FieldSupportedValuesQuery* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+bool FromAidl(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
+bool ToAidl(
+        FieldSupportedValuesQueryResult* d,
+        const C2FieldSupportedValuesQuery& s);
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
+bool FromAidl(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr);
+
+// C2Component::Traits -> ComponentTraits
+bool ToAidl(
+        IComponentStore::ComponentTraits* d,
+        const C2Component::Traits& s);
+
+// ComponentTraits -> C2Component::Traits
+bool FromAidl(
+        C2Component::Traits* d,
+        const IComponentStore::ComponentTraits& s);
+
+// C2StructDescriptor -> StructDescriptor
+bool ToAidl(
+        StructDescriptor* d,
+        const C2StructDescriptor& s);
+
+// StructDescriptor -> C2StructDescriptor
+bool FromAidl(
+        std::unique_ptr<C2StructDescriptor>* d,
+        const StructDescriptor& s);
+
+/**
+ * Parses a params blob and returns C2Param pointers to its params. The pointers
+ * point to locations inside the underlying buffer of \p blob. If \p blob is
+ * destroyed, the pointers become invalid.
+ *
+ * \param[out] params target vector of C2Param pointers
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed
+ * \retval false otherwise
+ */
+bool ParseParamsBlob(
+        std::vector<C2Param*> *params,
+        const Params &blob);
+
+/**
+ * Concatenates a list of C2Params into a params blob.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval true if the blob was successfully created
+ * \retval false if the blob was not successful (this only happens if the
+ *         parameters were not const)
+ */
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<C2Param*> &params);
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::unique_ptr<C2Param>> &params);
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::shared_ptr<const C2Info>> &params);
+bool CreateParamsBlob(
+        Params *blob,
+        const std::vector<std::unique_ptr<C2Tuning>> &params);
+
+/**
+ * Parses a params blob and create a vector of C2Params whose members are copies
+ * of the params in the blob.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval true if the full blob was parsed and params was constructed
+ * \retval false otherwise
+ */
+bool CopyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Param>>* params,
+        const Params &blob);
+bool CopyParamsFromBlob(
+        std::vector<std::unique_ptr<C2Tuning>>* params,
+        const Params &blob);
+
+/**
+ * Parses a params blob and applies updates to params.
+ *
+ * \param[in,out] params params to be updated
+ * \param[in] blob parameter blob containing updates
+ * \retval true if the full blob was parsed and params was updated
+ * \retval false otherwise
+ */
+bool UpdateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& blob);
+
+}  // namespace utils
+}  // namespace c2
+}  // namespace media
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // CODEC2_AIDL_UTILS_PARAM_TYPES_H
diff --git a/media/codec2/hal/client/Android.bp b/media/codec2/hal/client/Android.bp
index 31244fe..61ec10e 100644
--- a/media/codec2/hal/client/Android.bp
+++ b/media/codec2/hal/client/Android.bp
@@ -10,12 +10,6 @@
 cc_library_headers {
     name: "libcodec2_client_headers",
     export_include_dirs: ["include"],
-    vendor_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media",
-        "com.android.media.swcodec",
-    ],
     min_sdk_version: "29",
     host_supported: true,
     target: {
@@ -29,10 +23,15 @@
     name: "libcodec2_client",
 
     srcs: [
+        "GraphicsTracker.cpp",
         "client.cpp",
         "output.cpp",
     ],
 
+    defaults: [
+        "libcodec2-aidl-client-defaults",
+    ],
+
     header_libs: [
         "libcodec2_internal", // private
     ],
@@ -43,6 +42,7 @@
         "android.hardware.media.c2@1.0",
         "android.hardware.media.c2@1.1",
         "android.hardware.media.c2@1.2",
+        "android.hardware.media.c2-V1-ndk",
         "libbase",
         "libbinder",
         "libbinder_ndk",
@@ -55,6 +55,7 @@
         "libgui",
         "libhidlbase",
         "liblog",
+        "libnativewindow",
         "libstagefright_bufferpool@2.0.1",
         "libui",
         "libutils",
diff --git a/media/codec2/hal/client/GraphicsTracker.cpp b/media/codec2/hal/client/GraphicsTracker.cpp
new file mode 100644
index 0000000..5a2cb86
--- /dev/null
+++ b/media/codec2/hal/client/GraphicsTracker.cpp
@@ -0,0 +1,836 @@
+/*
+ * 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 <sys/eventfd.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <vndk/hardware_buffer.h>
+
+#include <codec2/aidl/GraphicsTracker.h>
+
+namespace aidl::android::hardware::media::c2::implementation {
+
+namespace {
+
+c2_status_t retrieveAHardwareBufferId(const C2ConstGraphicBlock &blk, uint64_t *bid) {
+    // TODO
+    (void)blk;
+    (void)bid;
+    return C2_OK;
+}
+
+} // anonymous namespace
+
+GraphicsTracker::BufferItem::BufferItem(
+        uint32_t generation, int slot, const sp<GraphicBuffer>& buf, const sp<Fence>& fence) :
+        mInit{false}, mGeneration{generation}, mSlot{slot} {
+    if (!buf) {
+        return;
+    }
+    AHardwareBuffer *pBuf = AHardwareBuffer_from_GraphicBuffer(buf.get());
+    int ret = AHardwareBuffer_getId(pBuf, &mId);
+    if (ret != ::android::OK) {
+        return;
+    }
+    mUsage = buf->getUsage();
+    AHardwareBuffer_acquire(pBuf);
+    mBuf = pBuf;
+    mFence = fence;
+    mInit = true;
+}
+
+GraphicsTracker::BufferItem::BufferItem(
+        uint32_t generation,
+        AHardwareBuffer_Desc *desc, AHardwareBuffer *pBuf) :
+        mInit{true}, mGeneration{generation}, mSlot{-1},
+        mBuf{pBuf}, mUsage{::android::AHardwareBuffer_convertToGrallocUsageBits(desc->usage)},
+        mFence{Fence::NO_FENCE} {
+}
+
+GraphicsTracker::BufferItem::~BufferItem() {
+    if (mInit) {
+        AHardwareBuffer_release(mBuf);
+    }
+}
+
+sp<GraphicBuffer> GraphicsTracker::BufferItem::updateBuffer(
+        uint64_t newUsage, uint32_t newGeneration) {
+    if (!mInit) {
+        return nullptr;
+    }
+    newUsage |= mUsage;
+    uint64_t ahbUsage = ::android::AHardwareBuffer_convertFromGrallocUsageBits(newUsage);
+    AHardwareBuffer_Desc desc;
+    AHardwareBuffer_describe(mBuf, &desc);
+    // TODO: we need well-established buffer migration features from graphics.
+    // (b/273776738)
+    desc.usage = ahbUsage;
+    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(mBuf);
+    if (!handle) {
+        return nullptr;
+    }
+
+    AHardwareBuffer *newBuf;
+    int err = AHardwareBuffer_createFromHandle(&desc, handle,
+                                     AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE,
+                                     &newBuf);
+    if (err != ::android::NO_ERROR) {
+        return nullptr;
+    }
+
+    GraphicBuffer *gb = ::android::AHardwareBuffer_to_GraphicBuffer(newBuf);
+    if (!gb) {
+        AHardwareBuffer_release(newBuf);
+        return nullptr;
+    }
+
+    gb->setGenerationNumber(newGeneration);
+    mUsage = newUsage;
+    mGeneration = newGeneration;
+    AHardwareBuffer_release(mBuf);
+    // acquire is already done when creating.
+    mBuf = newBuf;
+    return gb;
+}
+
+void GraphicsTracker::BufferCache::waitOnSlot(int slot) {
+    // TODO: log
+    CHECK(0 <= slot && slot < kNumSlots);
+    BlockedSlot *p = &mBlockedSlots[slot];
+    std::unique_lock<std::mutex> l(p->l);
+    while (p->blocked) {
+        p->cv.wait(l);
+    }
+}
+
+void GraphicsTracker::BufferCache::blockSlot(int slot) {
+    CHECK(0 <= slot && slot < kNumSlots);
+    BlockedSlot *p = &mBlockedSlots[slot];
+    std::unique_lock<std::mutex> l(p->l);
+    p->blocked = true;
+}
+
+void GraphicsTracker::BufferCache::unblockSlot(int slot) {
+    CHECK(0 <= slot && slot < kNumSlots);
+    BlockedSlot *p = &mBlockedSlots[slot];
+    std::unique_lock<std::mutex> l(p->l);
+    p->blocked = false;
+    l.unlock();
+    p->cv.notify_one();
+}
+
+GraphicsTracker::GraphicsTracker(int maxDequeueCount)
+    : mMaxDequeue{maxDequeueCount}, mMaxDequeueRequested{maxDequeueCount},
+    mMaxDequeueCommitted{maxDequeueCount},
+    mMaxDequeueRequestedSeqId{0UL}, mMaxDequeueCommittedSeqId{0ULL},
+    mDequeueable{maxDequeueCount},
+    mTotalDequeued{0}, mTotalCancelled{0}, mTotalDropped{0}, mTotalReleased{0},
+    mInConfig{false}, mStopped{false} {
+    if (maxDequeueCount <= 0) {
+        mMaxDequeue = kDefaultMaxDequeue;
+        mMaxDequeueRequested = kDefaultMaxDequeue;
+        mMaxDequeueCommitted = kDefaultMaxDequeue;
+        mDequeueable = kDefaultMaxDequeue;
+    }
+    int allocEventFd = ::eventfd(mDequeueable, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
+    int statusEventFd = ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+
+    mAllocEventFd.reset(allocEventFd);
+    mStopEventFd.reset(statusEventFd);
+
+    mEventQueueThread = std::thread([this](){processEvent();});
+
+    CHECK(allocEventFd >= 0 && statusEventFd >= 0);
+    CHECK(mEventQueueThread.joinable());
+}
+
+GraphicsTracker::~GraphicsTracker() {
+    stop();
+    if (mEventQueueThread.joinable()) {
+        std::unique_lock<std::mutex> l(mEventLock);
+        mStopEventThread = true;
+        l.unlock();
+        mEventCv.notify_one();
+        mEventQueueThread.join();
+    }
+}
+
+bool GraphicsTracker::adjustDequeueConfLocked(bool *updateDequeue) {
+    // TODO: can't we adjust during config? not committing it may safe?
+    *updateDequeue = false;
+    if (!mInConfig && mMaxDequeueRequested < mMaxDequeue) {
+        int delta = mMaxDequeue - mMaxDequeueRequested;
+        // Since we are supposed to increase mDequeuable by one already
+        int adjustable = mDequeueable + 1;
+        if (adjustable >= delta) {
+            mMaxDequeue = mMaxDequeueRequested;
+            mDequeueable -= (delta - 1);
+        } else {
+            mMaxDequeue -= adjustable;
+            mDequeueable = 0;
+        }
+        if (mMaxDequeueRequested == mMaxDequeue && mMaxDequeueRequested != mMaxDequeueCommitted) {
+            *updateDequeue = true;
+        }
+        return true;
+    }
+    return false;
+}
+
+c2_status_t GraphicsTracker::configureGraphics(
+        const sp<IGraphicBufferProducer>& igbp, uint32_t generation) {
+    std::shared_ptr<BufferCache> prevCache;
+    int prevDequeueCommitted;
+
+    std::unique_lock<std::mutex> cl(mConfigLock);
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        mInConfig = true;
+        prevCache = mBufferCache;
+        prevDequeueCommitted = mMaxDequeueCommitted;
+    }
+    // NOTE: Switching to the same surface is blocked from MediaCodec.
+    // Switching to the same surface might not work if tried, since disconnect()
+    // to the old surface in MediaCodec and allocate from the new surface from
+    // GraphicsTracker cannot be synchronized properly.
+    uint64_t bqId{0ULL};
+    ::android::status_t ret = ::android::OK;
+    if (igbp) {
+        ret = igbp->getUniqueId(&bqId);
+    }
+    if (ret != ::android::OK || prevCache->mGeneration == generation || prevCache->mBqId == bqId) {
+        return C2_BAD_VALUE;
+    }
+    ret = igbp->setMaxDequeuedBufferCount(prevDequeueCommitted);
+    if (ret != ::android::OK) {
+        // TODO: sort out the error from igbp and return an error accordingly.
+        return C2_CORRUPTED;
+    }
+    std::shared_ptr<BufferCache> newCache = std::make_shared<BufferCache>(bqId, generation, igbp);
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        mInConfig = false;
+        mBufferCache = newCache;
+    }
+    return C2_OK;
+}
+
+c2_status_t GraphicsTracker::configureMaxDequeueCount(int maxDequeueCount) {
+    std::shared_ptr<BufferCache> cache;
+
+    // max dequeue count which can be committed to IGBP.
+    // (Sometimes maxDequeueCount cannot be committed if the number of
+    // dequeued buffer count is bigger.)
+    int maxDequeueToCommit;
+    // max dequeue count which is committed to IGBP currently
+    // (actually mMaxDequeueCommitted, but needs to be read outside lock.)
+    int curMaxDequeueCommitted;
+    std::unique_lock<std::mutex> cl(mConfigLock);
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        if (mMaxDequeueRequested == maxDequeueCount) {
+            return C2_OK;
+        }
+        mInConfig = true;
+        mMaxDequeueRequested = maxDequeueCount;
+        cache = mBufferCache;
+        curMaxDequeueCommitted = mMaxDequeueCommitted;
+        if (mMaxDequeue <= maxDequeueCount) {
+            maxDequeueToCommit = maxDequeueCount;
+        } else {
+            // Since mDequeuable is decreasing,
+            // a delievered ready to allocate event may not be fulfilled.
+            // Another waiting via a waitable object may be necessary in the case.
+            int delta = mMaxDequeue - maxDequeueCount;
+            if (delta <= mDequeueable) {
+                maxDequeueToCommit = maxDequeueCount;
+                mDequeueable -= delta;
+            } else {
+                maxDequeueToCommit = mMaxDequeue - mDequeueable;
+                mDequeueable = 0;
+            }
+        }
+    }
+
+    bool committed = true;
+    if (cache->mIgbp && maxDequeueToCommit != curMaxDequeueCommitted) {
+        ::android::status_t ret = cache->mIgbp->setMaxDequeuedBufferCount(maxDequeueToCommit);
+        committed = (ret == ::android::OK);
+        if (!committed) {
+            // This should not happen.
+            ALOGE("dequeueCount failed with error(%d)", (int)ret);
+        }
+    }
+
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        mInConfig = false;
+        if (committed) {
+            mMaxDequeueCommitted = maxDequeueToCommit;
+            int delta = mMaxDequeueCommitted - mMaxDequeue;
+            if (delta > 0) {
+                mDequeueable += delta;
+                l.unlock();
+                writeIncDequeueable(delta);
+            }
+        }
+    }
+
+    if (!committed) {
+        return C2_CORRUPTED;
+    }
+    return C2_OK;
+}
+
+void GraphicsTracker::updateDequeueConf() {
+    std::shared_ptr<BufferCache> cache;
+    int dequeueCommit;
+    std::unique_lock<std::mutex> cl(mConfigLock);
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        if (mMaxDequeue == mMaxDequeueRequested && mMaxDequeueCommitted != mMaxDequeueRequested) {
+            dequeueCommit = mMaxDequeue;
+            mInConfig = true;
+            cache = mBufferCache;
+        } else {
+            return;
+        }
+    }
+    bool committed = true;
+    if (cache->mIgbp) {
+        ::android::status_t ret = cache->mIgbp->setMaxDequeuedBufferCount(dequeueCommit);
+        committed = (ret == ::android::OK);
+        if (!committed) {
+            // This should not happen.
+            ALOGE("dequeueCount failed with error(%d)", (int)ret);
+        }
+    }
+    int cleared = 0;
+    {
+        // cache == mCache here, since we locked config.
+        std::unique_lock<std::mutex> l(mLock);
+        mInConfig = false;
+        if (committed) {
+            if (cache->mIgbp && dequeueCommit < mMaxDequeueCommitted) {
+                // we are shrinking # of buffers, so clearing the cache.
+                for (auto it = cache->mBuffers.begin(); it != cache->mBuffers.end();) {
+                    uint64_t bid = it->second->mId;
+                    if (mDequeued.count(bid) == 0 || mDeallocating.count(bid) > 0) {
+                        ++cleared;
+                        it = cache->mBuffers.erase(it);
+                    } else {
+                        ++it;
+                    }
+                }
+            }
+            mMaxDequeueCommitted = dequeueCommit;
+        }
+    }
+    if (cleared > 0) {
+        ALOGD("%d buffers are cleared from cache, due to IGBP capacity change", cleared);
+    }
+
+}
+
+void GraphicsTracker::stop() {
+    bool expected = false;
+    bool updated = mStopped.compare_exchange_strong(expected, true);
+    if (updated) {
+        uint64_t val = 1ULL;
+        int ret = ::write(mStopEventFd.get(), &val, 8);
+        if (ret < 0) {
+            // EINTR maybe
+            std::unique_lock<std::mutex> l(mEventLock);
+            mStopRequest = true;
+            l.unlock();
+            mEventCv.notify_one();
+            ALOGW("stop() status update pending");
+        }
+    }
+}
+
+void GraphicsTracker::writeIncDequeueable(int inc) {
+    uint64_t val = inc;
+    int ret = ::write(mAllocEventFd.get(), &val, 8);
+    if (ret < 0) {
+        // EINTR due to signal handling maybe, this should be rare
+        std::unique_lock<std::mutex> l(mEventLock);
+        mIncDequeueable += inc;
+        l.unlock();
+        mEventCv.notify_one();
+        ALOGW("updating dequeueable to eventfd pending");
+    }
+}
+
+void GraphicsTracker::processEvent() {
+    // This is for write() failure of eventfds.
+    // write() failure other than EINTR should not happen.
+    int64_t acc = 0;
+    bool stopRequest = false;
+    bool stopCommitted = false;
+
+    while (true) {
+        {
+            std::unique_lock<std::mutex> l(mEventLock);
+            acc += mIncDequeueable;
+            mIncDequeueable = 0;
+            stopRequest |= mStopRequest;
+            mStopRequest = false;
+            if (acc == 0 && stopRequest == stopCommitted) {
+                if (mStopEventThread) {
+                    break;
+                }
+                mEventCv.wait(l);
+                continue;
+            }
+        }
+
+        if (acc > 0) {
+            int ret = ::write(mAllocEventFd.get(), &acc, 8);
+            if (ret > 0) {
+                acc = 0;
+            }
+        }
+        if (stopRequest && !stopCommitted) {
+            uint64_t val = 1ULL;
+            int ret = ::write(mStopEventFd.get(), &val, 8);
+            if (ret > 0) {
+                stopCommitted = true;
+            }
+        }
+        if (mStopEventThread) {
+            break;
+        }
+    }
+}
+
+c2_status_t GraphicsTracker::getWaitableFds(int *allocFd, int *statusFd) {
+    *allocFd = ::dup(mAllocEventFd.get());
+    *statusFd = ::dup(mStopEventFd.get());
+
+    if (*allocFd < 0 || *statusFd < 0) {
+        if (*allocFd >= 0) {
+            ::close(*allocFd);
+            *allocFd = -1;
+        }
+        if (*statusFd >= 0) {
+            ::close(*statusFd);
+            *statusFd = -1;
+        }
+        return C2_NO_MEMORY;
+    }
+    return C2_OK;
+}
+
+c2_status_t GraphicsTracker::requestAllocate(std::shared_ptr<BufferCache> *cache) {
+    std::lock_guard<std::mutex> l(mLock);
+    if (mDequeueable > 0) {
+        uint64_t val;
+        int ret = ::read(mAllocEventFd.get(), &val, 8);
+        if (ret < 0) {
+            if (errno == EINTR) {
+                // Do we really need to care for cancel due to signal handling?
+                return C2_CANCELED;
+            }
+            if (errno == EAGAIN) {
+                // proper usage of waitable object should not return this.
+                // but there could be alloc requests from HAL ignoring the internal status.
+                return C2_BLOCKING;
+            }
+            CHECK(errno != 0);
+        }
+        mDequeueable--;
+        *cache = mBufferCache;
+        return C2_OK;
+    }
+    return C2_BLOCKING;
+}
+
+// If {@code cached} is {@code true}, {@code pBuffer} should be read from the
+// current cached status. Otherwise, {@code pBuffer} should be written to
+// current caches status.
+void GraphicsTracker::commitAllocate(c2_status_t res, const std::shared_ptr<BufferCache> &cache,
+                    bool cached, int slot, const sp<Fence> &fence,
+                    std::shared_ptr<BufferItem> *pBuffer, bool *updateDequeue) {
+    std::unique_lock<std::mutex> l(mLock);
+    if (res == C2_OK) {
+        if (cached) {
+            auto it = cache->mBuffers.find(slot);
+            CHECK(it != cache->mBuffers.end());
+            it->second->mFence = fence;
+            *pBuffer = it->second;
+        } else if (cache.get() == mBufferCache.get() && mBufferCache->mIgbp) {
+            // Cache the buffer if it is allocated from the current IGBP
+            CHECK(slot >= 0);
+            auto ret = mBufferCache->mBuffers.emplace(slot, *pBuffer);
+            if (!ret.second) {
+                ret.first->second = *pBuffer;
+            }
+        }
+        uint64_t bid = (*pBuffer)->mId;
+        auto mapRet = mDequeued.emplace(bid, *pBuffer);
+        CHECK(mapRet.second);
+    } else {
+        if (adjustDequeueConfLocked(updateDequeue)) {
+            return;
+        }
+        mDequeueable++;
+        l.unlock();
+        writeIncDequeueable(1);
+    }
+}
+
+
+// if a buffer is newly allocated, {@code cached} is {@code false},
+// and the buffer is in the {@code buffer}
+// otherwise, {@code cached} is {@code false} and the buffer should be
+// retrieved by commitAllocate();
+c2_status_t GraphicsTracker::_allocate(const std::shared_ptr<BufferCache> &cache,
+                                      uint32_t width, uint32_t height, PixelFormat format,
+                                      int64_t usage,
+                                      bool *cached,
+                                      int *rSlotId,
+                                      sp<Fence> *rFence,
+                                      std::shared_ptr<BufferItem> *buffer) {
+    ::android::sp<IGraphicBufferProducer> igbp = cache->mIgbp;
+    uint32_t generation = cache->mGeneration;
+    if (!igbp) {
+        // allocate directly
+        AHardwareBuffer_Desc desc;
+        desc.width = width;
+        desc.height = height;
+        desc.layers = 1u;
+        desc.format = ::android::AHardwareBuffer_convertFromPixelFormat(format);
+        desc.usage = ::android::AHardwareBuffer_convertFromGrallocUsageBits(usage);
+        desc.rfu0 = 0;
+        desc.rfu1 = 0;
+
+        AHardwareBuffer *buf;
+        int ret = AHardwareBuffer_allocate(&desc, &buf);
+        if (ret != ::android::OK) {
+            ALOGE("direct allocation of AHB failed(%d)", ret);
+            return ret == ::android::NO_MEMORY ? C2_NO_MEMORY : C2_CORRUPTED;
+        }
+        *cached = false;
+        *buffer = std::make_shared<BufferItem>(generation, &desc, buf);
+        if (!*buffer) {
+            AHardwareBuffer_release(buf);
+            return C2_NO_MEMORY;
+        }
+        return C2_OK;
+    }
+
+    int slotId;
+    uint64_t outBufferAge;
+    ::android::FrameEventHistoryDelta outTimestamps;
+    sp<Fence> fence;
+
+    ::android::status_t status = igbp->dequeueBuffer(
+            &slotId, &fence, width, height, format, usage, &outBufferAge, &outTimestamps);
+    if (status < ::android::OK) {
+        ALOGE("dequeueBuffer() error %d", (int)status);
+        return C2_CORRUPTED;
+    }
+    cache->waitOnSlot(slotId);
+    bool exists = false;
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        if (cache.get() == mBufferCache.get() &&
+            cache->mBuffers.find(slotId) != cache->mBuffers.end()) {
+            exists = true;
+        }
+    }
+    bool needsRealloc = status & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
+    if (needsRealloc || !exists) {
+        sp<GraphicBuffer> realloced;
+        status = igbp->requestBuffer(slotId, &realloced);
+        if (status != ::android::OK) {
+            igbp->cancelBuffer(slotId, fence);
+            return C2_CORRUPTED;
+        }
+        *buffer = std::make_shared<BufferItem>(generation, slotId, realloced, fence);
+        if (!(*buffer)->mInit) {
+            buffer->reset();
+            igbp->cancelBuffer(slotId, fence);
+            return C2_CORRUPTED;
+        }
+        *cached = false;
+        return C2_OK;
+    }
+    *cached = true;
+    *rSlotId = slotId;
+    *rFence = fence;
+    return C2_OK;
+}
+
+c2_status_t GraphicsTracker::allocate(
+        uint32_t width, uint32_t height, PixelFormat format, uint64_t usage,
+        AHardwareBuffer **buf, sp<Fence> *rFence) {
+    if (mStopped.load() == true) {
+        return C2_BAD_STATE;
+    }
+    std::shared_ptr<BufferCache> cache;
+    c2_status_t res = requestAllocate(&cache);
+    if (res != C2_OK) {
+        return res;
+    }
+
+    bool cached = false;
+    int slotId;
+    sp<Fence> fence;
+    std::shared_ptr<BufferItem> buffer;
+    bool updateDequeue;
+    res = _allocate(cache, width, height, format, usage, &cached, &slotId, &fence, &buffer);
+    commitAllocate(res, cache, cached, slotId, fence, &buffer, &updateDequeue);
+    if (res == C2_OK) {
+        *buf = buffer->mBuf;
+        *rFence = buffer->mFence;
+        // *buf should be valid even if buffer is dtor-ed.
+        AHardwareBuffer_acquire(*buf);
+    }
+    if (updateDequeue) {
+        updateDequeueConf();
+    }
+    return res;
+}
+
+c2_status_t GraphicsTracker::requestDeallocate(uint64_t bid, const sp<Fence> &fence,
+                                              bool *completed, bool *updateDequeue,
+                                              std::shared_ptr<BufferCache> *cache, int *slotId,
+                                              sp<Fence> *rFence) {
+    std::unique_lock<std::mutex> l(mLock);
+    if (mDeallocating.find(bid) != mDeallocating.end()) {
+        ALOGE("Tries to deallocate a buffer which is already deallocating or rendering");
+        return C2_DUPLICATE;
+    }
+    auto it = mDequeued.find(bid);
+    if (it == mDequeued.end()) {
+        ALOGE("Tried to deallocate non dequeued buffer");
+        return C2_NOT_FOUND;
+    }
+
+    std::shared_ptr<BufferItem> buffer = it->second;
+    if (buffer->mGeneration == mBufferCache->mGeneration && mBufferCache->mIgbp) {
+        auto it = mBufferCache->mBuffers.find(buffer->mSlot);
+        CHECK(it != mBufferCache->mBuffers.end() && it->second.get() == buffer.get());
+        *cache = mBufferCache;
+        *slotId = buffer->mSlot;
+        *rFence = ( fence == Fence::NO_FENCE) ? buffer->mFence : fence;
+        // mark this deallocating
+        mDeallocating.emplace(bid);
+        mBufferCache->blockSlot(buffer->mSlot);
+        *completed = false;
+    } else { // buffer is not from the current underlying Graphics.
+        mDequeued.erase(bid);
+        *completed = true;
+        if (adjustDequeueConfLocked(updateDequeue)) {
+            return C2_OK;
+        }
+        mDequeueable++;
+        l.unlock();
+        writeIncDequeueable(1);
+    }
+    return C2_OK;
+}
+
+void GraphicsTracker::commitDeallocate(
+        std::shared_ptr<BufferCache> &cache, int slotId, uint64_t bid) {
+    std::lock_guard<std::mutex> l(mLock);
+    size_t del1 = mDequeued.erase(bid);
+    size_t del2 = mDeallocating.erase(bid);
+    CHECK(del1 > 0 && del2 > 0);
+    mDequeueable++;
+    if (cache) {
+        cache->unblockSlot(slotId);
+    }
+}
+
+
+c2_status_t GraphicsTracker::deallocate(uint64_t bid, const sp<Fence> &fence) {
+    bool completed;
+    bool updateDequeue;
+    std::shared_ptr<BufferCache> cache;
+    int slotId;
+    sp<Fence> rFence;
+    c2_status_t res = requestDeallocate(bid, fence, &completed, &updateDequeue,
+                                        &cache, &slotId, &rFence);
+    if (res != C2_OK) {
+        return res;
+    }
+    if (completed == true) {
+        if (updateDequeue) {
+            updateDequeueConf();
+        }
+        return C2_OK;
+    }
+
+    // ignore return value since IGBP could be already stale.
+    // cache->mIgbp is not null, if completed is false.
+    (void)cache->mIgbp->cancelBuffer(slotId, rFence);
+
+    commitDeallocate(cache, slotId, bid);
+    return C2_OK;
+}
+
+c2_status_t GraphicsTracker::requestRender(uint64_t bid, std::shared_ptr<BufferCache> *cache,
+                                          std::shared_ptr<BufferItem> *pBuffer,
+                                          bool *updateDequeue) {
+    std::unique_lock<std::mutex> l(mLock);
+    if (mDeallocating.find(bid) != mDeallocating.end()) {
+        ALOGE("Tries to render a buffer which is already deallocating or rendering");
+        return C2_DUPLICATE;
+    }
+    auto it = mDequeued.find(bid);
+    if (it == mDequeued.end()) {
+        ALOGE("Tried to render non dequeued buffer");
+        return C2_NOT_FOUND;
+    }
+    if (!mBufferCache->mIgbp) {
+        // Render requested without surface.
+        // reclaim the buffer for dequeue.
+        // TODO: is this correct for API wise?
+        mDequeued.erase(it);
+        if (adjustDequeueConfLocked(updateDequeue)) {
+            return C2_BAD_STATE;
+        }
+        mDequeueable++;
+        l.unlock();
+        writeIncDequeueable(1);
+        return C2_BAD_STATE;
+    }
+    std::shared_ptr<BufferItem> buffer = it->second;
+    *cache = mBufferCache;
+    if (buffer->mGeneration == mBufferCache->mGeneration) {
+        auto it = mBufferCache->mBuffers.find(buffer->mSlot);
+        CHECK(it != mBufferCache->mBuffers.end() && it->second.get() == buffer.get());
+        mBufferCache->blockSlot(buffer->mSlot);
+    }
+    *pBuffer = buffer;
+    mDeallocating.emplace(bid);
+    return C2_OK;
+}
+
+void GraphicsTracker::commitRender(uint64_t origBid,
+                                  const std::shared_ptr<BufferCache> &cache,
+                                  const std::shared_ptr<BufferItem> &buffer,
+                                  bool *updateDequeue) {
+    std::unique_lock<std::mutex> l(mLock);
+    uint64_t bid = buffer->mId;
+
+    if (cache.get() != mBufferCache.get()) {
+        // Surface changed, no need to wait for buffer being released.
+        mDeallocating.erase(bid);
+        mDequeued.erase(bid);
+        if (adjustDequeueConfLocked(updateDequeue)) {
+            return;
+        }
+        mDequeueable++;
+        l.unlock();
+        writeIncDequeueable(1);
+        return;
+    }
+
+    if (origBid != bid) {
+        // migration happened, need to register the buffer to Cache
+        mBufferCache->mBuffers.emplace(buffer->mSlot, buffer);
+    }
+    mDeallocating.erase(bid);
+    mDequeued.erase(bid);
+}
+
+c2_status_t GraphicsTracker::render(const C2ConstGraphicBlock& blk,
+                                   const IGraphicBufferProducer::QueueBufferInput &input,
+                                   IGraphicBufferProducer::QueueBufferOutput *output) {
+    uint64_t bid;
+    c2_status_t res = retrieveAHardwareBufferId(blk, &bid);
+    if (res != C2_OK) {
+        ALOGE("retrieving AHB-ID for GraphicBlock failed");
+        return C2_CORRUPTED;
+    }
+    std::shared_ptr<BufferCache> cache;
+    std::shared_ptr<BufferItem> buffer;
+    bool updateDequeue = false;
+    res = requestRender(bid, &cache, &buffer, &updateDequeue);
+    if (res != C2_OK) {
+        if (updateDequeue) {
+            updateDequeueConf();
+        }
+        return res;
+    }
+    ::android::status_t migrateRes = ::android::OK;
+    ::android::status_t renderRes = ::android::OK;
+    if (cache->mGeneration != buffer->mGeneration) {
+        uint64_t newUsage = 0ULL;
+        int slotId = -1;;
+
+        (void) cache->mIgbp->getConsumerUsage(&newUsage);
+        sp<GraphicBuffer> gb = buffer->updateBuffer(newUsage, cache->mGeneration);
+        if (gb) {
+            migrateRes = cache->mIgbp->attachBuffer(&(buffer->mSlot), gb);
+        } else {
+            ALOGW("realloc-ing a new buffer for migration failed");
+            migrateRes = ::android::INVALID_OPERATION;
+        }
+    }
+    if (migrateRes == ::android::OK) {
+        renderRes = cache->mIgbp->queueBuffer(buffer->mSlot, input, output);
+        if (renderRes != ::android::OK) {
+            CHECK(renderRes != ::android::BAD_VALUE);
+        }
+    }
+    if (migrateRes != ::android::OK || renderRes != ::android::OK) {
+        // since it is not renderable, just de-allocate
+        if (migrateRes != ::android::OK) {
+            std::shared_ptr<BufferCache> nullCache;
+            commitDeallocate(nullCache, -1, bid);
+        } else {
+            (void) cache->mIgbp->cancelBuffer(buffer->mSlot, input.fence);
+            commitDeallocate(cache, buffer->mSlot, bid);
+        }
+        ALOGE("migration error(%d), render error(%d)", (int)migrateRes, (int)renderRes);
+        return C2_REFUSED;
+    }
+
+    updateDequeue = false;
+    commitRender(bid, cache, buffer, &updateDequeue);
+    if (updateDequeue) {
+        updateDequeueConf();
+    }
+    if (output->bufferReplaced) {
+        // in case of buffer drop during render
+        onReleased(cache->mGeneration);
+    }
+    return C2_OK;
+}
+
+void GraphicsTracker::onReleased(uint32_t generation) {
+    bool updateDequeue = false;
+    {
+        std::unique_lock<std::mutex> l(mLock);
+        if (mBufferCache->mGeneration == generation) {
+            if (!adjustDequeueConfLocked(&updateDequeue)) {
+                mDequeueable++;
+                l.unlock();
+                writeIncDequeueable(1);
+            }
+        }
+    }
+    if (updateDequeue) {
+        updateDequeueConf();
+    }
+}
+
+} // namespace aidl::android::hardware::media::c2::implementation
diff --git a/media/codec2/hal/client/client.cpp b/media/codec2/hal/client/client.cpp
index 97c0806..75c0d04 100644
--- a/media/codec2/hal/client/client.cpp
+++ b/media/codec2/hal/client/client.cpp
@@ -24,6 +24,7 @@
 #include <C2Config.h> // for C2StreamUsageTuning
 #include <C2PlatformSupport.h>
 
+#include <android/binder_auto_utils.h>
 #include <android/hardware/media/bufferpool/2.0/IClientManager.h>
 #include <android/hardware/media/c2/1.0/IComponent.h>
 #include <android/hardware/media/c2/1.0/IComponentInterface.h>
@@ -32,8 +33,18 @@
 #include <android/hardware/media/c2/1.0/IConfigurable.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
 
+#include <aidl/android/hardware/media/c2/FieldSupportedValues.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQuery.h>
+#include <aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.h>
+#include <aidl/android/hardware/media/c2/IComponent.h>
+#include <aidl/android/hardware/media/c2/IComponentInterface.h>
+#include <aidl/android/hardware/media/c2/IComponentStore.h>
+#include <aidl/android/hardware/media/c2/IConfigurable.h>
+#include <aidl/android/hardware/media/c2/ParamDescriptor.h>
+
 #include <android-base/properties.h>
 #include <bufferpool/ClientManager.h>
+#include <codec2/aidl/ParamTypes.h>
 #include <codec2/hidl/1.0/types.h>
 #include <codec2/hidl/1.1/types.h>
 #include <codec2/hidl/1.2/types.h>
@@ -47,7 +58,6 @@
 #include <system/window.h> // for NATIVE_WINDOW_QUERY_*
 #include <media/stagefright/foundation/ADebug.h> // for asString(status_t)
 
-
 #include <deque>
 #include <iterator>
 #include <limits>
@@ -65,11 +75,6 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 
-using namespace ::android::hardware::media::c2::V1_1;
-using namespace ::android::hardware::media::c2::V1_1::utils;
-using namespace ::android::hardware::media::bufferpool::V2_0;
-using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
-
 using HGraphicBufferProducer1 = ::android::hardware::graphics::bufferqueue::
         V1_0::IGraphicBufferProducer;
 using HGraphicBufferProducer2 = ::android::hardware::graphics::bufferqueue::
@@ -80,6 +85,13 @@
         V2_0::utils::H2BGraphicBufferProducer;
 using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
 
+namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
+namespace c2_aidl = ::aidl::android::hardware::media::c2;
+namespace c2_hidl_base = ::android::hardware::media::c2;
+namespace c2_hidl = ::android::hardware::media::c2::V1_2;
+
+using c2_hidl::utils::operator<<;
+
 namespace /* unnamed */ {
 
 // c2_status_t value that corresponds to hwbinder transaction failure.
@@ -254,15 +266,43 @@
         return sCaches;
     }
 };
+// Codec2ConfigurableClient::HidlImpl
 
-// Codec2ConfigurableClient
+struct Codec2ConfigurableClient::HidlImpl : public Codec2ConfigurableClient::ImplBase {
+    typedef c2_hidl::IConfigurable Base;
 
-const C2String& Codec2ConfigurableClient::getName() const {
-    return mName;
-}
+    // base cannot be null.
+    explicit HidlImpl(const sp<Base>& base);
 
-Codec2ConfigurableClient::Codec2ConfigurableClient(
-        const sp<IConfigurable>& base)
+    const C2String& getName() const override {
+        return mName;
+    }
+
+    c2_status_t query(
+            const std::vector<C2Param*>& stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
+
+    c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
+
+    c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const override;
+
+    c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const override;
+
+private:
+    sp<Base> mBase;
+    const C2String mName;
+};
+
+Codec2ConfigurableClient::HidlImpl::HidlImpl(const sp<Base>& base)
       : mBase{base},
         mName{[base]() -> C2String {
                 C2String outName;
@@ -274,12 +314,12 @@
             }()} {
 }
 
-c2_status_t Codec2ConfigurableClient::query(
+c2_status_t Codec2ConfigurableClient::HidlImpl::query(
         const std::vector<C2Param*> &stackParams,
         const std::vector<C2Param::Index> &heapParamIndices,
         c2_blocking_t mayBlock,
         std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
-    hidl_vec<ParamIndex> indices(
+    hidl_vec<c2_hidl::ParamIndex> indices(
             stackParams.size() + heapParamIndices.size());
     size_t numIndices = 0;
     for (C2Param* const& stackParam : stackParams) {
@@ -287,12 +327,12 @@
             LOG(WARNING) << "query -- null stack param encountered.";
             continue;
         }
-        indices[numIndices++] = static_cast<ParamIndex>(stackParam->index());
+        indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
     }
     size_t numStackIndices = numIndices;
     for (const C2Param::Index& index : heapParamIndices) {
         indices[numIndices++] =
-                static_cast<ParamIndex>(static_cast<uint32_t>(index));
+                static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
     }
     indices.resize(numIndices);
     if (heapParams) {
@@ -303,7 +343,7 @@
             indices,
             mayBlock == C2_MAY_BLOCK,
             [&status, &numStackIndices, &stackParams, heapParams](
-                    Status s, const Params& p) {
+                    c2_hidl::Status s, const c2_hidl::Params& p) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK && status != C2_BAD_INDEX) {
                     LOG(DEBUG) << "query -- call failed: "
@@ -311,7 +351,7 @@
                     return;
                 }
                 std::vector<C2Param*> paramPointers;
-                if (!parseParamsBlob(&paramPointers, p)) {
+                if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
                     LOG(ERROR) << "query -- error while parsing params.";
                     status = C2_CORRUPTED;
                     return;
@@ -371,12 +411,12 @@
     return status;
 }
 
-c2_status_t Codec2ConfigurableClient::config(
+c2_status_t Codec2ConfigurableClient::HidlImpl::config(
         const std::vector<C2Param*> &params,
         c2_blocking_t mayBlock,
         std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
-    Params hidlParams;
-    if (!createParamsBlob(&hidlParams, params)) {
+    c2_hidl::Params hidlParams;
+    if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
         LOG(ERROR) << "config -- bad input.";
         return C2_TRANSACTION_FAILED;
     }
@@ -385,9 +425,9 @@
             hidlParams,
             mayBlock == C2_MAY_BLOCK,
             [&status, &params, failures](
-                    Status s,
-                    const hidl_vec<SettingResult> f,
-                    const Params& o) {
+                    c2_hidl::Status s,
+                    const hidl_vec<c2_hidl::SettingResult> f,
+                    const c2_hidl::Params& o) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK && status != C2_BAD_INDEX) {
                     LOG(DEBUG) << "config -- call failed: "
@@ -395,14 +435,14 @@
                 }
                 size_t i = failures->size();
                 failures->resize(i + f.size());
-                for (const SettingResult& sf : f) {
-                    if (!objcpy(&(*failures)[i++], sf)) {
+                for (const c2_hidl::SettingResult& sf : f) {
+                    if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
                         LOG(ERROR) << "config -- "
                                    << "invalid SettingResult returned.";
                         return;
                     }
                 }
-                if (!updateParamsFromBlob(params, o)) {
+                if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
                     LOG(ERROR) << "config -- "
                                << "failed to parse returned params.";
                     status = C2_CORRUPTED;
@@ -415,7 +455,7 @@
     return status;
 }
 
-c2_status_t Codec2ConfigurableClient::querySupportedParams(
+c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedParams(
         std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
     // TODO: Cache and query properly!
     c2_status_t status;
@@ -423,8 +463,8 @@
             std::numeric_limits<uint32_t>::min(),
             std::numeric_limits<uint32_t>::max(),
             [&status, params](
-                    Status s,
-                    const hidl_vec<ParamDescriptor>& p) {
+                    c2_hidl::Status s,
+                    const hidl_vec<c2_hidl::ParamDescriptor>& p) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     LOG(DEBUG) << "querySupportedParams -- call failed: "
@@ -433,8 +473,8 @@
                 }
                 size_t i = params->size();
                 params->resize(i + p.size());
-                for (const ParamDescriptor& sp : p) {
-                    if (!objcpy(&(*params)[i++], sp)) {
+                for (const c2_hidl::ParamDescriptor& sp : p) {
+                    if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
                         LOG(ERROR) << "querySupportedParams -- "
                                    << "invalid returned ParamDescriptor.";
                         return;
@@ -448,12 +488,12 @@
     return status;
 }
 
-c2_status_t Codec2ConfigurableClient::querySupportedValues(
+c2_status_t Codec2ConfigurableClient::HidlImpl::querySupportedValues(
         std::vector<C2FieldSupportedValuesQuery>& fields,
         c2_blocking_t mayBlock) const {
-    hidl_vec<FieldSupportedValuesQuery> inFields(fields.size());
+    hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
     for (size_t i = 0; i < fields.size(); ++i) {
-        if (!objcpy(&inFields[i], fields[i])) {
+        if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
             LOG(ERROR) << "querySupportedValues -- bad input";
             return C2_TRANSACTION_FAILED;
         }
@@ -464,8 +504,8 @@
             inFields,
             mayBlock == C2_MAY_BLOCK,
             [&status, &inFields, &fields](
-                    Status s,
-                    const hidl_vec<FieldSupportedValuesQueryResult>& r) {
+                    c2_hidl::Status s,
+                    const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     LOG(DEBUG) << "querySupportedValues -- call failed: "
@@ -480,7 +520,7 @@
                     return;
                 }
                 for (size_t i = 0; i < fields.size(); ++i) {
-                    if (!objcpy(&fields[i], inFields[i], r[i])) {
+                    if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
                         LOG(ERROR) << "querySupportedValues -- "
                                       "invalid returned value.";
                         status = C2_CORRUPTED;
@@ -495,14 +535,304 @@
     return status;
 }
 
+// Codec2ConfigurableClient::AidlImpl
+
+struct Codec2ConfigurableClient::AidlImpl : public Codec2ConfigurableClient::ImplBase {
+    typedef c2_aidl::IConfigurable Base;
+
+    // base cannot be null.
+    explicit AidlImpl(const std::shared_ptr<Base>& base);
+
+    const C2String& getName() const override {
+        return mName;
+    }
+
+    c2_status_t query(
+            const std::vector<C2Param*>& stackParams,
+            const std::vector<C2Param::Index> &heapParamIndices,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
+
+    c2_status_t config(
+            const std::vector<C2Param*> &params,
+            c2_blocking_t mayBlock,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
+
+    c2_status_t querySupportedParams(
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+            ) const override;
+
+    c2_status_t querySupportedValues(
+            std::vector<C2FieldSupportedValuesQuery>& fields,
+            c2_blocking_t mayBlock) const override;
+
+private:
+    std::shared_ptr<Base> mBase;
+    const C2String mName;
+};
+
+Codec2ConfigurableClient::AidlImpl::AidlImpl(const std::shared_ptr<Base>& base)
+      : mBase{base},
+        mName{[base]() -> C2String {
+                std::string outName;
+                ndk::ScopedAStatus status = base->getName(&outName);
+                return status.isOk() ? outName : "";
+            }()} {
+}
+
+c2_status_t Codec2ConfigurableClient::AidlImpl::query(
+        const std::vector<C2Param*> &stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
+    std::vector<int> indices(
+            stackParams.size() + heapParamIndices.size());
+    size_t numIndices = 0;
+    for (C2Param* const& stackParam : stackParams) {
+        if (!stackParam) {
+            LOG(WARNING) << "query -- null stack param encountered.";
+            continue;
+        }
+        indices[numIndices++] = int(stackParam->index());
+    }
+    size_t numStackIndices = numIndices;
+    for (const C2Param::Index& index : heapParamIndices) {
+        indices[numIndices++] = int(static_cast<uint32_t>(index));
+    }
+    indices.resize(numIndices);
+    if (heapParams) {
+        heapParams->reserve(heapParams->size() + numIndices);
+    }
+    c2_aidl::Params result;
+    ndk::ScopedAStatus transStatus = mBase->query(indices, (mayBlock == C2_MAY_BLOCK), &result);
+    if (!transStatus.isOk()) {
+        if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
+            LOG(DEBUG) << "query -- call failed: " << status << ".";
+            return status;
+        } else {
+            LOG(ERROR) << "query -- transaction failed.";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+
+    c2_status_t status = C2_OK;
+    std::vector<C2Param*> paramPointers;
+    if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, result)) {
+        LOG(ERROR) << "query -- error while parsing params.";
+        return C2_CORRUPTED;
+    }
+    size_t i = 0;
+    for (auto it = paramPointers.begin();
+            it != paramPointers.end(); ) {
+        C2Param* paramPointer = *it;
+        if (numStackIndices > 0) {
+            --numStackIndices;
+            if (!paramPointer) {
+                LOG(DEBUG) << "query -- null stack param.";
+                ++it;
+                continue;
+            }
+            for (; i < stackParams.size() && !stackParams[i]; ) {
+                ++i;
+            }
+            if (i >= stackParams.size()) {
+                LOG(ERROR) << "query -- unexpected error.";
+                status = C2_CORRUPTED;
+                break;
+            }
+            if (stackParams[i]->index() != paramPointer->index()) {
+                LOG(DEBUG) << "query -- param skipped: "
+                              "index = "
+                           << stackParams[i]->index() << ".";
+                stackParams[i++]->invalidate();
+                // this means that the param could not be queried.
+                // signalling C2_BAD_INDEX to the client.
+                status = C2_BAD_INDEX;
+                continue;
+            }
+            if (!stackParams[i++]->updateFrom(*paramPointer)) {
+                LOG(WARNING) << "query -- param update failed: "
+                                "index = "
+                             << paramPointer->index() << ".";
+            }
+        } else {
+            if (!paramPointer) {
+                LOG(DEBUG) << "query -- null heap param.";
+                ++it;
+                continue;
+            }
+            if (!heapParams) {
+                LOG(WARNING) << "query -- "
+                                "unexpected extra stack param.";
+            } else {
+                heapParams->emplace_back(C2Param::Copy(*paramPointer));
+            }
+        }
+        ++it;
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::AidlImpl::config(
+        const std::vector<C2Param*> &params,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+    c2_aidl::Params aidlParams;
+    if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
+        LOG(ERROR) << "config -- bad input.";
+        return C2_TRANSACTION_FAILED;
+    }
+    c2_aidl::IConfigurable::ConfigResult result;
+    ndk::ScopedAStatus transStatus = mBase->config(aidlParams, (mayBlock == C2_MAY_BLOCK), &result);
+    if (!transStatus.isOk()) {
+        if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
+            LOG(DEBUG) << "config -- call failed: " << status << ".";
+            return status;
+        } else {
+            LOG(ERROR) << "config -- transaction failed.";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+    c2_status_t status = C2_OK;
+    size_t i = failures->size();
+    failures->resize(i + result.failures.size());
+    for (const c2_aidl::SettingResult& sf : result.failures) {
+        if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
+            LOG(ERROR) << "config -- invalid SettingResult returned.";
+            return C2_CORRUPTED;
+        }
+    }
+    if (!c2_aidl::utils::UpdateParamsFromBlob(params, result.params)) {
+        LOG(ERROR) << "config -- "
+                   << "failed to parse returned params.";
+        status = C2_CORRUPTED;
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedParams(
+        std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
+    // TODO: Cache and query properly!
+    std::vector<c2_aidl::ParamDescriptor> result;
+    ndk::ScopedAStatus transStatus = mBase->querySupportedParams(
+            std::numeric_limits<uint32_t>::min(),
+            std::numeric_limits<uint32_t>::max(),
+            &result);
+    if (!transStatus.isOk()) {
+        if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
+            LOG(DEBUG) << "querySupportedParams -- call failed: " << status << ".";
+            return status;
+        } else {
+            LOG(ERROR) << "querySupportedParams -- transaction failed.";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+    c2_status_t status = C2_OK;
+    size_t i = params->size();
+    params->resize(i + result.size());
+    for (const c2_aidl::ParamDescriptor& sp : result) {
+        if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
+            LOG(ERROR) << "querySupportedParams -- invalid returned ParamDescriptor.";
+            return C2_CORRUPTED;
+        }
+    }
+    return status;
+}
+
+c2_status_t Codec2ConfigurableClient::AidlImpl::querySupportedValues(
+        std::vector<C2FieldSupportedValuesQuery>& fields,
+        c2_blocking_t mayBlock) const {
+    std::vector<c2_aidl::FieldSupportedValuesQuery> inFields(fields.size());
+    for (size_t i = 0; i < fields.size(); ++i) {
+        if (!c2_aidl::utils::ToAidl(&inFields[i], fields[i])) {
+            LOG(ERROR) << "querySupportedValues -- bad input";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+
+    std::vector<c2_aidl::FieldSupportedValuesQueryResult> result;
+    ndk::ScopedAStatus transStatus = mBase->querySupportedValues(
+            inFields, (mayBlock == C2_MAY_BLOCK), &result);
+    if (!transStatus.isOk()) {
+        if (transStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            c2_status_t status = static_cast<c2_status_t>(transStatus.getServiceSpecificError());
+            LOG(DEBUG) << "querySupportedValues -- call failed: " << status << ".";
+            return status;
+        } else {
+            LOG(ERROR) << "querySupportedValues -- transaction failed.";
+            return C2_TRANSACTION_FAILED;
+        }
+    }
+    c2_status_t status = C2_OK;
+    if (result.size() != fields.size()) {
+        LOG(ERROR) << "querySupportedValues -- "
+                      "input and output lists "
+                      "have different sizes.";
+        return C2_CORRUPTED;
+    }
+    for (size_t i = 0; i < fields.size(); ++i) {
+        if (!c2_aidl::utils::FromAidl(&fields[i], inFields[i], result[i])) {
+            LOG(ERROR) << "querySupportedValues -- "
+                          "invalid returned value.";
+            return C2_CORRUPTED;
+        }
+    }
+    return status;
+}
+
+// Codec2ConfigurableClient
+
+Codec2ConfigurableClient::Codec2ConfigurableClient(const sp<HidlBase> &hidlBase)
+    : mImpl(new Codec2ConfigurableClient::HidlImpl(hidlBase)) {
+}
+
+Codec2ConfigurableClient::Codec2ConfigurableClient(
+        const std::shared_ptr<AidlBase> &aidlBase)
+    : mImpl(new Codec2ConfigurableClient::AidlImpl(aidlBase)) {
+}
+
+const C2String& Codec2ConfigurableClient::getName() const {
+    return mImpl->getName();
+}
+
+c2_status_t Codec2ConfigurableClient::query(
+        const std::vector<C2Param*>& stackParams,
+        const std::vector<C2Param::Index> &heapParamIndices,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
+    return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
+}
+
+c2_status_t Codec2ConfigurableClient::config(
+        const std::vector<C2Param*> &params,
+        c2_blocking_t mayBlock,
+        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+    return mImpl->config(params, mayBlock, failures);
+}
+
+c2_status_t Codec2ConfigurableClient::querySupportedParams(
+        std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
+    return mImpl->querySupportedParams(params);
+}
+
+c2_status_t Codec2ConfigurableClient::querySupportedValues(
+        std::vector<C2FieldSupportedValuesQuery>& fields,
+        c2_blocking_t mayBlock) const {
+    return mImpl->querySupportedValues(fields, mayBlock);
+}
+
+
 // Codec2Client::Component::HidlListener
-struct Codec2Client::Component::HidlListener : public IComponentListener {
+struct Codec2Client::Component::HidlListener : public c2_hidl::IComponentListener {
     std::weak_ptr<Component> component;
     std::weak_ptr<Listener> base;
 
-    virtual Return<void> onWorkDone(const WorkBundle& workBundle) override {
+    virtual Return<void> onWorkDone(const c2_hidl::WorkBundle& workBundle) override {
         std::list<std::unique_ptr<C2Work>> workItems;
-        if (!objcpy(&workItems, workBundle)) {
+        if (!c2_hidl::utils::objcpy(&workItems, workBundle)) {
             LOG(DEBUG) << "onWorkDone -- received corrupted WorkBundle.";
             return Void();
         }
@@ -521,12 +851,12 @@
     }
 
     virtual Return<void> onTripped(
-            const hidl_vec<SettingResult>& settingResults) override {
+            const hidl_vec<c2_hidl::SettingResult>& settingResults) override {
         std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
                 settingResults.size());
         for (size_t i = 0; i < settingResults.size(); ++i) {
             std::unique_ptr<C2SettingResult> c2SettingResult;
-            if (!objcpy(&c2SettingResult, settingResults[i])) {
+            if (!c2_hidl::utils::objcpy(&c2SettingResult, settingResults[i])) {
                 LOG(DEBUG) << "onTripped -- received corrupted SettingResult.";
                 return Void();
             }
@@ -540,13 +870,13 @@
         return Void();
     }
 
-    virtual Return<void> onError(Status s, uint32_t errorCode) override {
+    virtual Return<void> onError(c2_hidl::Status s, uint32_t errorCode) override {
         LOG(DEBUG) << "onError --"
                    << " status = " << s
                    << ", errorCode = " << errorCode
                    << ".";
         if (std::shared_ptr<Listener> listener = base.lock()) {
-            listener->onError(component, s == Status::OK ?
+            listener->onError(component, s == c2_hidl::Status::OK ?
                     errorCode : static_cast<c2_status_t>(s));
         } else {
             LOG(DEBUG) << "onError -- listener died.";
@@ -617,11 +947,11 @@
         mBase1_1{Base1_1::castFrom(base)},
         mBase1_2{Base1_2::castFrom(base)},
         mServiceIndex{serviceIndex} {
-    Return<sp<IClientManager>> transResult = base->getPoolClientManager();
+    Return<sp<bufferpool_hidl::IClientManager>> transResult = base->getPoolClientManager();
     if (!transResult.isOk()) {
         LOG(ERROR) << "getPoolClientManager -- transaction failed.";
     } else {
-        mHostPoolManager = static_cast<sp<IClientManager>>(transResult);
+        mHostPoolManager = static_cast<sp<bufferpool_hidl::IClientManager>>(transResult);
     }
 }
 
@@ -658,10 +988,10 @@
         transStatus = mBase1_2->createComponent_1_2(
             name,
             hidlListener,
-            ClientManager::getInstance(),
+            bufferpool_hidl::implementation::ClientManager::getInstance(),
             [&status, component, hidlListener](
-                    Status s,
-                    const sp<IComponent>& c) {
+                    c2_hidl::Status s,
+                    const sp<c2_hidl::IComponent>& c) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     return;
@@ -674,10 +1004,10 @@
         transStatus = mBase1_1->createComponent_1_1(
             name,
             hidlListener,
-            ClientManager::getInstance(),
+            bufferpool_hidl::implementation::ClientManager::getInstance(),
             [&status, component, hidlListener](
-                    Status s,
-                    const sp<IComponent>& c) {
+                    c2_hidl::Status s,
+                    const sp<c2_hidl_base::V1_1::IComponent>& c) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     return;
@@ -689,10 +1019,10 @@
         transStatus = mBase1_0->createComponent(
             name,
             hidlListener,
-            ClientManager::getInstance(),
+            bufferpool_hidl::implementation::ClientManager::getInstance(),
             [&status, component, hidlListener](
-                    Status s,
-                    const sp<hardware::media::c2::V1_0::IComponent>& c) {
+                    c2_hidl::Status s,
+                    const sp<c2_hidl_base::V1_0::IComponent>& c) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     return;
@@ -740,8 +1070,8 @@
     Return<void> transStatus = mBase1_0->createInterface(
             name,
             [&status, interface](
-                    Status s,
-                    const sp<IComponentInterface>& i) {
+                    c2_hidl::Status s,
+                    const sp<c2_hidl::IComponentInterface>& i) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     return;
@@ -771,8 +1101,8 @@
     c2_status_t status;
     Return<void> transStatus = mBase1_0->createInputSurface(
             [&status, inputSurface](
-                    Status s,
-                    const sp<IInputSurface>& i) {
+                    c2_hidl::Status s,
+                    const sp<c2_hidl::IInputSurface>& i) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     return;
@@ -798,16 +1128,16 @@
     std::vector<C2Component::Traits> traits;
     std::string const& serviceName = getServiceName();
     Return<void> transStatus = mBase1_0->listComponents(
-            [&traits, &serviceName](Status s,
-                   const hidl_vec<IComponentStore::ComponentTraits>& t) {
-                if (s != Status::OK) {
+            [&traits, &serviceName](c2_hidl::Status s,
+                   const hidl_vec<c2_hidl::IComponentStore::ComponentTraits>& t) {
+                if (s != c2_hidl::Status::OK) {
                     LOG(DEBUG) << "_listComponents -- call failed: "
                                << static_cast<c2_status_t>(s) << ".";
                     return;
                 }
                 traits.resize(t.size());
                 for (size_t i = 0; i < t.size(); ++i) {
-                    if (!objcpy(&traits[i], t[i])) {
+                    if (!c2_hidl::utils::objcpy(&traits[i], t[i])) {
                         LOG(ERROR) << "_listComponents -- corrupted output.";
                         return;
                     }
@@ -839,14 +1169,14 @@
     // should reflect the HAL API.
     struct SimpleParamReflector : public C2ParamReflector {
         virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) const {
-            hidl_vec<ParamIndex> indices(1);
-            indices[0] = static_cast<ParamIndex>(coreIndex.coreIndex());
+            hidl_vec<c2_hidl::ParamIndex> indices(1);
+            indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
             std::unique_ptr<C2StructDescriptor> descriptor;
             Return<void> transStatus = mBase->getStructDescriptors(
                     indices,
                     [&descriptor](
-                            Status s,
-                            const hidl_vec<StructDescriptor>& sd) {
+                            c2_hidl::Status s,
+                            const hidl_vec<c2_hidl::StructDescriptor>& sd) {
                         c2_status_t status = static_cast<c2_status_t>(s);
                         if (status != C2_OK) {
                             LOG(DEBUG) << "SimpleParamReflector -- "
@@ -864,7 +1194,7 @@
                             descriptor.reset();
                             return;
                         }
-                        if (!objcpy(&descriptor, sd[0])) {
+                        if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
                             LOG(DEBUG) << "SimpleParamReflector -- "
                                           "getStructDescriptors() returned "
                                           "corrupted data.";
@@ -1196,11 +1526,11 @@
 // Codec2Client::Interface
 Codec2Client::Interface::Interface(const sp<Base>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IConfigurable>> transResult =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IConfigurable>> transResult =
                         base->getConfigurable();
                 return transResult.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
                         nullptr;
             }()
         },
@@ -1210,17 +1540,17 @@
 // Codec2Client::Component
 Codec2Client::Component::Component(const sp<Base>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IComponentInterface>> transResult1 =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IComponentInterface>> transResult1 =
                         base->getInterface();
                 if (!transResult1.isOk()) {
                     return nullptr;
                 }
-                Return<sp<IConfigurable>> transResult2 =
-                        static_cast<sp<IComponentInterface>>(transResult1)->
+                Return<sp<c2_hidl::IConfigurable>> transResult2 =
+                        static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
                         getConfigurable();
                 return transResult2.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult2) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
                         nullptr;
             }()
         },
@@ -1233,17 +1563,17 @@
 
 Codec2Client::Component::Component(const sp<Base1_1>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IComponentInterface>> transResult1 =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IComponentInterface>> transResult1 =
                         base->getInterface();
                 if (!transResult1.isOk()) {
                     return nullptr;
                 }
-                Return<sp<IConfigurable>> transResult2 =
-                        static_cast<sp<IComponentInterface>>(transResult1)->
+                Return<sp<c2_hidl::IConfigurable>> transResult2 =
+                        static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
                         getConfigurable();
                 return transResult2.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult2) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
                         nullptr;
             }()
         },
@@ -1256,17 +1586,17 @@
 
 Codec2Client::Component::Component(const sp<Base1_2>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IComponentInterface>> transResult1 =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IComponentInterface>> transResult1 =
                         base->getInterface();
                 if (!transResult1.isOk()) {
                     return nullptr;
                 }
-                Return<sp<IConfigurable>> transResult2 =
-                        static_cast<sp<IComponentInterface>>(transResult1)->
+                Return<sp<c2_hidl::IConfigurable>> transResult2 =
+                        static_cast<sp<c2_hidl::IComponentInterface>>(transResult1)->
                         getConfigurable();
                 return transResult2.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult2) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult2) :
                         nullptr;
             }()
         },
@@ -1288,9 +1618,9 @@
     Return<void> transStatus = mBase1_0->createBlockPool(
             static_cast<uint32_t>(id),
             [&status, blockPoolId, configurable](
-                    Status s,
+                    c2_hidl::Status s,
                     uint64_t pId,
-                    const sp<IConfigurable>& c) {
+                    const sp<c2_hidl::IConfigurable>& c) {
                 status = static_cast<c2_status_t>(s);
                 configurable->reset();
                 if (status != C2_OK) {
@@ -1310,13 +1640,13 @@
 
 c2_status_t Codec2Client::Component::destroyBlockPool(
         C2BlockPool::local_id_t localId) {
-    Return<Status> transResult = mBase1_0->destroyBlockPool(
+    Return<c2_hidl::Status> transResult = mBase1_0->destroyBlockPool(
             static_cast<uint64_t>(localId));
     if (!transResult.isOk()) {
         LOG(ERROR) << "destroyBlockPool -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
-    return static_cast<c2_status_t>(static_cast<Status>(transResult));
+    return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
 }
 
 void Codec2Client::Component::handleOnWorkDone(
@@ -1327,18 +1657,18 @@
 
 c2_status_t Codec2Client::Component::queue(
         std::list<std::unique_ptr<C2Work>>* const items) {
-    WorkBundle workBundle;
+    c2_hidl::WorkBundle workBundle;
     if (!objcpy(&workBundle, *items, mBufferPoolSender.get())) {
         LOG(ERROR) << "queue -- bad input.";
         return C2_TRANSACTION_FAILED;
     }
-    Return<Status> transStatus = mBase1_0->queue(workBundle);
+    Return<c2_hidl::Status> transStatus = mBase1_0->queue(workBundle);
     if (!transStatus.isOk()) {
         LOG(ERROR) << "queue -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "queue -- call failed: " << status << ".";
     }
@@ -1352,13 +1682,13 @@
     c2_status_t status;
     Return<void> transStatus = mBase1_0->flush(
             [&status, flushedWork](
-                    Status s, const WorkBundle& wb) {
+                    c2_hidl::Status s, const c2_hidl::WorkBundle& wb) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     LOG(DEBUG) << "flush -- call failed: " << status << ".";
                     return;
                 }
-                if (!objcpy(flushedWork, wb)) {
+                if (!c2_hidl::utils::objcpy(flushedWork, wb)) {
                     status = C2_CORRUPTED;
                 } else {
                     status = C2_OK;
@@ -1391,14 +1721,14 @@
 }
 
 c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
-    Return<Status> transStatus = mBase1_0->drain(
+    Return<c2_hidl::Status> transStatus = mBase1_0->drain(
             mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
     if (!transStatus.isOk()) {
         LOG(ERROR) << "drain -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "drain -- call failed: " << status << ".";
     }
@@ -1406,13 +1736,13 @@
 }
 
 c2_status_t Codec2Client::Component::start() {
-    Return<Status> transStatus = mBase1_0->start();
+    Return<c2_hidl::Status> transStatus = mBase1_0->start();
     if (!transStatus.isOk()) {
         LOG(ERROR) << "start -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "start -- call failed: " << status << ".";
     }
@@ -1420,13 +1750,13 @@
 }
 
 c2_status_t Codec2Client::Component::stop() {
-    Return<Status> transStatus = mBase1_0->stop();
+    Return<c2_hidl::Status> transStatus = mBase1_0->stop();
     if (!transStatus.isOk()) {
         LOG(ERROR) << "stop -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "stop -- call failed: " << status << ".";
     }
@@ -1434,13 +1764,13 @@
 }
 
 c2_status_t Codec2Client::Component::reset() {
-    Return<Status> transStatus = mBase1_0->reset();
+    Return<c2_hidl::Status> transStatus = mBase1_0->reset();
     if (!transStatus.isOk()) {
         LOG(ERROR) << "reset -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "reset -- call failed: " << status << ".";
     }
@@ -1448,13 +1778,13 @@
 }
 
 c2_status_t Codec2Client::Component::release() {
-    Return<Status> transStatus = mBase1_0->release();
+    Return<c2_hidl::Status> transStatus = mBase1_0->release();
     if (!transStatus.isOk()) {
         LOG(ERROR) << "release -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "release -- call failed: " << status << ".";
     }
@@ -1471,7 +1801,7 @@
     c2_status_t status{};
     Return<void> transStatus = mBase1_1->configureVideoTunnel(avSyncHwId,
             [&status, sidebandHandle](
-                    Status s, hardware::hidl_handle const& h) {
+                    c2_hidl::Status s, hardware::hidl_handle const& h) {
                 status = static_cast<c2_status_t>(s);
                 if (h.getNativeHandle()) {
                     *sidebandHandle = native_handle_clone(h.getNativeHandle());
@@ -1550,7 +1880,7 @@
     ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
             generation, (long long)consumerUsage, syncObj ? " sync" : "");
 
-    Return<Status> transStatus = syncObj ?
+    Return<c2_hidl::Status> transStatus = syncObj ?
             mBase1_2->setOutputSurfaceWithSyncObj(
                     static_cast<uint64_t>(blockPoolId),
                     bqId == 0 ? nullHgbp : igbp, *syncObj) :
@@ -1565,7 +1895,7 @@
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "setOutputSurface -- call failed: " << status << ".";
     }
@@ -1593,13 +1923,13 @@
         C2BlockPool::local_id_t blockPoolId) {
     std::scoped_lock lock(mOutputMutex);
     mOutputBufferQueue->stop();
-    Return<Status> transStatus = mBase1_0->setOutputSurface(
+    Return<c2_hidl::Status> transStatus = mBase1_0->setOutputSurface(
             static_cast<uint64_t>(blockPoolId), nullptr);
     if (!transStatus.isOk()) {
         LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed.";
     } else {
         c2_status_t status =
-                static_cast<c2_status_t>(static_cast<Status>(transStatus));
+                static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
         if (status != C2_OK) {
             LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: "
                        << status << ".";
@@ -1615,7 +1945,7 @@
     Return<void> transStatus = mBase1_0->connectToInputSurface(
             inputSurface->mBase,
             [&status, connection](
-                    Status s, const sp<IInputSurfaceConnection>& c) {
+                    c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     LOG(DEBUG) << "connectToInputSurface -- call failed: "
@@ -1639,7 +1969,7 @@
     Return<void> transStatus = mBase1_0->connectToOmxInputSurface(
             producer, source,
             [&status, connection](
-                    Status s, const sp<IInputSurfaceConnection>& c) {
+                    c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) {
                 status = static_cast<c2_status_t>(s);
                 if (status != C2_OK) {
                     LOG(DEBUG) << "connectToOmxInputSurface -- call failed: "
@@ -1656,13 +1986,13 @@
 }
 
 c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
-    Return<Status> transStatus = mBase1_0->disconnectFromInputSurface();
+    Return<c2_hidl::Status> transStatus = mBase1_0->disconnectFromInputSurface();
     if (!transStatus.isOk()) {
         LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
         return C2_TRANSACTION_FAILED;
     }
     c2_status_t status =
-            static_cast<c2_status_t>(static_cast<Status>(transStatus));
+            static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus));
     if (status != C2_OK) {
         LOG(DEBUG) << "disconnectFromInputSurface -- call failed: "
                    << status << ".";
@@ -1709,13 +2039,13 @@
 }
 
 // Codec2Client::InputSurface
-Codec2Client::InputSurface::InputSurface(const sp<IInputSurface>& base)
+Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IConfigurable>> transResult =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IConfigurable>> transResult =
                         base->getConfigurable();
                 return transResult.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
                         nullptr;
             }()
         },
@@ -1735,19 +2065,19 @@
     return mGraphicBufferProducer;
 }
 
-sp<IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
+sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const {
     return mBase;
 }
 
 // Codec2Client::InputSurfaceConnection
 Codec2Client::InputSurfaceConnection::InputSurfaceConnection(
-        const sp<IInputSurfaceConnection>& base)
+        const sp<c2_hidl::IInputSurfaceConnection>& base)
       : Configurable{
-            [base]() -> sp<IConfigurable> {
-                Return<sp<IConfigurable>> transResult =
+            [base]() -> sp<c2_hidl::IConfigurable> {
+                Return<sp<c2_hidl::IConfigurable>> transResult =
                         base->getConfigurable();
                 return transResult.isOk() ?
-                        static_cast<sp<IConfigurable>>(transResult) :
+                        static_cast<sp<c2_hidl::IConfigurable>>(transResult) :
                         nullptr;
             }()
         },
@@ -1755,8 +2085,8 @@
 }
 
 c2_status_t Codec2Client::InputSurfaceConnection::disconnect() {
-    Return<Status> transResult = mBase->disconnect();
-    return static_cast<c2_status_t>(static_cast<Status>(transResult));
+    Return<c2_hidl::Status> transResult = mBase->disconnect();
+    return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult));
 }
 
 }  // namespace android
diff --git a/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
new file mode 100644
index 0000000..681b7e8
--- /dev/null
+++ b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware_buffer.h>
+#include <android-base/unique_fd.h>
+#include <gui/IGraphicBufferProducer.h>
+
+#include <atomic>
+#include <condition_variable>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <thread>
+
+#include <C2Buffer.h>
+
+namespace aidl::android::hardware::media::c2::implementation {
+
+using ::android::IGraphicBufferProducer;
+using ::android::GraphicBuffer;
+using ::android::Fence;
+using ::android::PixelFormat;
+using ::android::sp;
+/**
+ * The class allocates AHardwareBuffer(GraphicBuffer)s using BufferQueue.
+ *
+ * The class tracks and manages outstanding # of allocations for buffer
+ * recycling. So Graphics operations which affects # of outstanding allocation
+ * should be done via the class. (e.g. rendering a buffer to display)
+ *
+ * The class is supposed to be wrapped into IGraphicBufferAllocator AIDL interface,
+ * and the interface will be passed to HAL for a specific BlockPool instance.
+ *
+ * The class has one to one relation with HAL side Graphic C2BlockPool.
+ * The life cycle of the class is tied to a HAL side BlockPool object.
+ *
+ * So, reset()/stop() of HAL which related to blokcpool destruction will terminate the
+ * use of the class. And a new instance should be created in order for start()
+ * of HAL.
+ */
+class GraphicsTracker {
+public:
+    static std::shared_ptr<GraphicsTracker> CreateGraphicsTracker(int maxDequeueCount) {
+        GraphicsTracker *p = new GraphicsTracker(maxDequeueCount);
+        std::shared_ptr<GraphicsTracker> sp(p);
+        return sp;
+    }
+
+    ~GraphicsTracker();
+
+    /**
+     * Configure a new surface to render/allocate graphic blocks.
+     *
+     * Graphic  blocks from the old surface will be migrated to the new surface,
+     * if possible. Configuring to a null surface is possible in the case,
+     * an allocation request will be fulfilled by a direct allocation(not using
+     * BQ). generation should be different to the previous generations.
+     *
+     * @param[in] igbp        the new surface to configure
+     * @param[in] generation  identifier for each configured surface
+     */
+    c2_status_t configureGraphics(const sp<IGraphicBufferProducer>& igbp, uint32_t generation);
+
+    /**
+     * Configure max # of outstanding allocations at any given time.
+     *
+     * @param[in] maxDequeueCount    max # of outstanding allocation to configure
+     */
+    c2_status_t configureMaxDequeueCount(int maxDequeueCount);
+
+    /**
+     * Allocates a AHardwareBuffer.
+     *
+     * @param[in] width       width
+     * @param[in] height      height
+     * @param[in] PixelFormat pixel format which describes color format and etc
+     * @param[in] usage       gralloc usage bits
+     * @param[out] buf        the allocated buffer
+     * @param[out] fence      fence for the allocated buffer
+     * @return  C2_OK         the buffer is allocated
+     *          C2_BAD_STATE  stop() is called and in stopped state
+     *          C2_BLOCKING   should be waited to allocate
+     *          C2_NO_MEMORY  out of memory
+     *          C2_CORRUPTED
+     */
+    c2_status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint64_t usage,
+                         AHardwareBuffer **buf, sp<Fence> *fence);
+
+    /**
+     * Deallocates a AHardwareBuffer
+     *
+     * @param[in] bufId         id of the buffer to deallocate
+     * @param[in] fence         i/o fence for the buffer
+     * @return  C2_OK           the buffer is successfully deallocated.
+     *          C2_DUPLICATE    deallocation/render request is pending already.
+     *          C2_NOT_FOUND    the buffer with the id is not allocated.
+     */
+    c2_status_t deallocate(uint64_t bufId, const sp<Fence> &fence);
+
+    /**
+     * Render a GraphicBlock which is associated to a pending allocated buffer
+     *
+     * @param[in] block         GraphicBlock
+     * @param[in] input         render input params to Graphics
+     * @param[out] output       render output params from Graphics
+     * @return  C2_OK           the buffer is now ready to render
+     *          C2_BAD_STATE    there is no surface to render.
+     *                          (null surface mode or life cycle ends)
+     *          C2_DUPLICATE    deallocation/render request is pending already.
+     *          C2_NOT_FOUND    the buffer with the id is not allocated.
+     *          C2_REFUSED      the buffer is refused to render from Graphics
+     *          C2_CORRUPTED
+     */
+    c2_status_t render(const C2ConstGraphicBlock& block,
+                       const IGraphicBufferProducer::QueueBufferInput& input,
+                       IGraphicBufferProducer::QueueBufferOutput *output);
+
+    /**
+     * Notifies when a Buffer is ready to allocate from Graphics.
+     * If generation does not match to the current, notifications via the interface
+     * will be ignored. (In the case, the notifications are from one of the old surfaces
+     * which is no longer used.)
+     *
+     * @param[in] generation    generation id for specifying Graphics(BQ)
+     */
+    void onReleased(uint32_t generation);
+
+    /**
+     * Get waitable fds for events.(allocate is ready, end of life cycle)
+     *
+     * @param[out]  allocFd     eventFd which signals being ready to allocate
+     * @param[out]  statusFd    eventFd which signals end of life cycle.
+     *                          When signaled no more allocate is possible.
+     * @return  C2_OK
+     *          C2_NO_MEMORY    Max # of fd reached.(not really a memory issue)
+     */
+    c2_status_t getWaitableFds(int *allocFd, int *statusFd);
+
+    /**
+     *  Ends to use the class. after the call, allocate will fail.
+     */
+    void stop();
+
+private:
+    static constexpr int kDefaultMaxDequeue = 2;
+
+    struct BufferCache;
+
+    struct BufferItem {
+        bool mInit;
+        uint64_t mId;
+        uint32_t mGeneration;
+        int mSlot;
+        AHardwareBuffer *mBuf;
+        uint64_t mUsage; // Gralloc usage format, not AHB
+        sp<Fence> mFence;
+
+        // Create from a GraphicBuffer
+        BufferItem(uint32_t generation, int slot,
+                   const sp<GraphicBuffer>& buf,
+                   const sp<Fence> &fence);
+
+        // Create from an AHB (no slot information)
+        // Should be attached to IGBP for rendering
+        BufferItem(uint32_t generation,
+                   AHardwareBuffer_Desc *desc,
+                   AHardwareBuffer *pBuf);
+
+        ~BufferItem();
+
+        sp<GraphicBuffer> updateBuffer(uint64_t newUsage, uint32_t newGeneration);
+    };
+
+    struct BufferCache {
+        static constexpr int kNumSlots = ::android::BufferQueueDefs::NUM_BUFFER_SLOTS;
+
+        uint64_t mBqId;
+        uint32_t mGeneration;
+        ::android::sp<IGraphicBufferProducer> mIgbp;
+
+        // Maps slotId to buffer
+        // IGBP::dequeueBuffer(), IGBP::queueBuffer() and IGBP::cancelBuffer()
+        // require slotId.
+        std::map<int, std::shared_ptr<BufferItem>> mBuffers;
+
+        // block slot use, while deallocating(cancel, render and etc)
+        struct BlockedSlot {
+            std::mutex l;
+            std::condition_variable cv;
+            bool blocked;
+            BlockedSlot() : blocked{false} {}
+            ~BlockedSlot() = default;
+        };
+
+        BlockedSlot mBlockedSlots[kNumSlots];
+
+        BufferCache() : mBqId{0ULL}, mGeneration{0}, mIgbp{nullptr} {}
+        BufferCache(uint64_t bqId, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) :
+            mBqId{bqId}, mGeneration{generation}, mIgbp{igbp} {}
+
+        void waitOnSlot(int slot);
+
+        void blockSlot(int slot);
+
+        void unblockSlot(int slot);
+    };
+
+    std::shared_ptr<BufferCache> mBufferCache;
+    // Maps bufferId to buffer
+    std::map<uint64_t, std::shared_ptr<BufferItem>> mDequeued;
+    std::set<uint64_t> mDeallocating;
+
+    int mMaxDequeue;
+    int mMaxDequeueRequested;
+    int mMaxDequeueCommitted;
+
+    uint32_t mMaxDequeueRequestedSeqId;
+    uint32_t mMaxDequeueCommittedSeqId;
+
+    int mDequeueable;
+
+    // TODO: statistics
+    uint64_t mTotalDequeued;
+    //uint64_t mTotalQueued;
+    uint64_t mTotalCancelled;
+    uint64_t mTotalDropped;
+    uint64_t mTotalReleased;
+
+    bool mInConfig;
+    std::mutex mLock; // locks for data synchronization
+    std::mutex mConfigLock; // locks for configuration change.
+
+    std::atomic<bool> mStopped;
+
+    ::android::base::unique_fd mAllocEventFd; // eventfd in semaphore mode which
+                                              // mirrors mDqueueable.
+    ::android::base::unique_fd mStopEventFd; // eventfd which indicates the life
+                                             // cycle of the class being stopped.
+
+    std::thread mEventQueueThread; // Thread to handle interrupted
+                                   // writes to eventfd{s}.
+    std::mutex mEventLock;
+    std::condition_variable mEventCv;
+
+    bool mStopEventThread;
+    int mIncDequeueable; // pending # of write to increase dequeueable eventfd
+    bool mStopRequest; // pending write to statusfd
+
+private:
+    explicit GraphicsTracker(int maxDequeueCount);
+
+    // return {@code true} only when dequeue config adjust happened.
+    // {@code updateDequeueConf} is an output parameter, and returns
+    // {@code true} only when the current dequeue conf is required to be
+    // updated to IGBP(BQ) as a result of the adjust.
+    bool adjustDequeueConfLocked(bool *updateDequeueConf);
+
+    void updateDequeueConf();
+
+    c2_status_t requestAllocate(std::shared_ptr<BufferCache> *cache);
+    c2_status_t requestDeallocate(uint64_t bid, const sp<Fence> &fence,
+                                  bool *completed, bool *updateDequeue,
+                                  std::shared_ptr<BufferCache> *cache, int *slotId,
+                                  sp<Fence> *rFence);
+    c2_status_t requestRender(uint64_t bid, std::shared_ptr<BufferCache> *cache,
+                              std::shared_ptr<BufferItem> *pBuffer,
+                              bool *updateDequeue);
+
+    void commitAllocate(c2_status_t res,
+                        const std::shared_ptr<BufferCache> &cache,
+                        bool cached, int slotId, const sp<Fence> &fence,
+                        std::shared_ptr<BufferItem> *buffer,
+                        bool *updateDequeue);
+    void commitDeallocate(std::shared_ptr<BufferCache> &cache, int slotId, uint64_t bid);
+    void commitRender(uint64_t origBid,
+                      const std::shared_ptr<BufferCache> &cache,
+                      const std::shared_ptr<BufferItem> &buffer,
+                      bool *updateDequeue);
+
+    c2_status_t _allocate(
+            const std::shared_ptr<BufferCache> &cache,
+            uint32_t width, uint32_t height, PixelFormat format, int64_t usage,
+            bool *cached, int *rSlotId, sp<Fence> *rFence,
+            std::shared_ptr<BufferItem> *buffer);
+
+    void writeIncDequeueable(int inc);
+    void processEvent();
+};
+
+} // namespace aidl::android::hardware::media::c2::implementation
diff --git a/media/codec2/hal/client/include/codec2/hidl/client.h b/media/codec2/hal/client/include/codec2/hidl/client.h
index 5267394..6fa19b0 100644
--- a/media/codec2/hal/client/include/codec2/hidl/client.h
+++ b/media/codec2/hal/client/include/codec2/hidl/client.h
@@ -84,6 +84,13 @@
 struct IComponentStore;
 }  // namespace android::hardware::media::c2::V1_2
 
+namespace aidl::android::hardware::media::c2 {
+class IComponent;
+class IComponentInterface;
+class IComponentStore;
+class IConfigurable;
+}  // namespace aidl::android::hardware::media::c2
+
 namespace android::hardware::media::bufferpool::V2_0 {
 struct IClientManager;
 }  // namespace android::hardware::media::bufferpool::V2_0
@@ -106,7 +113,36 @@
 // declaration of an inner class is not possible.
 struct Codec2ConfigurableClient {
 
-    typedef ::android::hardware::media::c2::V1_0::IConfigurable Base;
+    typedef ::android::hardware::media::c2::V1_0::IConfigurable HidlBase;
+    typedef ::aidl::android::hardware::media::c2::IConfigurable AidlBase;
+
+    struct ImplBase {
+        virtual ~ImplBase() = default;
+
+        virtual const C2String& getName() const = 0;
+
+        virtual c2_status_t query(
+                const std::vector<C2Param*>& stackParams,
+                const std::vector<C2Param::Index> &heapParamIndices,
+                c2_blocking_t mayBlock,
+                std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
+
+        virtual c2_status_t config(
+                const std::vector<C2Param*> &params,
+                c2_blocking_t mayBlock,
+                std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
+
+        virtual c2_status_t querySupportedParams(
+                std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+                ) const = 0;
+
+        virtual c2_status_t querySupportedValues(
+                std::vector<C2FieldSupportedValuesQuery>& fields,
+                c2_blocking_t mayBlock) const = 0;
+    };
+
+    explicit Codec2ConfigurableClient(const sp<HidlBase> &hidlBase);
+    explicit Codec2ConfigurableClient(const std::shared_ptr<AidlBase> &aidlBase);
 
     const C2String& getName() const;
 
@@ -128,15 +164,11 @@
     c2_status_t querySupportedValues(
             std::vector<C2FieldSupportedValuesQuery>& fields,
             c2_blocking_t mayBlock) const;
+private:
+    struct HidlImpl;
+    struct AidlImpl;
 
-    // base cannot be null.
-    Codec2ConfigurableClient(const sp<Base>& base);
-
-protected:
-    sp<Base> mBase;
-    C2String mName;
-
-    friend struct Codec2Client;
+    const std::unique_ptr<ImplBase> mImpl;
 };
 
 struct Codec2Client : public Codec2ConfigurableClient {
diff --git a/media/codec2/hal/common/Android.bp b/media/codec2/hal/common/Android.bp
new file mode 100644
index 0000000..f0193d7
--- /dev/null
+++ b/media/codec2/hal/common/Android.bp
@@ -0,0 +1,30 @@
+cc_library {
+    name: "libcodec2_hal_common",
+    double_loadable: true,
+    vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+
+    srcs: [
+        "BufferTypes.cpp",
+    ],
+
+    export_include_dirs: ["include/"],
+
+    header_libs: [
+        "libcodec2_internal", // private
+        "libgui_headers",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcodec2",
+        "libcodec2_vndk",
+        "liblog",
+        "libstagefright_foundation",
+    ],
+}
diff --git a/media/codec2/hal/common/BufferTypes.cpp b/media/codec2/hal/common/BufferTypes.cpp
new file mode 100644
index 0000000..f10a195
--- /dev/null
+++ b/media/codec2/hal/common/BufferTypes.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-BufferTypes"
+#include <android-base/logging.h>
+
+#include <codec2/common/BufferTypes.h>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2FenceFactory.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+
+namespace android {
+
+// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool CreateLinearBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2LinearBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hal_RangeInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2LinearBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hal_RangeInfo)) {
+        LOG(ERROR) << "Invalid range info in C2LinearBlock.";
+        return false;
+    }
+    C2Hal_RangeInfo *rangeInfo =
+            reinterpret_cast<C2Hal_RangeInfo*>(meta[0]);
+
+    // Create C2Buffer from C2LinearBlock.
+    *buffer = C2Buffer::CreateLinearBuffer(block->share(
+            rangeInfo->offset, rangeInfo->length,
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateLinearBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool CreateGraphicBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2GraphicBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence) {
+    // Check the block meta. It should have exactly 1 C2Info:
+    // C2Hal_RectInfo.
+    if ((meta.size() != 1) || !meta[0]) {
+        LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
+        return false;
+    }
+    if (meta[0]->size() != sizeof(C2Hal_RectInfo)) {
+        LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
+        return false;
+    }
+    C2Hal_RectInfo *rectInfo =
+            reinterpret_cast<C2Hal_RectInfo*>(meta[0]);
+
+    // Create C2Buffer from C2GraphicBlock.
+    *buffer = C2Buffer::CreateGraphicBuffer(block->share(
+            C2Rect(rectInfo->width, rectInfo->height).
+            at(rectInfo->left, rectInfo->top),
+            fence));
+    if (!(*buffer)) {
+        LOG(ERROR) << "CreateGraphicBuffer failed.";
+        return false;
+    }
+    return true;
+}
+
+namespace /* unnamed */ {
+
+template <typename BlockProcessor>
+void forEachBlock(C2FrameData& frameData,
+                  BlockProcessor process) {
+    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
+        if (buffer) {
+            for (const C2ConstGraphicBlock& block :
+                    buffer->data().graphicBlocks()) {
+                process(block);
+            }
+        }
+    }
+}
+
+template <typename BlockProcessor>
+void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
+                  BlockProcessor process,
+                  bool processInput, bool processOutput) {
+    for (const std::unique_ptr<C2Work>& work : workList) {
+        if (!work) {
+            continue;
+        }
+        if (processInput) {
+            forEachBlock(work->input, process);
+        }
+        if (processOutput) {
+            for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+                if (worklet) {
+                    forEachBlock(worklet->output,
+                                 process);
+                }
+            }
+        }
+    }
+}
+
+} // unnamed namespace
+
+bool BeginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::BeginTransferBlockToClient(data);
+        return true;
+    }
+    return false;
+}
+
+void BeginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList, BeginTransferBufferQueueBlock,
+                 processInput, processOutput);
+}
+
+bool EndTransferBufferQueueBlock(
+        const C2ConstGraphicBlock& block,
+        bool transfer) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::EndTransferBlockToClient(data, transfer);
+        return true;
+    }
+    return false;
+}
+
+void EndTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput, bool processOutput) {
+    forEachBlock(workList,
+                 std::bind(EndTransferBufferQueueBlock,
+                           std::placeholders::_1, transfer),
+                 processInput, processOutput);
+}
+
+bool DisplayBufferQueueBlock(const C2ConstGraphicBlock& block) {
+    std::shared_ptr<_C2BlockPoolData> data =
+            _C2BlockFactory::GetGraphicBlockPoolData(block);
+    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
+        _C2BlockFactory::DisplayBlockToBufferQueue(data);
+        return true;
+    }
+    return false;
+}
+
+}  // namespace android
+
diff --git a/media/codec2/hal/common/include/codec2/common/BufferPoolSender.h b/media/codec2/hal/common/include/codec2/common/BufferPoolSender.h
new file mode 100644
index 0000000..a9e5942
--- /dev/null
+++ b/media/codec2/hal/common/include/codec2/common/BufferPoolSender.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_COMMON_BUFFER_POOL_SENDER_H
+#define CODEC2_COMMON_BUFFER_POOL_SENDER_H
+
+#include <memory>
+
+namespace android {
+
+// Template class to be used in
+// objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+template <typename BufferPoolTypes>
+struct BufferPoolSender {
+    // BufferPoolTypes should define the following types:
+    typedef typename BufferPoolTypes::BufferPoolData        BufferPoolData;
+    typedef typename BufferPoolTypes::ResultStatus          ResultStatus;
+    typedef typename BufferPoolTypes::BufferPoolStatus      BufferPoolStatus;
+    typedef typename BufferPoolTypes::BufferStatusMessage   BufferStatusMessage;
+
+    /**
+     * Send bpData and return BufferStatusMessage that can be supplied to
+     * IClientManager::receive() in the receiving process.
+     *
+     * This function will be called from within the function
+     * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
+     *
+     * \param[in] bpData BufferPoolData identifying the buffer to send.
+     * \param[out] bpMessage BufferStatusMessage of the transaction. Information
+     *    inside \p bpMessage should be passed to the receiving process by some
+     *    other means so it can call receive() properly.
+     * \return ResultStatus value that determines the success of the operation.
+     *    (See the possible values of ResultStatus in
+     *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
+     */
+    virtual BufferPoolStatus send(
+            const std::shared_ptr<BufferPoolData>& bpData,
+            BufferStatusMessage* bpMessage) = 0;
+
+    virtual ~BufferPoolSender() = default;
+};
+
+}  // namespace android
+
+#endif  // CODEC2_COMMON_BUFFER_POOL_SENDER_H
diff --git a/media/codec2/hal/common/include/codec2/common/BufferTypes.h b/media/codec2/hal/common/include/codec2/common/BufferTypes.h
new file mode 100644
index 0000000..8998a6d
--- /dev/null
+++ b/media/codec2/hal/common/include/codec2/common/BufferTypes.h
@@ -0,0 +1,863 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_COMMON_BUFFER_TYPES_H
+#define CODEC2_COMMON_BUFFER_TYPES_H
+
+#ifndef LOG_TAG
+#define LOG_TAG "Codec2-BufferTypes"
+#endif
+#include <android-base/logging.h>
+
+#include <codec2/common/BufferPoolSender.h>
+#include <codec2/common/ParamTypes.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2AllocatorIon.h>
+#include <C2AllocatorGralloc.h>
+#include <C2BlockInternal.h>
+#include <C2Buffer.h>
+#include <C2Component.h>
+#include <C2FenceFactory.h>
+#include <C2Param.h>
+#include <C2ParamDef.h>
+#include <C2PlatformSupport.h>
+#include <C2Work.h>
+
+#include <algorithm>
+#include <functional>
+#include <iomanip>
+#include <map>
+
+namespace android {
+
+// Types of metadata for Blocks.
+struct C2Hal_Range {
+    uint32_t offset;
+    uint32_t length; // Do not use "size" because the name collides with C2Info::size().
+};
+typedef C2GlobalParam<C2Info, C2Hal_Range, 0> C2Hal_RangeInfo;
+
+struct C2Hal_Rect {
+    uint32_t left;
+    uint32_t top;
+    uint32_t width;
+    uint32_t height;
+};
+typedef C2GlobalParam<C2Info, C2Hal_Rect, 1> C2Hal_RectInfo;
+
+// Note: The handle is not cloned.
+template <typename BaseBlock>
+void SetHandle(BaseBlock *baseBlock, const C2Handle *handle);
+
+template <typename BufferPoolTypes, typename BaseBlock>
+void SetPooledBlock(
+        BaseBlock *baseBlock,
+        const typename BufferPoolTypes::BufferStatusMessage &pooledBlock);
+
+template <typename BufferPoolTypes>
+bool GetBufferPoolData(
+        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
+        std::shared_ptr<typename BufferPoolTypes::BufferPoolData> *bpData);
+
+// Find or add a HAL BaseBlock object from a given C2Handle* to a list and an
+// associated map.
+// Note: The handle is not cloned.
+template <typename BaseBlock>
+bool _addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!handle) {
+        LOG(ERROR) << "addBaseBlock called on a null C2Handle.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(handle);
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(handle, *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+        SetHandle(&dBaseBlock, handle);
+    }
+    return true;
+}
+
+// Find or add a hidl BaseBlock object from a given BufferPoolData to a list and
+// an associated map.
+template <typename BufferPoolTypes, typename BaseBlock>
+bool _addBaseBlock(
+        uint32_t* index,
+        const std::shared_ptr<typename BufferPoolTypes::BufferPoolData> &bpData,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!bpData) {
+        LOG(ERROR) << "addBaseBlock called on a null BufferPoolData.";
+        return false;
+    }
+    auto it = baseBlockIndices->find(bpData.get());
+    if (it != baseBlockIndices->end()) {
+        *index = it->second;
+    } else {
+        *index = baseBlocks->size();
+        baseBlockIndices->emplace(bpData.get(), *index);
+        baseBlocks->emplace_back();
+
+        BaseBlock &dBaseBlock = baseBlocks->back();
+
+        if (bufferPoolSender) {
+            typename BufferPoolTypes::BufferStatusMessage pooledBlock;
+            typename BufferPoolTypes::BufferPoolStatus bpStatus =
+                bufferPoolSender->send(bpData, &pooledBlock);
+
+            if (bpStatus != BufferPoolTypes::ResultStatus::OK) {
+                LOG(ERROR) << "Failed to send buffer with BufferPool. Error: "
+                           << static_cast<int32_t>(bpStatus)
+                           << ".";
+                return false;
+            }
+            SetPooledBlock<BufferPoolTypes>(&dBaseBlock, pooledBlock);
+        }
+    }
+    return true;
+}
+
+template <typename BufferPoolTypes, typename BaseBlock>
+bool addBaseBlock(
+        uint32_t* index,
+        const C2Handle* handle,
+        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!blockPoolData) {
+        // No BufferPoolData ==> NATIVE block.
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    }
+    switch (blockPoolData->getType()) {
+    case _C2BlockPoolData::TYPE_BUFFERPOOL: {
+            // BufferPoolData
+            std::shared_ptr<typename BufferPoolTypes::BufferPoolData> bpData;
+            if (!GetBufferPoolData<BufferPoolTypes>(blockPoolData, &bpData) || !bpData) {
+                LOG(ERROR) << "BufferPoolData unavailable in a block.";
+                return false;
+            }
+            return _addBaseBlock(
+                    index, bpData,
+                    bufferPoolSender, baseBlocks, baseBlockIndices);
+        }
+    case _C2BlockPoolData::TYPE_BUFFERQUEUE:
+        uint32_t gen;
+        uint64_t bqId;
+        int32_t bqSlot;
+        // Update handle if migration happened.
+        if (_C2BlockFactory::GetBufferQueueData(
+                blockPoolData, &gen, &bqId, &bqSlot)) {
+            android::MigrateNativeCodec2GrallocHandle(
+                    const_cast<native_handle_t*>(handle), gen, bqId, bqSlot);
+        }
+        return _addBaseBlock(
+                index, handle,
+                baseBlocks, baseBlockIndices);
+    default:
+        LOG(ERROR) << "Unknown C2BlockPoolData type.";
+        return false;
+    }
+}
+
+// C2Fence -> Handle
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+template <typename Handle>
+bool objcpy(Handle* d, const C2Fence& s) {
+    d->setTo(nullptr);
+    native_handle_t* handle = _C2FenceFactory::CreateNativeHandle(s);
+    if (handle) {
+        d->setTo(handle, true /* owns */);
+//  } else if (!s.ready()) {
+//      // TODO: we should wait for unmarshallable fences but this may not be
+//      // the best place for it. We can safely ignore here as at this time
+//      // all fences used here are marshallable.
+    }
+    return true;
+}
+
+// C2ConstLinearBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+template <typename Block, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(Block* d, const C2ConstLinearBlock& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetLinearBlockPoolData(s);
+    if (!addBaseBlock((uint32_t *)&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hal_RangeInfo dRangeInfo;
+    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
+    dRangeInfo.length = static_cast<uint32_t>(s.size());
+    if (!_createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRangeInfo })) {
+        LOG(ERROR) << "Invalid range info in C2ConstLinearBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstLinearBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2ConstGraphicBlock -> Block
+// Note: Native handles are not duplicated. The original handles must not be
+// closed before the transaction is complete.
+template <typename Block, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(Block* d, const C2ConstGraphicBlock& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    std::shared_ptr<const _C2BlockPoolData> bpData =
+            _C2BlockFactory::GetGraphicBlockPoolData(s);
+    if (!addBaseBlock((uint32_t *)&d->index, s.handle(), bpData,
+            bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid block data in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Create the metadata.
+    C2Hal_RectInfo dRectInfo;
+    C2Rect sRect = s.crop();
+    dRectInfo.left = static_cast<uint32_t>(sRect.left);
+    dRectInfo.top = static_cast<uint32_t>(sRect.top);
+    dRectInfo.width = static_cast<uint32_t>(sRect.width);
+    dRectInfo.height = static_cast<uint32_t>(sRect.height);
+    if (!_createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRectInfo })) {
+        LOG(ERROR) << "Invalid rect info in C2ConstGraphicBlock.";
+        return false;
+    }
+
+    // Copy the fence
+    if (!objcpy(&d->fence, s.fence())) {
+        LOG(ERROR) << "Invalid C2ConstGraphicBlock::fence.";
+        return false;
+    }
+    return true;
+}
+
+// C2BufferData -> Buffer
+// This function only fills in d->blocks.
+template <typename Buffer, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(Buffer* d, const C2BufferData& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->blocks.resize(
+            s.linearBlocks().size() +
+            s.graphicBlocks().size());
+    size_t i = 0;
+    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
+        auto& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, linearBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::linearBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
+        auto& dBlock = d->blocks[i++];
+        if (!objcpy(
+                &dBlock, graphicBlock,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2BufferData::graphicBlocks. "
+                       << "(Destination index = " << i - 1 << ".)";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2Buffer -> Buffer
+template <typename Buffer, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(Buffer* d, const C2Buffer& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    if (!_createParamsBlob(&d->info, s.info())) {
+        LOG(ERROR) << "Invalid C2Buffer::info.";
+        return false;
+    }
+    if (!objcpy(d, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2Buffer::data.";
+        return false;
+    }
+    return true;
+}
+
+// C2InfoBuffer -> InfoBuffer
+template <typename InfoBuffer, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(InfoBuffer* d, const C2InfoBuffer& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->index = static_cast<decltype(d->index)>(s.index());
+    auto& dBuffer = d->buffer;
+    if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2InfoBuffer::data";
+        return false;
+    }
+    return true;
+}
+
+// C2FrameData -> FrameData
+template <typename FrameData, typename BufferPoolTypes, typename BaseBlock>
+bool objcpy(FrameData* d, const C2FrameData& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender,
+        std::list<BaseBlock>* baseBlocks,
+        std::map<const void*, uint32_t>* baseBlockIndices) {
+    d->flags = static_cast<decltype(d->flags)>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid C2FrameData::ordinal.";
+        return false;
+    }
+
+    d->buffers.resize(s.buffers.size());
+    size_t i = 0;
+    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
+        auto& dBuffer = d->buffers[i++];
+        if (!sBuffer) {
+            // A null (pointer to) C2Buffer corresponds to a Buffer with empty
+            // info and blocks.
+            auto *dInfo = GetBlob(&dBuffer.info);
+            dInfo->resize(0);
+            dBuffer.blocks.resize(0);
+            continue;
+        }
+        if (!objcpy(
+                &dBuffer, *sBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::buffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    if (!_createParamsBlob(&d->configUpdate, s.configUpdate)) {
+        LOG(ERROR) << "Invalid C2FrameData::configUpdate.";
+        return false;
+    }
+
+    d->infoBuffers.resize(s.infoBuffers.size());
+    i = 0;
+    for (const C2InfoBuffer& sInfoBuffer : s.infoBuffers) {
+        auto& dInfoBuffer = d->infoBuffers[i++];
+        if (!objcpy(&dInfoBuffer, sInfoBuffer,
+                bufferPoolSender, baseBlocks, baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// std::list<std::unique_ptr<C2Work>> -> WorkBundle
+template <typename WorkBundle, typename BufferPoolTypes>
+bool objcpy(
+        WorkBundle* d,
+        const std::list<std::unique_ptr<C2Work>>& s,
+        BufferPoolSender<BufferPoolTypes>* bufferPoolSender) {
+    // baseBlocks holds a list of BaseBlock objects that Blocks can refer to.
+    std::list<typename decltype(d->baseBlocks)::value_type> baseBlocks;
+
+    // baseBlockIndices maps a raw pointer to native_handle_t or BufferPoolData
+    // inside baseBlocks to the corresponding index into baseBlocks. The keys
+    // (pointers) are used to identify blocks that have the same "base block" in
+    // s, a list of C2Work objects. Because baseBlocks will be copied into a
+    // hidl_vec eventually, the values of baseBlockIndices are zero-based
+    // integer indices instead of list iterators.
+    //
+    // Note that the pointers can be raw because baseBlockIndices has a shorter
+    // lifespan than all of base blocks.
+    std::map<const void*, uint32_t> baseBlockIndices;
+
+    d->works.resize(s.size());
+    size_t i = 0;
+    for (const std::unique_ptr<C2Work>& sWork : s) {
+        auto &dWork = d->works[i++];
+        if (!sWork) {
+            LOG(WARNING) << "Null C2Work encountered.";
+            continue;
+        }
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork->input,
+                bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+            LOG(ERROR) << "Invalid C2Work::input.";
+            return false;
+        }
+
+        // worklets
+        if (sWork->worklets.size() == 0) {
+            LOG(DEBUG) << "Work with no worklets.";
+        } else {
+            // Parcel the worklets.
+            auto &dWorklets = dWork.worklets;
+            dWorklets.resize(sWork->worklets.size());
+            size_t j = 0;
+            for (const std::unique_ptr<C2Worklet>& sWorklet : sWork->worklets)
+            {
+                if (!sWorklet) {
+                    LOG(WARNING) << "Null C2Work::worklets["
+                                 << j << "].";
+                    continue;
+                }
+                auto &dWorklet = dWorklets[j++];
+
+                // component id
+                dWorklet.componentId = static_cast<uint32_t>(
+                        sWorklet->component);
+
+                // tunings
+                if (!_createParamsBlob(&dWorklet.tunings, sWorklet->tunings)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->tunings.";
+                    return false;
+                }
+
+                // failures
+                dWorklet.failures.resize(sWorklet->failures.size());
+                size_t k = 0;
+                for (const std::unique_ptr<C2SettingResult>& sFailure :
+                        sWorklet->failures) {
+                    if (!sFailure) {
+                        LOG(WARNING) << "Null C2Work::worklets["
+                                     << j - 1 << "]->failures["
+                                     << k << "].";
+                        continue;
+                    }
+                    if (!objcpy(&dWorklet.failures[k++], *sFailure)) {
+                        LOG(ERROR) << "Invalid C2Work::worklets["
+                                   << j - 1 << "]->failures["
+                                   << k - 1 << "].";
+                        return false;
+                    }
+                }
+
+                // output
+                if (!objcpy(&dWorklet.output, sWorklet->output,
+                        bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
+                    LOG(ERROR) << "Invalid C2Work::worklets["
+                               << j - 1 << "]->output.";
+                    return false;
+                }
+            }
+        }
+
+        // worklets processed
+        dWork.workletsProcessed = sWork->workletsProcessed;
+
+        // result
+        SetStatus(&dWork.result, sWork->result);
+    }
+
+    // Move std::list<BaseBlock> to vector<BaseBlock>.
+    {
+        d->baseBlocks.resize(baseBlocks.size());
+        size_t i = 0;
+        for (auto&& baseBlock : baseBlocks) {
+            d->baseBlocks[i++] = std::move(baseBlock);
+        }
+    }
+
+    return true;
+}
+
+struct C2BaseBlock {
+    enum type_t {
+        LINEAR,
+        GRAPHIC,
+    };
+    type_t type;
+    std::shared_ptr<C2LinearBlock> linear;
+    std::shared_ptr<C2GraphicBlock> graphic;
+};
+
+// Handle -> C2Fence
+// Note: File descriptors are not duplicated. The original file descriptor must
+// not be closed before the transaction is complete.
+template <typename Handle>
+bool objcpy(C2Fence* d, const Handle& s) {
+    const native_handle_t* handle = s.getNativeHandle();
+    *d = _C2FenceFactory::CreateFromNativeHandle(handle);
+    return true;
+}
+
+// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool CreateLinearBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2LinearBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence);
+
+// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
+bool CreateGraphicBuffer(
+        std::shared_ptr<C2Buffer>* buffer,
+        const std::shared_ptr<C2GraphicBlock>& block,
+        const std::vector<C2Param*>& meta,
+        const C2Fence& fence);
+
+// Buffer -> C2Buffer
+// Note: The native handles will be cloned.
+template <typename Buffer>
+bool objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    *d = nullptr;
+
+    // Currently, a non-null C2Buffer must contain exactly 1 block.
+    if (s.blocks.size() == 0) {
+        return true;
+    } else if (s.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid Buffer: "
+                      "Currently, a C2Buffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const auto &sBlock = s.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (!CreateLinearBuffer(d, baseBlock.linear, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::linear.";
+            return false;
+        }
+        break;
+    case C2BaseBlock::GRAPHIC:
+        if (!CreateGraphicBuffer(d, baseBlock.graphic, sBlockMeta, dFence)) {
+            LOG(ERROR) << "Invalid C2BaseBlock::graphic.";
+            return false;
+        }
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type.";
+        return false;
+    }
+
+    // Parse info
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.info)) {
+        LOG(ERROR) << "Invalid Buffer::info.";
+        return false;
+    }
+    for (C2Param* param : params) {
+        if (param == nullptr) {
+            LOG(ERROR) << "Null param in Buffer::info.";
+            return false;
+        }
+        std::shared_ptr<C2Param> c2param{
+                C2Param::Copy(*param).release()};
+        if (!c2param) {
+            LOG(ERROR) << "Invalid param in Buffer::info.";
+            return false;
+        }
+        c2_status_t status =
+                (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
+        if (status != C2_OK) {
+            LOG(ERROR) << "C2Buffer::setInfo failed.";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// InfoBuffer -> C2InfoBuffer
+template <typename InfoBuffer>
+bool objcpy(
+        std::vector<C2InfoBuffer> *d,
+        const InfoBuffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+
+    // Currently, a non-null C2InfoBufer must contain exactly 1 block.
+    if (s.buffer.blocks.size() == 0) {
+        return true;
+    } else if (s.buffer.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer "
+                      "Currently, a C2InfoBuffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const auto &sBlock = s.buffer.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
+            sBlockMeta[0]->size() == sizeof(C2Hal_RangeInfo)) {
+            C2Hal_RangeInfo *rangeInfo =
+                    reinterpret_cast<C2Hal_RangeInfo*>(sBlockMeta[0]);
+            d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
+                    uint32_t(s.index),
+                    baseBlock.linear->share(
+                            rangeInfo->offset, rangeInfo->length, dFence)));
+            return true;
+        }
+        LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
+        break;
+    case C2BaseBlock::GRAPHIC:
+        // It's not used now
+        LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
+        break;
+    }
+
+    return false;
+}
+
+// FrameData -> C2FrameData
+template <typename FrameData>
+bool objcpy(C2FrameData* d, const FrameData& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
+    if (!objcpy(&d->ordinal, s.ordinal)) {
+        LOG(ERROR) << "Invalid FrameData::ordinal.";
+        return false;
+    }
+    d->buffers.clear();
+    d->buffers.reserve(s.buffers.size());
+    for (const auto& sBuffer : s.buffers) {
+        std::shared_ptr<C2Buffer> dBuffer;
+        if (!objcpy(&dBuffer, sBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid FrameData::buffers.";
+            return false;
+        }
+        d->buffers.emplace_back(dBuffer);
+    }
+
+    std::vector<C2Param*> params;
+    if (!parseParamsBlob(&params, s.configUpdate)) {
+        LOG(ERROR) << "Invalid FrameData::configUpdate.";
+        return false;
+    }
+    d->configUpdate.clear();
+    for (C2Param* param : params) {
+        d->configUpdate.emplace_back(C2Param::Copy(*param));
+        if (!d->configUpdate.back()) {
+            LOG(ERROR) << "Unexpected error while parsing "
+                          "FrameData::configUpdate.";
+            return false;
+        }
+    }
+
+    d->infoBuffers.clear();
+    if (s.infoBuffers.size() == 0) {
+        // InfoBuffer is optional
+        return true;
+    }
+    d->infoBuffers.reserve(s.infoBuffers.size());
+    for (const auto &sInfoBuffer: s.infoBuffers) {
+        if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid Framedata::infoBuffers.";
+            return false;
+        }
+    }
+    return true;
+}
+
+// BaseBlock -> C2BaseBlock
+template <typename BaseBlock>
+bool objcpy(C2BaseBlock* d, const BaseBlock& s);
+
+// WorkBundle -> std::list<std::unique_ptr<C2Work>>
+template <typename WorkBundle>
+bool objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
+    // Convert BaseBlocks to C2BaseBlocks.
+    std::vector<C2BaseBlock> dBaseBlocks(s.baseBlocks.size());
+    for (size_t i = 0; i < s.baseBlocks.size(); ++i) {
+        if (!objcpy(&dBaseBlocks[i], s.baseBlocks[i])) {
+            LOG(ERROR) << "Invalid WorkBundle::baseBlocks["
+                       << i << "].";
+            return false;
+        }
+    }
+
+    d->clear();
+    for (const auto& sWork : s.works) {
+        d->emplace_back(std::make_unique<C2Work>());
+        C2Work& dWork = *d->back();
+
+        // chain info is not in use currently.
+
+        // input
+        if (!objcpy(&dWork.input, sWork.input, dBaseBlocks)) {
+            LOG(ERROR) << "Invalid Work::input.";
+            return false;
+        }
+
+        // worklet(s)
+        dWork.worklets.clear();
+        for (const auto& sWorklet : sWork.worklets) {
+            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
+
+            // component id
+            dWorklet->component = static_cast<c2_node_id_t>(
+                    sWorklet.componentId);
+
+            // tunings
+            if (!_copyParamsFromBlob(&dWorklet->tunings, sWorklet.tunings)) {
+                LOG(ERROR) << "Invalid Worklet::tunings";
+                return false;
+            }
+
+            // failures
+            dWorklet->failures.clear();
+            dWorklet->failures.reserve(sWorklet.failures.size());
+            for (const auto& sFailure : sWorklet.failures) {
+                std::unique_ptr<C2SettingResult> dFailure;
+                if (!objcpy(&dFailure, sFailure)) {
+                    LOG(ERROR) << "Invalid Worklet::failures.";
+                    return false;
+                }
+                dWorklet->failures.emplace_back(std::move(dFailure));
+            }
+
+            // output
+            if (!objcpy(&dWorklet->output, sWorklet.output, dBaseBlocks)) {
+                LOG(ERROR) << "Invalid Worklet::output.";
+                return false;
+            }
+
+            dWork.worklets.emplace_back(std::move(dWorklet));
+        }
+
+        // workletsProcessed
+        dWork.workletsProcessed = sWork.workletsProcessed;
+
+        // result
+        dWork.result = GetStatus(sWork.result);
+    }
+
+    return true;
+}
+
+// BufferQueue-Based Block Operations
+// ==================================
+
+// Call before transferring block to other processes.
+//
+// The given block is ready to transfer to other processes. This will guarantee
+// the given block data is not mutated by bufferqueue migration.
+bool BeginTransferBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+// Call beginTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void BeginTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool processInput = false,
+        bool processOutput = true);
+
+// Call after transferring block is finished and make sure that
+// beginTransferBufferQueueBlock() is called before.
+//
+// The transfer of given block is finished. If transfer is successful the given
+// block is not owned by process anymore. Since transfer is finished the given
+// block data is OK to mutate by bufferqueue migration after this call.
+bool EndTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
+                                 bool transfer);
+
+// Call endTransferBufferQueueBlock() on blocks in the given workList.
+// processInput determines whether input blocks are yielded. processOutput
+// works similarly on output blocks. (The default value of processInput is
+// false while the default value of processOutput is true. This implies that in
+// most cases, only output buffers contain bufferqueue-based blocks.)
+void EndTransferBufferQueueBlocks(
+        const std::list<std::unique_ptr<C2Work>>& workList,
+        bool transfer,
+        bool processInput = false,
+        bool processOutput = true);
+
+// The given block is ready to be rendered. the given block is not owned by
+// process anymore. If migration is in progress, this returns false in order
+// not to render.
+bool DisplayBufferQueueBlock(const C2ConstGraphicBlock& block);
+
+}  // namespace android
+
+#endif  // CODEC2_COMMON_BUFFER_TYPES_H
diff --git a/media/codec2/hal/common/include/codec2/common/ParamTypes.h b/media/codec2/hal/common/include/codec2/common/ParamTypes.h
new file mode 100644
index 0000000..5446100
--- /dev/null
+++ b/media/codec2/hal/common/include/codec2/common/ParamTypes.h
@@ -0,0 +1,807 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_COMMON_PARAM_TYPES_H
+#define CODEC2_COMMON_PARAM_TYPES_H
+
+#ifndef LOG_TAG
+#define LOG_TAG "Codec2-ParamTypes"
+#endif
+#include <android-base/logging.h>
+
+#include <log/log_safetynet.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2ParamInternal.h>
+#include <util/C2ParamUtils.h>
+
+#include <algorithm>
+#include <unordered_map>
+
+namespace android {
+
+template <typename EnumClass>
+typename std::underlying_type<EnumClass>::type underlying_value(EnumClass x) {
+    return static_cast<typename std::underlying_type<EnumClass>::type>(x);
+}
+
+template <typename Common, typename DstVector, typename SrcVector>
+void copyVector(DstVector* d, const SrcVector& s) {
+    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
+            "DstVector's component size does not match Common");
+    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
+            "SrcVector's component size does not match Common");
+    d->resize(s.size());
+    std::copy(
+            reinterpret_cast<const Common*>(&s[0]),
+            reinterpret_cast<const Common*>(&s[0] + s.size()),
+            reinterpret_cast<Common*>(&(*d)[0]));
+}
+
+// {offset, size} -> FieldId
+template <typename FieldId>
+void SetFieldId(FieldId *d, uint32_t offset, uint32_t size) {
+    d->offset = offset;
+    d->size = size;
+}
+
+// FieldId -> offset
+template <typename FieldId>
+uint32_t GetOffsetFromFieldId(const FieldId &s) {
+    return s.offset;
+}
+
+// FieldId -> size
+template <typename FieldId>
+uint32_t GetSizeFromFieldId(const FieldId &s) {
+    return s.size;
+}
+
+// C2ParamField -> ParamField
+template <typename ParamField>
+bool objcpy(ParamField *d, const C2ParamField &s) {
+    d->index = static_cast<decltype(d->index)>(_C2ParamInspector::GetIndex(s));
+    SetFieldId(
+            &d->fieldId,
+            static_cast<uint32_t>(_C2ParamInspector::GetOffset(s)),
+            static_cast<uint32_t>(_C2ParamInspector::GetSize(s)));
+    return true;
+}
+
+template <typename ParamField>
+struct C2ParamFieldBuilder : public C2ParamField {
+    C2ParamFieldBuilder() : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
+    }
+    // ParamField -> C2ParamField
+    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
+            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
+            static_cast<uint32_t>(GetOffsetFromFieldId(s.fieldId)),
+            static_cast<uint32_t>(GetSizeFromFieldId(s.fieldId))) {
+    }
+};
+
+// C2WorkOrdinalStruct -> WorkOrdinal
+template <typename WorkOrdinal>
+bool objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
+    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
+    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
+    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
+    return true;
+}
+
+// WorkOrdinal -> C2WorkOrdinalStruct
+template <typename WorkOrdinal>
+bool objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
+    d->frameIndex = c2_cntr64_t(s.frameIndex);
+    d->timestamp = c2_cntr64_t(s.timestampUs);
+    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
+    return true;
+}
+
+// C2FieldSupportedValues::range's type -> ValueRange
+template <typename ValueRange>
+bool objcpy(
+        ValueRange* d,
+        const decltype(C2FieldSupportedValues::range)& s) {
+    d->min    = static_cast<decltype(d->min)>(s.min.u64);
+    d->max    = static_cast<decltype(d->max)>(s.max.u64);
+    d->step   = static_cast<decltype(d->step)>(s.step.u64);
+    d->num    = static_cast<decltype(d->num)>(s.num.u64);
+    d->denom  = static_cast<decltype(d->denom)>(s.denom.u64);
+    return true;
+}
+
+// ValueRange -> C2FieldSupportedValues::range's type
+template <typename ValueRange>
+bool objcpy(
+        decltype(C2FieldSupportedValues::range)* d,
+        const ValueRange& s) {
+    d->min.u64  = static_cast<uint64_t>(s.min);
+    d->max.u64  = static_cast<uint64_t>(s.max);
+    d->step.u64 = static_cast<uint64_t>(s.step);
+    d->num.u64  = static_cast<uint64_t>(s.num);
+    d->denom.u64  = static_cast<uint64_t>(s.denom);
+    return true;
+}
+
+template <typename Status>
+void SetStatus(Status *dst, c2_status_t src) {
+    *dst = static_cast<Status>(src);
+}
+
+template <typename Status>
+c2_status_t GetStatus(const Status &status) {
+    return static_cast<c2_status_t>(status);
+}
+
+// C2FieldSupportedValues -> FieldSupportedValues
+template <typename FieldSupportedValues>
+bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s);
+
+// FieldSupportedValues -> C2FieldSupportedValues
+template <typename FieldSupportedValues>
+bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s);
+
+// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery, FieldSupportedValuesQueryResult
+template <typename FieldSupportedValuesQueryPtr>
+bool objcpy(
+        FieldSupportedValuesQueryPtr dq,
+        nullptr_t,
+        const C2FieldSupportedValuesQuery& s) {
+    static_assert(!std::is_null_pointer_v<FieldSupportedValuesQueryPtr>);
+    static_assert(std::is_pointer_v<FieldSupportedValuesQueryPtr>);
+    typedef std::remove_pointer_t<FieldSupportedValuesQueryPtr> FieldSupportedValuesQuery;
+    if (!dq) {
+        return false;
+    }
+    if (!objcpy(&dq->field, s.field())) {
+        LOG(ERROR) << "Invalid C2FieldSupportedValuesQuery::field.";
+        return false;
+    }
+    switch (s.type()) {
+    case C2FieldSupportedValuesQuery::POSSIBLE:
+        dq->type = FieldSupportedValuesQuery::Type::POSSIBLE;
+        break;
+    case C2FieldSupportedValuesQuery::CURRENT:
+        dq->type = FieldSupportedValuesQuery::Type::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValuesQuery::type_t "
+                   << "with underlying value " << underlying_value(s.type())
+                   << ".";
+        dq->type = static_cast<decltype(dq->type)>(s.type());
+    }
+    return true;
+}
+
+template <typename FieldSupportedValuesQueryResultPtr>
+bool objcpy(
+        nullptr_t,
+        FieldSupportedValuesQueryResultPtr dr,
+        const C2FieldSupportedValuesQuery& s) {
+    static_assert(!std::is_null_pointer_v<FieldSupportedValuesQueryResultPtr>);
+    static_assert(std::is_pointer_v<FieldSupportedValuesQueryResultPtr>);
+    if (!dr) {
+        return false;
+    }
+    SetStatus(&dr->status, s.status);
+    return objcpy(&dr->values, s.values);
+}
+
+template <typename FieldSupportedValuesQueryPtr, typename FieldSupportedValuesQueryResultPtr>
+bool objcpy(
+        FieldSupportedValuesQueryPtr dq,
+        FieldSupportedValuesQueryResultPtr dr,
+        const C2FieldSupportedValuesQuery& s) {
+    if (!objcpy(dq, nullptr, s)) {
+        return false;
+    }
+    return objcpy(nullptr, dr, s);
+}
+
+// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
+template <typename FieldSupportedValuesQuery>
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& s) {
+    C2FieldSupportedValuesQuery::type_t dType;
+    switch (s.type) {
+    case FieldSupportedValuesQuery::Type::POSSIBLE:
+        dType = C2FieldSupportedValuesQuery::POSSIBLE;
+        break;
+    case FieldSupportedValuesQuery::Type::CURRENT:
+        dType = C2FieldSupportedValuesQuery::CURRENT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized FieldSupportedValuesQuery::Type "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        dType = static_cast<C2FieldSupportedValuesQuery::type_t>(s.type);
+    }
+    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
+    return true;
+}
+
+// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
+// C2FieldSupportedValuesQuery
+template <typename FieldSupportedValuesQuery,
+          typename FieldSupportedValuesQueryResult>
+bool objcpy(
+        C2FieldSupportedValuesQuery* d,
+        const FieldSupportedValuesQuery& sq,
+        const FieldSupportedValuesQueryResult& sr) {
+    if (!objcpy(d, sq)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQuery.";
+        return false;
+    }
+    d->status = GetStatus(sr.status);
+    if (!objcpy(&d->values, sr.values)) {
+        LOG(ERROR) << "Invalid FieldSupportedValuesQueryResult::values.";
+        return false;
+    }
+    return true;
+}
+
+// C2Component::Traits -> IComponentStore::ComponentTraits
+template <typename ComponentTraits>
+bool objcpy(
+        ComponentTraits *d,
+        const C2Component::Traits &s) {
+    d->name = s.name;
+
+    switch (s.domain) {
+    case C2Component::DOMAIN_VIDEO:
+        d->domain = ComponentTraits::Domain::VIDEO;
+        break;
+    case C2Component::DOMAIN_AUDIO:
+        d->domain = ComponentTraits::Domain::AUDIO;
+        break;
+    case C2Component::DOMAIN_IMAGE:
+        d->domain = ComponentTraits::Domain::IMAGE;
+        break;
+    case C2Component::DOMAIN_OTHER:
+        d->domain = ComponentTraits::Domain::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::domain_t "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<decltype(d->domain)>(s.domain);
+    }
+
+    switch (s.kind) {
+    case C2Component::KIND_DECODER:
+        d->kind = ComponentTraits::Kind::DECODER;
+        break;
+    case C2Component::KIND_ENCODER:
+        d->kind = ComponentTraits::Kind::ENCODER;
+        break;
+    case C2Component::KIND_OTHER:
+        d->kind = ComponentTraits::Kind::OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2Component::kind_t "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<decltype(d->kind)>(s.kind);
+    }
+
+    d->rank = static_cast<uint32_t>(s.rank);
+
+    d->mediaType = s.mediaType;
+
+    d->aliases.resize(s.aliases.size());
+    for (size_t ix = s.aliases.size(); ix > 0; ) {
+        --ix;
+        d->aliases[ix] = s.aliases[ix];
+    }
+    return true;
+}
+
+// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
+template <typename ComponentTraits>
+bool objcpy(
+        C2Component::Traits* d,
+        const ComponentTraits& s) {
+    d->name = s.name.c_str();
+
+    switch (s.domain) {
+    case ComponentTraits::Domain::VIDEO:
+        d->domain = C2Component::DOMAIN_VIDEO;
+        break;
+    case ComponentTraits::Domain::AUDIO:
+        d->domain = C2Component::DOMAIN_AUDIO;
+        break;
+    case ComponentTraits::Domain::IMAGE:
+        d->domain = C2Component::DOMAIN_IMAGE;
+        break;
+    case ComponentTraits::Domain::OTHER:
+        d->domain = C2Component::DOMAIN_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Domain "
+                   << "with underlying value " << underlying_value(s.domain)
+                   << ".";
+        d->domain = static_cast<C2Component::domain_t>(s.domain);
+    }
+
+    switch (s.kind) {
+    case ComponentTraits::Kind::DECODER:
+        d->kind = C2Component::KIND_DECODER;
+        break;
+    case ComponentTraits::Kind::ENCODER:
+        d->kind = C2Component::KIND_ENCODER;
+        break;
+    case ComponentTraits::Kind::OTHER:
+        d->kind = C2Component::KIND_OTHER;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized ComponentTraits::Kind "
+                   << "with underlying value " << underlying_value(s.kind)
+                   << ".";
+        d->kind = static_cast<C2Component::kind_t>(s.kind);
+    }
+
+    d->rank = static_cast<C2Component::rank_t>(s.rank);
+    d->mediaType = s.mediaType.c_str();
+    d->aliases.resize(s.aliases.size());
+    for (size_t i = 0; i < s.aliases.size(); ++i) {
+        d->aliases[i] = s.aliases[i];
+    }
+    return true;
+}
+
+// C2ParamFieldValues -> ParamFieldValues
+template <typename ParamFieldValues>
+bool objcpy(
+        ParamFieldValues *d,
+        const C2ParamFieldValues &s) {
+    if (!objcpy(&d->paramOrField, s.paramOrField)) {
+        LOG(ERROR) << "Invalid C2ParamFieldValues::paramOrField.";
+        return false;
+    }
+    if (s.values) {
+        d->values.resize(1);
+        if (!objcpy(&d->values[0], *s.values)) {
+            LOG(ERROR) << "Invalid C2ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    }
+    d->values.resize(0);
+    return true;
+}
+
+// ParamFieldValues -> C2ParamFieldValues
+template <typename ParamFieldValues>
+bool objcpy(
+        C2ParamFieldValues *d,
+        const ParamFieldValues &s) {
+    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
+    if (s.values.size() == 1) {
+        d->values = std::make_unique<C2FieldSupportedValues>();
+        if (!objcpy(d->values.get(), s.values[0])) {
+            LOG(ERROR) << "Invalid ParamFieldValues::values.";
+            return false;
+        }
+        return true;
+    } else if (s.values.size() == 0) {
+        d->values.reset();
+        return true;
+    }
+    LOG(ERROR) << "Invalid ParamFieldValues: "
+                  "Two or more FieldSupportedValues objects exist in "
+                  "ParamFieldValues. "
+                  "Only zero or one is allowed.";
+    return false;
+}
+
+// C2SettingResult -> SettingResult
+template <typename SettingResult>
+bool objcpy(
+        SettingResult *d,
+        const C2SettingResult &s) {
+    switch (s.failure) {
+    case C2SettingResult::BAD_TYPE:
+        d->failure = SettingResult::Failure::BAD_TYPE;
+        break;
+    case C2SettingResult::BAD_PORT:
+        d->failure = SettingResult::Failure::BAD_PORT;
+        break;
+    case C2SettingResult::BAD_INDEX:
+        d->failure = SettingResult::Failure::BAD_INDEX;
+        break;
+    case C2SettingResult::READ_ONLY:
+        d->failure = SettingResult::Failure::READ_ONLY;
+        break;
+    case C2SettingResult::MISMATCH:
+        d->failure = SettingResult::Failure::MISMATCH;
+        break;
+    case C2SettingResult::BAD_VALUE:
+        d->failure = SettingResult::Failure::BAD_VALUE;
+        break;
+    case C2SettingResult::CONFLICT:
+        d->failure = SettingResult::Failure::CONFLICT;
+        break;
+    case C2SettingResult::UNSUPPORTED:
+        d->failure = SettingResult::Failure::UNSUPPORTED;
+        break;
+    case C2SettingResult::INFO_BAD_VALUE:
+        d->failure = SettingResult::Failure::INFO_BAD_VALUE;
+        break;
+    case C2SettingResult::INFO_CONFLICT:
+        d->failure = SettingResult::Failure::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized C2SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        d->failure = static_cast<decltype(d->failure)>(s.failure);
+    }
+    if (!objcpy(&d->field, s.field)) {
+        LOG(ERROR) << "Invalid C2SettingResult::field.";
+        return false;
+    }
+    d->conflicts.resize(s.conflicts.size());
+    size_t i = 0;
+    for (const C2ParamFieldValues& sConflict : s.conflicts) {
+        auto &dConflict = d->conflicts[i++];
+        if (!objcpy(&dConflict, sConflict)) {
+            LOG(ERROR) << "Invalid C2SettingResult::conflicts["
+                       << i - 1 << "].";
+            return false;
+        }
+    }
+    return true;
+}
+
+// SettingResult -> std::unique_ptr<C2SettingResult>
+template <typename SettingResult>
+bool objcpy(
+        std::unique_ptr<C2SettingResult> *d,
+        const SettingResult &s) {
+    typedef decltype((*d)->field) ParamField;
+    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
+            .field = C2ParamFieldValues(C2ParamFieldBuilder<ParamField>()) });
+    if (!*d) {
+        LOG(ERROR) << "No memory for C2SettingResult.";
+        return false;
+    }
+
+    // failure
+    switch (s.failure) {
+    case SettingResult::Failure::BAD_TYPE:
+        (*d)->failure = C2SettingResult::BAD_TYPE;
+        break;
+    case SettingResult::Failure::BAD_PORT:
+        (*d)->failure = C2SettingResult::BAD_PORT;
+        break;
+    case SettingResult::Failure::BAD_INDEX:
+        (*d)->failure = C2SettingResult::BAD_INDEX;
+        break;
+    case SettingResult::Failure::READ_ONLY:
+        (*d)->failure = C2SettingResult::READ_ONLY;
+        break;
+    case SettingResult::Failure::MISMATCH:
+        (*d)->failure = C2SettingResult::MISMATCH;
+        break;
+    case SettingResult::Failure::BAD_VALUE:
+        (*d)->failure = C2SettingResult::BAD_VALUE;
+        break;
+    case SettingResult::Failure::CONFLICT:
+        (*d)->failure = C2SettingResult::CONFLICT;
+        break;
+    case SettingResult::Failure::UNSUPPORTED:
+        (*d)->failure = C2SettingResult::UNSUPPORTED;
+        break;
+    case SettingResult::Failure::INFO_BAD_VALUE:
+        (*d)->failure = C2SettingResult::INFO_BAD_VALUE;
+        break;
+    case SettingResult::Failure::INFO_CONFLICT:
+        (*d)->failure = C2SettingResult::INFO_CONFLICT;
+        break;
+    default:
+        LOG(DEBUG) << "Unrecognized SettingResult::Failure "
+                   << "with underlying value " << underlying_value(s.failure)
+                   << ".";
+        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failure);
+    }
+
+    // field
+    if (!objcpy(&(*d)->field, s.field)) {
+        LOG(ERROR) << "Invalid SettingResult::field.";
+        return false;
+    }
+
+    // conflicts
+    (*d)->conflicts.clear();
+    (*d)->conflicts.reserve(s.conflicts.size());
+    for (const auto& sConflict : s.conflicts) {
+        (*d)->conflicts.emplace_back(
+                C2ParamFieldValues{ C2ParamFieldBuilder<ParamField>(), nullptr });
+        if (!objcpy(&(*d)->conflicts.back(), sConflict)) {
+            LOG(ERROR) << "Invalid SettingResult::conflicts.";
+            return false;
+        }
+    }
+    return true;
+}
+
+// C2ParamDescriptor -> ParamDescriptor
+template <typename ParamDescriptor>
+bool objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
+    d->index = static_cast<decltype(d->index)>(s.index());
+    d->attrib = static_cast<decltype(d->attrib)>(
+            _C2ParamInspector::GetAttrib(s));
+    d->name = s.name();
+    copyVector<uint32_t>(&d->dependencies, s.dependencies());
+    return true;
+}
+
+// ParamDescriptor -> C2ParamDescriptor
+template <typename ParamDescriptor>
+bool objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
+    std::vector<C2Param::Index> dDependencies;
+    dDependencies.reserve(s.dependencies.size());
+    for (const auto& sDependency : s.dependencies) {
+        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
+    }
+    *d = std::make_shared<C2ParamDescriptor>(
+            C2Param::Index(static_cast<uint32_t>(s.index)),
+            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
+            C2String(s.name.c_str()),
+            std::move(dDependencies));
+    return true;
+}
+
+// C2StructDescriptor -> StructDescriptor
+template <typename StructDescriptor>
+bool objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
+    d->type = static_cast<decltype(d->type)>(s.coreIndex().coreIndex());
+    d->fields.resize(s.numFields());
+    size_t i = 0;
+    for (const C2FieldDescriptor& sField : s) {
+        auto& dField = d->fields[i++];
+        SetFieldId(
+                &dField.fieldId,
+                _C2ParamInspector::GetOffset(sField),
+                _C2ParamInspector::GetSize(sField));
+        dField.type = static_cast<decltype(dField.type)>(sField.type());
+        dField.extent = static_cast<uint32_t>(sField.extent());
+        dField.name = static_cast<decltype(dField.name)>(sField.name());
+        const auto& sNamedValues = sField.namedValues();
+        dField.namedValues.resize(sNamedValues.size());
+        size_t j = 0;
+        for (const auto& sNamedValue : sNamedValues) {
+            auto& dNamedValue = dField.namedValues[j++];
+            dNamedValue.name = static_cast<decltype(dNamedValue.name)>(sNamedValue.first);
+            dNamedValue.value = static_cast<decltype(dNamedValue.value)>(
+                    sNamedValue.second.u64);
+        }
+    }
+    return true;
+}
+
+// StructDescriptor -> C2StructDescriptor
+template <typename StructDescriptor>
+bool objcpy(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
+    C2Param::CoreIndex dIndex = C2Param::CoreIndex(static_cast<uint32_t>(s.type));
+    std::vector<C2FieldDescriptor> dFields;
+    dFields.reserve(s.fields.size());
+    for (const auto &sField : s.fields) {
+        C2FieldDescriptor dField = {
+            static_cast<uint32_t>(sField.type),
+            static_cast<uint32_t>(sField.extent),
+            sField.name,
+            GetOffsetFromFieldId(sField.fieldId),
+            GetSizeFromFieldId(sField.fieldId) };
+        C2FieldDescriptor::NamedValuesType namedValues;
+        namedValues.reserve(sField.namedValues.size());
+        for (const auto& sNamedValue : sField.namedValues) {
+            namedValues.emplace_back(
+                sNamedValue.name,
+                C2Value::Primitive(static_cast<uint64_t>(sNamedValue.value)));
+        }
+        _C2ParamInspector::AddNamedValues(dField, std::move(namedValues));
+        dFields.emplace_back(dField);
+    }
+    *d = std::make_unique<C2StructDescriptor>(
+            _C2ParamInspector::CreateStructDescriptor(dIndex, std::move(dFields)));
+    return true;
+}
+
+constexpr size_t PARAMS_ALIGNMENT = 8;  // 64-bit alignment
+static_assert(PARAMS_ALIGNMENT % alignof(C2Param) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Info) == 0, "C2Param alignment mismatch");
+static_assert(PARAMS_ALIGNMENT % alignof(C2Tuning) == 0, "C2Param alignment mismatch");
+
+template <typename Params>
+struct _ParamsBlobHelper { typedef Params BlobType; };
+
+template <typename Params>
+using ParamsBlobType = typename _ParamsBlobHelper<Params>::BlobType;
+
+template <typename Params>
+const ParamsBlobType<Params> &GetBlob(const Params &params) {
+    return params;
+}
+
+template <typename Params>
+ParamsBlobType<Params> *GetBlob(Params *params) {
+    return params;
+}
+
+// Params -> std::vector<C2Param*>
+template <typename Params>
+bool parseParamsBlob(std::vector<C2Param*> *params, const Params &paramsBlob) {
+    // assuming blob is const here
+    const ParamsBlobType<Params> &blob = GetBlob(paramsBlob);
+    size_t size = blob.size();
+    size_t ix = 0;
+    size_t old_ix = 0;
+    const uint8_t *data = blob.data();
+    C2Param *p = nullptr;
+
+    do {
+        p = C2ParamUtils::ParseFirst(data + ix, size - ix);
+        if (p) {
+            params->emplace_back(p);
+            old_ix = ix;
+            ix += p->size();
+            ix = align(ix, PARAMS_ALIGNMENT);
+            if (ix <= old_ix || ix > size) {
+                android_errorWriteLog(0x534e4554, "238083570");
+                break;
+            }
+        }
+    } while (p);
+
+    if (ix != size) {
+        LOG(ERROR) << "parseParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Concatenates a list of C2Params into a params blob. T is a container type
+ * whose member type is compatible with C2Param*.
+ *
+ * \param[out] blob target blob
+ * \param[in] params parameters to concatenate
+ * \retval C2_OK if the blob was successfully created
+ * \retval C2_BAD_VALUE if the blob was not successful created (this only
+ *         happens if the parameters were not const)
+ */
+template <typename Params, typename T>
+bool _createParamsBlob(Params *paramsBlob, const T &params) {
+    // assuming the parameter values are const
+    size_t size = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        size += p->size();
+        size = align(size, PARAMS_ALIGNMENT);
+    }
+    ParamsBlobType<Params> *blob = GetBlob(paramsBlob);
+    blob->resize(size);
+    size_t ix = 0;
+    for (const auto &p : params) {
+        if (!p) {
+            continue;
+        }
+        // NEVER overwrite even if param values (e.g. size) changed
+        size_t paramSize = std::min(p->size(), size - ix);
+        std::copy(
+                reinterpret_cast<const uint8_t*>(&*p),
+                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
+                &(*blob)[ix]);
+        ix += paramSize;
+        ix = align(ix, PARAMS_ALIGNMENT);
+    }
+    blob->resize(ix);
+    if (ix != size) {
+        LOG(ERROR) << "createParamsBlob -- inconsistent sizes.";
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Parses a params blob and create a vector of new T objects that contain copies
+ * of the params in the blob. T is C2Param or its compatible derived class.
+ *
+ * \param[out] params the resulting vector
+ * \param[in] blob parameter blob to parse
+ * \retval C2_OK if the full blob was parsed and params was constructed
+ * \retval C2_BAD_VALUE otherwise
+ */
+template <typename Params, typename T>
+bool _copyParamsFromBlob(
+        std::vector<std::unique_ptr<T>>* params,
+        const Params &paramsBlob) {
+    const ParamsBlobType<Params> &blob = GetBlob(paramsBlob);
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "copyParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    params->resize(paramPointers.size());
+    size_t i = 0;
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "copyParamsFromBlob -- null paramPointer.";
+            return false;
+        }
+        (*params)[i++].reset(reinterpret_cast<T*>(
+                C2Param::Copy(*paramPointer).release()));
+    }
+    return true;
+}
+
+// Params -> update std::vector<std::unique_ptr<C2Param>>
+template <typename Params>
+bool updateParamsFromBlob(
+        const std::vector<C2Param*>& params,
+        const Params& paramsBlob) {
+    const ParamsBlobType<Params> &blob = GetBlob(paramsBlob);
+    std::unordered_map<uint32_t, C2Param*> index2param;
+    for (C2Param* const& param : params) {
+        if (!param) {
+            LOG(ERROR) << "updateParamsFromBlob -- null output param.";
+            return false;
+        }
+        if (index2param.find(param->index()) == index2param.end()) {
+            index2param.emplace(param->index(), param);
+        }
+    }
+
+    std::vector<C2Param*> paramPointers;
+    if (!parseParamsBlob(&paramPointers, blob)) {
+        LOG(ERROR) << "updateParamsFromBlob -- failed to parse.";
+        return false;
+    }
+
+    for (C2Param* const& paramPointer : paramPointers) {
+        if (!paramPointer) {
+            LOG(ERROR) << "updateParamsFromBlob -- null input param.";
+            return false;
+        }
+        decltype(index2param)::iterator i = index2param.find(
+                paramPointer->index());
+        if (i == index2param.end()) {
+            LOG(DEBUG) << "updateParamsFromBlob -- index "
+                       << paramPointer->index() << " not found. Skipping...";
+            continue;
+        }
+        if (!i->second->updateFrom(*paramPointer)) {
+            LOG(ERROR) << "updateParamsFromBlob -- size mismatch: "
+                       << params.size() << " vs " << paramPointer->size()
+                       << " (index = " << i->first << ").";
+            return false;
+        }
+    }
+    return true;
+}
+
+}  // namespace android
+
+#endif  // CODEC2_COMMON_PARAM_TYPES_H
diff --git a/media/codec2/hal/hidl/1.0/utils/Android.bp b/media/codec2/hal/hidl/1.0/utils/Android.bp
index db7874d..2f2ecd1 100644
--- a/media/codec2/hal/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hal/hidl/1.0/utils/Android.bp
@@ -27,6 +27,7 @@
         "android.hardware.media.c2@1.0",
         "libbase",
         "libcodec2",
+        "libcodec2_hal_common",
         "libcodec2_vndk",
         "libcutils",
         "libgui",
@@ -44,6 +45,7 @@
     export_shared_lib_headers: [
         "android.hardware.media.c2@1.0",
         "libcodec2",
+        "libcodec2_hal_common",
         "libgui",
         "libstagefright_bufferpool@2.0.1",
         "libui",
@@ -77,8 +79,8 @@
 
     header_libs: [
         "libbinder_headers",
-        "libsystem_headers",
         "libcodec2_internal", // private
+        "libsystem_headers",
     ],
 
     shared_libs: [
@@ -91,8 +93,9 @@
         "android.hardware.media.omx@1.0",
         "libbase",
         "libcodec2",
-        "libcodec2_vndk",
+        "libcodec2_hal_common",
         "libcodec2_hidl_plugin_stub",
+        "libcodec2_vndk",
         "libcutils",
         "libhidlbase",
         "liblog",
@@ -128,6 +131,7 @@
     export_shared_lib_headers: [
         "android.hardware.media.c2@1.0",
         "libcodec2",
+        "libcodec2_hal_common",
         "libcodec2_vndk",
         "libhidlbase",
         "libstagefright_bufferpool@2.0.1",
diff --git a/media/codec2/hal/hidl/1.0/utils/Component.cpp b/media/codec2/hal/hidl/1.0/utils/Component.cpp
index df30dba..0aeed08 100644
--- a/media/codec2/hal/hidl/1.0/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.0/utils/Component.cpp
@@ -222,6 +222,21 @@
     return mInit;
 }
 
+void Component::onDeathReceived() {
+    {
+        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+        mClientDied = true;
+        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
+            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
+                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
+                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
+                bqPool->invalidate();
+            }
+        }
+    }
+    release();
+}
+
 // Methods from ::android::hardware::media::c2::V1_0::IComponent
 Return<Status> Component::queue(const WorkBundle& workBundle) {
     std::list<std::unique_ptr<C2Work>> c2works;
@@ -409,9 +424,19 @@
         blockPool = nullptr;
     }
     if (blockPool) {
-        mBlockPoolsMutex.lock();
-        mBlockPools.emplace(blockPool->getLocalId(), blockPool);
-        mBlockPoolsMutex.unlock();
+        bool emplaced = false;
+        {
+            mBlockPoolsMutex.lock();
+            if (!mClientDied) {
+                mBlockPools.emplace(blockPool->getLocalId(), blockPool);
+                emplaced = true;
+            }
+            mBlockPoolsMutex.unlock();
+        }
+        if (!emplaced) {
+            blockPool.reset();
+            status = C2_BAD_STATE;
+        }
     } else if (status == C2_OK) {
         status = C2_CORRUPTED;
     }
@@ -494,8 +519,8 @@
                 ) override {
             auto strongComponent = mComponent.promote();
             if (strongComponent) {
-                LOG(INFO) << "Client died ! release the component !!";
-                strongComponent->release();
+                LOG(INFO) << "Client died ! notify and release the component !!";
+                strongComponent->onDeathReceived();
             } else {
                 LOG(ERROR) << "Client died ! no component to release !!";
             }
diff --git a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h
index e343655..3f55618 100644
--- a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h
+++ b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Component.h
@@ -66,6 +66,8 @@
             const sp<::android::hardware::media::bufferpool::V2_0::
                 IClientManager>& clientPoolManager);
     c2_status_t status() const;
+    // Receives a death notification of the client.
+    void onDeathReceived();
 
     typedef ::android::hardware::graphics::bufferqueue::V1_0::
             IGraphicBufferProducer HGraphicBufferProducer1;
@@ -135,6 +137,7 @@
 
     using HwDeathRecipient = ::android::hardware::hidl_death_recipient;
     sp<HwDeathRecipient> mDeathRecipient;
+    bool mClientDied{false};
 };
 
 }  // namespace utils
diff --git a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/types.h b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
index f111f81..20e3fb5 100644
--- a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
+++ b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
@@ -23,6 +23,7 @@
 #include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <android/hardware/media/c2/1.0/types.h>
 #include <android/hidl/safe_union/1.0/types.h>
+#include <codec2/common/BufferPoolSender.h>
 
 #include <C2Component.h>
 #include <C2Param.h>
@@ -42,8 +43,6 @@
 namespace utils {
 
 using ::android::hardware::hidl_bitfield;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::status_t;
 using ::android::sp;
@@ -134,38 +133,15 @@
         std::unique_ptr<C2StructDescriptor>* d,
         const StructDescriptor& s);
 
-// Abstract class to be used in
-// objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
-struct BufferPoolSender {
-    typedef ::android::hardware::media::bufferpool::V2_0::
-            ResultStatus ResultStatus;
-    typedef ::android::hardware::media::bufferpool::V2_0::
-            BufferStatusMessage BufferStatusMessage;
-    typedef ::android::hardware::media::bufferpool::
-            BufferPoolData BufferPoolData;
-
-    /**
-     * Send bpData and return BufferStatusMessage that can be supplied to
-     * IClientManager::receive() in the receiving process.
-     *
-     * This function will be called from within the function
-     * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle).
-     *
-     * \param[in] bpData BufferPoolData identifying the buffer to send.
-     * \param[out] bpMessage BufferStatusMessage of the transaction. Information
-     *    inside \p bpMessage should be passed to the receiving process by some
-     *    other means so it can call receive() properly.
-     * \return ResultStatus value that determines the success of the operation.
-     *    (See the possible values of ResultStatus in
-     *    hardware/interfaces/media/bufferpool/2.0/types.hal.)
-     */
-    virtual ResultStatus send(
-            const std::shared_ptr<BufferPoolData>& bpData,
-            BufferStatusMessage* bpMessage) = 0;
-
-    virtual ~BufferPoolSender() = default;
+struct BufferPoolTypes {
+    typedef bufferpool::BufferPoolData              BufferPoolData;
+    typedef bufferpool::V2_0::ResultStatus          BufferPoolStatus;
+    typedef bufferpool::V2_0::ResultStatus          ResultStatus;
+    typedef bufferpool::V2_0::BufferStatusMessage   BufferStatusMessage;
 };
 
+typedef ::android::BufferPoolSender<BufferPoolTypes> BufferPoolSender;
+
 // Default implementation of BufferPoolSender.
 //
 // To use DefaultBufferPoolSender, the IClientManager instance of the receiving
@@ -198,7 +174,7 @@
     // Implementation of BufferPoolSender::send(). send() will establish a
     // bufferpool connection if needed, then send the bufferpool data over to
     // the receiving process.
-    virtual ResultStatus send(
+    ResultStatus send(
             const std::shared_ptr<BufferPoolData>& bpData,
             BufferStatusMessage* bpMessage) override;
 
diff --git a/media/codec2/hal/hidl/1.0/utils/types.cpp b/media/codec2/hal/hidl/1.0/utils/types.cpp
index 319ba62..abe5494 100644
--- a/media/codec2/hal/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hal/hidl/1.0/utils/types.cpp
@@ -18,8 +18,10 @@
 #define LOG_TAG "Codec2-types"
 #include <android-base/logging.h>
 
+#include <bufferpool/ClientManager.h>
+#include <codec2/common/BufferTypes.h>
+#include <codec2/common/ParamTypes.h>
 #include <codec2/hidl/1.0/types.h>
-#include <media/stagefright/foundation/AUtils.h>
 
 #include <C2AllocatorIon.h>
 #include <C2AllocatorGralloc.h>
@@ -27,108 +29,23 @@
 #include <C2Buffer.h>
 #include <C2Component.h>
 #include <C2FenceFactory.h>
-#include <C2Param.h>
-#include <C2ParamInternal.h>
 #include <C2PlatformSupport.h>
 #include <C2Work.h>
-#include <util/C2ParamUtils.h>
-
-#include <algorithm>
-#include <functional>
-#include <iomanip>
-#include <unordered_map>
 
 namespace android {
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace utils {
 
-using ::android::hardware::Return;
-using ::android::hardware::media::bufferpool::BufferPoolData;
-using ::android::hardware::media::bufferpool::V2_0::BufferStatusMessage;
-using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
-using ::android::hardware::media::bufferpool::V2_0::implementation::
-        ClientManager;
-using ::android::hardware::media::bufferpool::V2_0::implementation::
-        TransactionId;
-
-const char* asString(Status status, const char* def) {
-    return asString(static_cast<c2_status_t>(status), def);
-}
-
-namespace /* unnamed */ {
-
-template <typename EnumClass>
-typename std::underlying_type<EnumClass>::type underlying_value(
-        EnumClass x) {
-    return static_cast<typename std::underlying_type<EnumClass>::type>(x);
-}
-
-template <typename Common, typename DstVector, typename SrcVector>
-void copyVector(DstVector* d, const SrcVector& s) {
-    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
-            "DstVector's component size does not match Common");
-    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
-            "SrcVector's component size does not match Common");
-    d->resize(s.size());
-    std::copy(
-            reinterpret_cast<const Common*>(&s[0]),
-            reinterpret_cast<const Common*>(&s[0] + s.size()),
-            reinterpret_cast<Common*>(&(*d)[0]));
-}
-
-// C2ParamField -> ParamField
-bool objcpy(ParamField *d, const C2ParamField &s) {
-    d->index = static_cast<ParamIndex>(_C2ParamInspector::GetIndex(s));
-    d->fieldId.offset = static_cast<uint32_t>(_C2ParamInspector::GetOffset(s));
-    d->fieldId.size = static_cast<uint32_t>(_C2ParamInspector::GetSize(s));
-    return true;
-}
-
-struct C2ParamFieldBuilder : public C2ParamField {
-    C2ParamFieldBuilder() : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
-    }
-    // ParamField -> C2ParamField
-    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
-            static_cast<uint32_t>(s.fieldId.offset),
-            static_cast<uint32_t>(s.fieldId.size)) {
-    }
-};
-
-// C2WorkOrdinalStruct -> WorkOrdinal
-bool objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
-    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
-    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
-    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
-    return true;
-}
-
-// WorkOrdinal -> C2WorkOrdinalStruct
-bool objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
-    d->frameIndex = c2_cntr64_t(s.frameIndex);
-    d->timestamp = c2_cntr64_t(s.timestampUs);
-    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
-    return true;
-}
-
-// C2FieldSupportedValues::range's type -> ValueRange
-bool objcpy(
-        ValueRange* d,
-        const decltype(C2FieldSupportedValues::range)& s) {
-    d->min = static_cast<PrimitiveValue>(s.min.u64);
-    d->max = static_cast<PrimitiveValue>(s.max.u64);
-    d->step = static_cast<PrimitiveValue>(s.step.u64);
-    d->num = static_cast<PrimitiveValue>(s.num.u64);
-    d->denom = static_cast<PrimitiveValue>(s.denom.u64);
-    return true;
-}
+using hardware::media::bufferpool::V2_0::implementation::ClientManager;
+using hardware::media::c2::V1_0::BaseBlock;
+using hardware::media::c2::V1_0::FieldSupportedValues;
+using hardware::media::c2::V1_0::PrimitiveValue;
+using hardware::media::c2::V1_0::ValueRange;
+using hardware::media::c2::V1_0::utils::BufferPoolTypes;
+using hardware::hidl_vec;
 
 // C2FieldSupportedValues -> FieldSupportedValues
-bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
+template<>
+bool objcpy(
+        FieldSupportedValues *d, const C2FieldSupportedValues &s) {
     switch (s.type) {
     case C2FieldSupportedValues::EMPTY: {
             d->empty(::android::hidl::safe_union::V1_0::Monostate{});
@@ -165,20 +82,10 @@
     return true;
 }
 
-// ValueRange -> C2FieldSupportedValues::range's type
-bool objcpy(
-        decltype(C2FieldSupportedValues::range)* d,
-        const ValueRange& s) {
-    d->min.u64 = static_cast<uint64_t>(s.min);
-    d->max.u64 = static_cast<uint64_t>(s.max);
-    d->step.u64 = static_cast<uint64_t>(s.step);
-    d->num.u64 = static_cast<uint64_t>(s.num);
-    d->denom.u64 = static_cast<uint64_t>(s.denom);
-    return true;
-}
-
 // FieldSupportedValues -> C2FieldSupportedValues
-bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
+template<>
+bool objcpy(
+        C2FieldSupportedValues *d, const FieldSupportedValues &s) {
     switch (s.getDiscriminator()) {
     case FieldSupportedValues::hidl_discriminator::empty: {
             d->type = C2FieldSupportedValues::EMPTY;
@@ -210,60 +117,146 @@
     return true;
 }
 
-} // unnamed namespace
+template<>
+bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
+    switch (s.getDiscriminator()) {
+    case BaseBlock::hidl_discriminator::nativeBlock: {
+            if (s.nativeBlock() == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
+                return false;
+            }
+            native_handle_t* sHandle =
+                    native_handle_clone(s.nativeBlock());
+            if (sHandle == nullptr) {
+                LOG(ERROR) << "Null BaseBlock::nativeBlock.";
+                return false;
+            }
+            const C2Handle *sC2Handle =
+                    reinterpret_cast<const C2Handle*>(sHandle);
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(sC2Handle);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(sC2Handle);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::nativeBlock.";
+            if (sHandle) {
+                native_handle_close(sHandle);
+                native_handle_delete(sHandle);
+            }
+            return false;
+        }
+    case BaseBlock::hidl_discriminator::pooledBlock: {
+            const BufferPoolTypes::BufferStatusMessage &bpMessage =
+                    s.pooledBlock();
+            sp<ClientManager> bp = ClientManager::getInstance();
+            std::shared_ptr<BufferPoolTypes::BufferPoolData> bpData;
+            native_handle_t *cHandle;
+            BufferPoolTypes::BufferPoolStatus bpStatus = bp->receive(
+                    bpMessage.connectionId,
+                    bpMessage.transactionId,
+                    bpMessage.bufferId,
+                    bpMessage.timestampUs,
+                    &cHandle,
+                    &bpData);
+            if (bpStatus != BufferPoolTypes::ResultStatus::OK) {
+                LOG(ERROR) << "Failed to receive buffer from bufferpool -- "
+                           << "resultStatus = " << underlying_value(bpStatus)
+                           << ".";
+                return false;
+            } else if (!bpData) {
+                LOG(ERROR) << "No data in bufferpool transaction.";
+                return false;
+            }
+
+            d->linear = _C2BlockFactory::CreateLinearBlock(cHandle, bpData);
+            if (d->linear) {
+                d->type = C2BaseBlock::LINEAR;
+                return true;
+            }
+
+            d->graphic = _C2BlockFactory::CreateGraphicBlock(cHandle, bpData);
+            if (d->graphic) {
+                d->type = C2BaseBlock::GRAPHIC;
+                return true;
+            }
+            if (cHandle) {
+                // Though we got cloned handle, creating block failed.
+                native_handle_close(cHandle);
+                native_handle_delete(cHandle);
+            }
+
+            LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
+            return false;
+        }
+    default:
+        LOG(ERROR) << "Unrecognized BaseBlock's discriminator with "
+                   << "underlying value "
+                   << underlying_value(s.getDiscriminator()) << ".";
+        return false;
+    }
+}
+
+template<>
+void SetHandle(BaseBlock *block, const C2Handle *handle) {
+    block->nativeBlock(reinterpret_cast<const native_handle_t*>(handle));
+}
+
+template<>
+void SetPooledBlock<BufferPoolTypes>(
+        BaseBlock *baseBlock,
+        const typename BufferPoolTypes::BufferStatusMessage &pooledBlock) {
+    baseBlock->pooledBlock(pooledBlock);
+}
+
+template<>
+bool GetBufferPoolData<BufferPoolTypes>(
+        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
+        std::shared_ptr<typename BufferPoolTypes::BufferPoolData> *bpData) {
+    return _C2BlockFactory::GetBufferPoolData(blockPoolData, bpData);
+}
+
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::media::bufferpool::BufferPoolData;
+using ::android::hardware::media::bufferpool::V2_0::ResultStatus;
+using ::android::hardware::media::bufferpool::V2_0::implementation::
+        TransactionId;
+
+const char* asString(Status status, const char* def) {
+    return asString(static_cast<c2_status_t>(status), def);
+}
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
 bool objcpy(
         FieldSupportedValuesQuery* d,
         const C2FieldSupportedValuesQuery& s) {
-    if (!objcpy(&d->field, s.field())) {
-        LOG(ERROR) << "Invalid C2FieldSupportedValuesQuery::field.";
-        return false;
-    }
-    switch (s.type()) {
-    case C2FieldSupportedValuesQuery::POSSIBLE:
-        d->type = FieldSupportedValuesQuery::Type::POSSIBLE;
-        break;
-    case C2FieldSupportedValuesQuery::CURRENT:
-        d->type = FieldSupportedValuesQuery::Type::CURRENT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2FieldSupportedValuesQuery::type_t "
-                   << "with underlying value " << underlying_value(s.type())
-                   << ".";
-        d->type = static_cast<FieldSupportedValuesQuery::Type>(s.type());
-    }
-    return true;
+    return ::android::objcpy(d, nullptr, s);
 }
 
 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
 bool objcpy(
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& s) {
-    C2FieldSupportedValuesQuery::type_t dType;
-    switch (s.type) {
-    case FieldSupportedValuesQuery::Type::POSSIBLE:
-        dType = C2FieldSupportedValuesQuery::POSSIBLE;
-        break;
-    case FieldSupportedValuesQuery::Type::CURRENT:
-        dType = C2FieldSupportedValuesQuery::CURRENT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized FieldSupportedValuesQuery::Type "
-                   << "with underlying value " << underlying_value(s.type)
-                   << ".";
-        dType = static_cast<C2FieldSupportedValuesQuery::type_t>(s.type);
-    }
-    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
 bool objcpy(
         FieldSupportedValuesQueryResult* d,
         const C2FieldSupportedValuesQuery& s) {
-    d->status = static_cast<Status>(s.status);
-    return objcpy(&d->values, s.values);
+    return ::android::objcpy(nullptr, d, s);
 }
 
 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
@@ -272,689 +265,53 @@
         C2FieldSupportedValuesQuery* d,
         const FieldSupportedValuesQuery& sq,
         const FieldSupportedValuesQueryResult& sr) {
-    if (!objcpy(d, sq)) {
-        LOG(ERROR) << "Invalid FieldSupportedValuesQuery.";
-        return false;
-    }
-    d->status = static_cast<c2_status_t>(sr.status);
-    if (!objcpy(&d->values, sr.values)) {
-        LOG(ERROR) << "Invalid FieldSupportedValuesQueryResult::values.";
-        return false;
-    }
-    return true;
+    return ::android::objcpy(d, sq, sr);
 }
 
 // C2Component::Traits -> IComponentStore::ComponentTraits
 bool objcpy(
         IComponentStore::ComponentTraits *d,
         const C2Component::Traits &s) {
-    d->name = s.name;
-
-    switch (s.domain) {
-    case C2Component::DOMAIN_VIDEO:
-        d->domain = IComponentStore::ComponentTraits::Domain::VIDEO;
-        break;
-    case C2Component::DOMAIN_AUDIO:
-        d->domain = IComponentStore::ComponentTraits::Domain::AUDIO;
-        break;
-    case C2Component::DOMAIN_IMAGE:
-        d->domain = IComponentStore::ComponentTraits::Domain::IMAGE;
-        break;
-    case C2Component::DOMAIN_OTHER:
-        d->domain = IComponentStore::ComponentTraits::Domain::OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2Component::domain_t "
-                   << "with underlying value " << underlying_value(s.domain)
-                   << ".";
-        d->domain = static_cast<IComponentStore::ComponentTraits::Domain>(
-                s.domain);
-    }
-
-    switch (s.kind) {
-    case C2Component::KIND_DECODER:
-        d->kind = IComponentStore::ComponentTraits::Kind::DECODER;
-        break;
-    case C2Component::KIND_ENCODER:
-        d->kind = IComponentStore::ComponentTraits::Kind::ENCODER;
-        break;
-    case C2Component::KIND_OTHER:
-        d->kind = IComponentStore::ComponentTraits::Kind::OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2Component::kind_t "
-                   << "with underlying value " << underlying_value(s.kind)
-                   << ".";
-        d->kind = static_cast<IComponentStore::ComponentTraits::Kind>(
-                s.kind);
-    }
-
-    d->rank = static_cast<uint32_t>(s.rank);
-
-    d->mediaType = s.mediaType;
-
-    d->aliases.resize(s.aliases.size());
-    for (size_t ix = s.aliases.size(); ix > 0; ) {
-        --ix;
-        d->aliases[ix] = s.aliases[ix];
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
 bool objcpy(
         C2Component::Traits* d,
         const IComponentStore::ComponentTraits& s) {
-    d->name = s.name.c_str();
-
-    switch (s.domain) {
-    case IComponentStore::ComponentTraits::Domain::VIDEO:
-        d->domain = C2Component::DOMAIN_VIDEO;
-        break;
-    case IComponentStore::ComponentTraits::Domain::AUDIO:
-        d->domain = C2Component::DOMAIN_AUDIO;
-        break;
-    case IComponentStore::ComponentTraits::Domain::IMAGE:
-        d->domain = C2Component::DOMAIN_IMAGE;
-        break;
-    case IComponentStore::ComponentTraits::Domain::OTHER:
-        d->domain = C2Component::DOMAIN_OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized ComponentTraits::Domain "
-                   << "with underlying value " << underlying_value(s.domain)
-                   << ".";
-        d->domain = static_cast<C2Component::domain_t>(s.domain);
-    }
-
-    switch (s.kind) {
-    case IComponentStore::ComponentTraits::Kind::DECODER:
-        d->kind = C2Component::KIND_DECODER;
-        break;
-    case IComponentStore::ComponentTraits::Kind::ENCODER:
-        d->kind = C2Component::KIND_ENCODER;
-        break;
-    case IComponentStore::ComponentTraits::Kind::OTHER:
-        d->kind = C2Component::KIND_OTHER;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized ComponentTraits::Kind "
-                   << "with underlying value " << underlying_value(s.kind)
-                   << ".";
-        d->kind = static_cast<C2Component::kind_t>(s.kind);
-    }
-
-    d->rank = static_cast<C2Component::rank_t>(s.rank);
-    d->mediaType = s.mediaType.c_str();
-    d->aliases.resize(s.aliases.size());
-    for (size_t i = 0; i < s.aliases.size(); ++i) {
-        d->aliases[i] = s.aliases[i];
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
-namespace /* unnamed */ {
-
-// C2ParamFieldValues -> ParamFieldValues
-bool objcpy(ParamFieldValues *d, const C2ParamFieldValues &s) {
-    if (!objcpy(&d->paramOrField, s.paramOrField)) {
-        LOG(ERROR) << "Invalid C2ParamFieldValues::paramOrField.";
-        return false;
-    }
-    if (s.values) {
-        d->values.resize(1);
-        if (!objcpy(&d->values[0], *s.values)) {
-            LOG(ERROR) << "Invalid C2ParamFieldValues::values.";
-            return false;
-        }
-        return true;
-    }
-    d->values.resize(0);
-    return true;
-}
-
-// ParamFieldValues -> C2ParamFieldValues
-bool objcpy(C2ParamFieldValues *d, const ParamFieldValues &s) {
-    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
-    if (s.values.size() == 1) {
-        d->values = std::make_unique<C2FieldSupportedValues>();
-        if (!objcpy(d->values.get(), s.values[0])) {
-            LOG(ERROR) << "Invalid ParamFieldValues::values.";
-            return false;
-        }
-        return true;
-    } else if (s.values.size() == 0) {
-        d->values.reset();
-        return true;
-    }
-    LOG(ERROR) << "Invalid ParamFieldValues: "
-                  "Two or more FieldSupportedValues objects exist in "
-                  "ParamFieldValues. "
-                  "Only zero or one is allowed.";
-    return false;
-}
-
-} // unnamed namespace
-
 // C2SettingResult -> SettingResult
 bool objcpy(SettingResult *d, const C2SettingResult &s) {
-    switch (s.failure) {
-    case C2SettingResult::BAD_TYPE:
-        d->failure = SettingResult::Failure::BAD_TYPE;
-        break;
-    case C2SettingResult::BAD_PORT:
-        d->failure = SettingResult::Failure::BAD_PORT;
-        break;
-    case C2SettingResult::BAD_INDEX:
-        d->failure = SettingResult::Failure::BAD_INDEX;
-        break;
-    case C2SettingResult::READ_ONLY:
-        d->failure = SettingResult::Failure::READ_ONLY;
-        break;
-    case C2SettingResult::MISMATCH:
-        d->failure = SettingResult::Failure::MISMATCH;
-        break;
-    case C2SettingResult::BAD_VALUE:
-        d->failure = SettingResult::Failure::BAD_VALUE;
-        break;
-    case C2SettingResult::CONFLICT:
-        d->failure = SettingResult::Failure::CONFLICT;
-        break;
-    case C2SettingResult::UNSUPPORTED:
-        d->failure = SettingResult::Failure::UNSUPPORTED;
-        break;
-    case C2SettingResult::INFO_BAD_VALUE:
-        d->failure = SettingResult::Failure::INFO_BAD_VALUE;
-        break;
-    case C2SettingResult::INFO_CONFLICT:
-        d->failure = SettingResult::Failure::INFO_CONFLICT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized C2SettingResult::Failure "
-                   << "with underlying value " << underlying_value(s.failure)
-                   << ".";
-        d->failure = static_cast<SettingResult::Failure>(s.failure);
-    }
-    if (!objcpy(&d->field, s.field)) {
-        LOG(ERROR) << "Invalid C2SettingResult::field.";
-        return false;
-    }
-    d->conflicts.resize(s.conflicts.size());
-    size_t i = 0;
-    for (const C2ParamFieldValues& sConflict : s.conflicts) {
-        ParamFieldValues &dConflict = d->conflicts[i++];
-        if (!objcpy(&dConflict, sConflict)) {
-            LOG(ERROR) << "Invalid C2SettingResult::conflicts["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // SettingResult -> std::unique_ptr<C2SettingResult>
 bool objcpy(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
-    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
-            .field = C2ParamFieldValues(C2ParamFieldBuilder()) });
-    if (!*d) {
-        LOG(ERROR) << "No memory for C2SettingResult.";
-        return false;
-    }
-
-    // failure
-    switch (s.failure) {
-    case SettingResult::Failure::BAD_TYPE:
-        (*d)->failure = C2SettingResult::BAD_TYPE;
-        break;
-    case SettingResult::Failure::BAD_PORT:
-        (*d)->failure = C2SettingResult::BAD_PORT;
-        break;
-    case SettingResult::Failure::BAD_INDEX:
-        (*d)->failure = C2SettingResult::BAD_INDEX;
-        break;
-    case SettingResult::Failure::READ_ONLY:
-        (*d)->failure = C2SettingResult::READ_ONLY;
-        break;
-    case SettingResult::Failure::MISMATCH:
-        (*d)->failure = C2SettingResult::MISMATCH;
-        break;
-    case SettingResult::Failure::BAD_VALUE:
-        (*d)->failure = C2SettingResult::BAD_VALUE;
-        break;
-    case SettingResult::Failure::CONFLICT:
-        (*d)->failure = C2SettingResult::CONFLICT;
-        break;
-    case SettingResult::Failure::UNSUPPORTED:
-        (*d)->failure = C2SettingResult::UNSUPPORTED;
-        break;
-    case SettingResult::Failure::INFO_BAD_VALUE:
-        (*d)->failure = C2SettingResult::INFO_BAD_VALUE;
-        break;
-    case SettingResult::Failure::INFO_CONFLICT:
-        (*d)->failure = C2SettingResult::INFO_CONFLICT;
-        break;
-    default:
-        LOG(DEBUG) << "Unrecognized SettingResult::Failure "
-                   << "with underlying value " << underlying_value(s.failure)
-                   << ".";
-        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failure);
-    }
-
-    // field
-    if (!objcpy(&(*d)->field, s.field)) {
-        LOG(ERROR) << "Invalid SettingResult::field.";
-        return false;
-    }
-
-    // conflicts
-    (*d)->conflicts.clear();
-    (*d)->conflicts.reserve(s.conflicts.size());
-    for (const ParamFieldValues& sConflict : s.conflicts) {
-        (*d)->conflicts.emplace_back(
-                C2ParamFieldValues{ C2ParamFieldBuilder(), nullptr });
-        if (!objcpy(&(*d)->conflicts.back(), sConflict)) {
-            LOG(ERROR) << "Invalid SettingResult::conflicts.";
-            return false;
-        }
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // C2ParamDescriptor -> ParamDescriptor
 bool objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
-    d->index = static_cast<ParamIndex>(s.index());
-    d->attrib = static_cast<hidl_bitfield<ParamDescriptor::Attrib>>(
-            _C2ParamInspector::GetAttrib(s));
-    d->name = s.name();
-    copyVector<uint32_t>(&d->dependencies, s.dependencies());
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // ParamDescriptor -> C2ParamDescriptor
 bool objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
-    std::vector<C2Param::Index> dDependencies;
-    dDependencies.reserve(s.dependencies.size());
-    for (const ParamIndex& sDependency : s.dependencies) {
-        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
-    }
-    *d = std::make_shared<C2ParamDescriptor>(
-            C2Param::Index(static_cast<uint32_t>(s.index)),
-            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
-            C2String(s.name.c_str()),
-            std::move(dDependencies));
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // C2StructDescriptor -> StructDescriptor
 bool objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
-    d->type = static_cast<ParamIndex>(s.coreIndex().coreIndex());
-    d->fields.resize(s.numFields());
-    size_t i = 0;
-    for (const auto& sField : s) {
-        FieldDescriptor& dField = d->fields[i++];
-        dField.fieldId.offset = static_cast<uint32_t>(
-                _C2ParamInspector::GetOffset(sField));
-        dField.fieldId.size = static_cast<uint32_t>(
-                _C2ParamInspector::GetSize(sField));
-        dField.type = static_cast<hidl_bitfield<FieldDescriptor::Type>>(
-                sField.type());
-        dField.extent = static_cast<uint32_t>(sField.extent());
-        dField.name = static_cast<hidl_string>(sField.name());
-        const auto& sNamedValues = sField.namedValues();
-        dField.namedValues.resize(sNamedValues.size());
-        size_t j = 0;
-        for (const auto& sNamedValue : sNamedValues) {
-            FieldDescriptor::NamedValue& dNamedValue = dField.namedValues[j++];
-            dNamedValue.name = static_cast<hidl_string>(sNamedValue.first);
-            dNamedValue.value = static_cast<PrimitiveValue>(
-                    sNamedValue.second.u64);
-        }
-    }
-    return true;
+    return ::android::objcpy(d, s);
 }
 
 // StructDescriptor -> C2StructDescriptor
 bool objcpy(std::unique_ptr<C2StructDescriptor> *d, const StructDescriptor &s) {
-    C2Param::CoreIndex dIndex = C2Param::CoreIndex(static_cast<uint32_t>(s.type));
-    std::vector<C2FieldDescriptor> dFields;
-    dFields.reserve(s.fields.size());
-    for (const auto &sField : s.fields) {
-        C2FieldDescriptor dField = {
-            static_cast<uint32_t>(sField.type),
-            sField.extent,
-            sField.name,
-            sField.fieldId.offset,
-            sField.fieldId.size };
-        C2FieldDescriptor::NamedValuesType namedValues;
-        namedValues.reserve(sField.namedValues.size());
-        for (const auto& sNamedValue : sField.namedValues) {
-            namedValues.emplace_back(
-                sNamedValue.name,
-                C2Value::Primitive(static_cast<uint64_t>(sNamedValue.value)));
-        }
-        _C2ParamInspector::AddNamedValues(dField, std::move(namedValues));
-        dFields.emplace_back(dField);
-    }
-    *d = std::make_unique<C2StructDescriptor>(
-            _C2ParamInspector::CreateStructDescriptor(dIndex, std::move(dFields)));
-    return true;
+    return ::android::objcpy(d, s);
 }
 
-namespace /* unnamed */ {
-
-// Find or add a hidl BaseBlock object from a given C2Handle* to a list and an
-// associated map.
-// Note: The handle is not cloned.
-bool _addBaseBlock(
-        uint32_t* index,
-        const C2Handle* handle,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!handle) {
-        LOG(ERROR) << "addBaseBlock called on a null C2Handle.";
-        return false;
-    }
-    auto it = baseBlockIndices->find(handle);
-    if (it != baseBlockIndices->end()) {
-        *index = it->second;
-    } else {
-        *index = baseBlocks->size();
-        baseBlockIndices->emplace(handle, *index);
-        baseBlocks->emplace_back();
-
-        BaseBlock &dBaseBlock = baseBlocks->back();
-        // This does not clone the handle.
-        dBaseBlock.nativeBlock(
-                reinterpret_cast<const native_handle_t*>(handle));
-
-    }
-    return true;
-}
-
-// Find or add a hidl BaseBlock object from a given BufferPoolData to a list and
-// an associated map.
-bool _addBaseBlock(
-        uint32_t* index,
-        const std::shared_ptr<BufferPoolData> bpData,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!bpData) {
-        LOG(ERROR) << "addBaseBlock called on a null BufferPoolData.";
-        return false;
-    }
-    auto it = baseBlockIndices->find(bpData.get());
-    if (it != baseBlockIndices->end()) {
-        *index = it->second;
-    } else {
-        *index = baseBlocks->size();
-        baseBlockIndices->emplace(bpData.get(), *index);
-        baseBlocks->emplace_back();
-
-        BaseBlock &dBaseBlock = baseBlocks->back();
-
-        if (bufferPoolSender) {
-            BufferStatusMessage pooledBlock;
-            ResultStatus bpStatus = bufferPoolSender->send(
-                    bpData,
-                    &pooledBlock);
-
-            if (bpStatus != ResultStatus::OK) {
-                LOG(ERROR) << "Failed to send buffer with BufferPool. Error: "
-                           << static_cast<int32_t>(bpStatus)
-                           << ".";
-                return false;
-            }
-            dBaseBlock.pooledBlock(pooledBlock);
-        }
-    }
-    return true;
-}
-
-bool addBaseBlock(
-        uint32_t* index,
-        const C2Handle* handle,
-        const std::shared_ptr<const _C2BlockPoolData>& blockPoolData,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!blockPoolData) {
-        // No BufferPoolData ==> NATIVE block.
-        return _addBaseBlock(
-                index, handle,
-                baseBlocks, baseBlockIndices);
-    }
-    switch (blockPoolData->getType()) {
-    case _C2BlockPoolData::TYPE_BUFFERPOOL: {
-            // BufferPoolData
-            std::shared_ptr<BufferPoolData> bpData;
-            if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData)
-                    || !bpData) {
-                LOG(ERROR) << "BufferPoolData unavailable in a block.";
-                return false;
-            }
-            return _addBaseBlock(
-                    index, bpData,
-                    bufferPoolSender, baseBlocks, baseBlockIndices);
-        }
-    case _C2BlockPoolData::TYPE_BUFFERQUEUE:
-        uint32_t gen;
-        uint64_t bqId;
-        int32_t bqSlot;
-        // Update handle if migration happened.
-        if (_C2BlockFactory::GetBufferQueueData(
-                blockPoolData, &gen, &bqId, &bqSlot)) {
-            android::MigrateNativeCodec2GrallocHandle(
-                    const_cast<native_handle_t*>(handle), gen, bqId, bqSlot);
-        }
-        return _addBaseBlock(
-                index, handle,
-                baseBlocks, baseBlockIndices);
-    default:
-        LOG(ERROR) << "Unknown C2BlockPoolData type.";
-        return false;
-    }
-}
-
-// C2Fence -> hidl_handle
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-bool objcpy(hidl_handle* d, const C2Fence& s) {
-    d->setTo(nullptr);
-    native_handle_t* handle = _C2FenceFactory::CreateNativeHandle(s);
-    if (handle) {
-        d->setTo(handle, true /* owns */);
-//  } else if (!s.ready()) {
-//      // TODO: we should wait for unmarshallable fences but this may not be
-//      // the best place for it. We can safely ignore here as at this time
-//      // all fences used here are marshallable.
-    }
-    return true;
-}
-
-// C2ConstLinearBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-bool objcpy(Block* d, const C2ConstLinearBlock& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    std::shared_ptr<const _C2BlockPoolData> bpData =
-            _C2BlockFactory::GetLinearBlockPoolData(s);
-    if (!addBaseBlock(&d->index, s.handle(), bpData,
-            bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid block data in C2ConstLinearBlock.";
-        return false;
-    }
-
-    // Create the metadata.
-    C2Hidl_RangeInfo dRangeInfo;
-    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
-    dRangeInfo.length = static_cast<uint32_t>(s.size());
-    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRangeInfo })) {
-        LOG(ERROR) << "Invalid range info in C2ConstLinearBlock.";
-        return false;
-    }
-
-    // Copy the fence
-    if (!objcpy(&d->fence, s.fence())) {
-        LOG(ERROR) << "Invalid C2ConstLinearBlock::fence.";
-        return false;
-    }
-    return true;
-}
-
-// C2ConstGraphicBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-bool objcpy(Block* d, const C2ConstGraphicBlock& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    std::shared_ptr<const _C2BlockPoolData> bpData =
-            _C2BlockFactory::GetGraphicBlockPoolData(s);
-    if (!addBaseBlock(&d->index, s.handle(), bpData,
-            bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid block data in C2ConstGraphicBlock.";
-        return false;
-    }
-
-    // Create the metadata.
-    C2Hidl_RectInfo dRectInfo;
-    C2Rect sRect = s.crop();
-    dRectInfo.left = static_cast<uint32_t>(sRect.left);
-    dRectInfo.top = static_cast<uint32_t>(sRect.top);
-    dRectInfo.width = static_cast<uint32_t>(sRect.width);
-    dRectInfo.height = static_cast<uint32_t>(sRect.height);
-    if (!createParamsBlob(&d->meta, std::vector<C2Param*>{ &dRectInfo })) {
-        LOG(ERROR) << "Invalid rect info in C2ConstGraphicBlock.";
-        return false;
-    }
-
-    // Copy the fence
-    if (!objcpy(&d->fence, s.fence())) {
-        LOG(ERROR) << "Invalid C2ConstGraphicBlock::fence.";
-        return false;
-    }
-    return true;
-}
-
-// C2BufferData -> Buffer
-// This function only fills in d->blocks.
-bool objcpy(Buffer* d, const C2BufferData& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->blocks.resize(
-            s.linearBlocks().size() +
-            s.graphicBlocks().size());
-    size_t i = 0;
-    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        if (!objcpy(
-                &dBlock, linearBlock,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2BufferData::linearBlocks. "
-                       << "(Destination index = " << i - 1 << ".)";
-            return false;
-        }
-    }
-    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        if (!objcpy(
-                &dBlock, graphicBlock,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2BufferData::graphicBlocks. "
-                       << "(Destination index = " << i - 1 << ".)";
-            return false;
-        }
-    }
-    return true;
-}
-
-// C2Buffer -> Buffer
-bool objcpy(Buffer* d, const C2Buffer& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    if (!createParamsBlob(&d->info, s.info())) {
-        LOG(ERROR) << "Invalid C2Buffer::info.";
-        return false;
-    }
-    if (!objcpy(d, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid C2Buffer::data.";
-        return false;
-    }
-    return true;
-}
-
-// C2InfoBuffer -> InfoBuffer
-bool objcpy(InfoBuffer* d, const C2InfoBuffer& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->index = static_cast<ParamIndex>(s.index());
-    Buffer& dBuffer = d->buffer;
-    if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
-        LOG(ERROR) << "Invalid C2InfoBuffer::data";
-        return false;
-    }
-    return true;
-}
-
-// C2FrameData -> FrameData
-bool objcpy(FrameData* d, const C2FrameData& s,
-        BufferPoolSender* bufferPoolSender,
-        std::list<BaseBlock>* baseBlocks,
-        std::map<const void*, uint32_t>* baseBlockIndices) {
-    d->flags = static_cast<hidl_bitfield<FrameData::Flags>>(s.flags);
-    if (!objcpy(&d->ordinal, s.ordinal)) {
-        LOG(ERROR) << "Invalid C2FrameData::ordinal.";
-        return false;
-    }
-
-    d->buffers.resize(s.buffers.size());
-    size_t i = 0;
-    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
-        Buffer& dBuffer = d->buffers[i++];
-        if (!sBuffer) {
-            // A null (pointer to) C2Buffer corresponds to a Buffer with empty
-            // info and blocks.
-            dBuffer.info.resize(0);
-            dBuffer.blocks.resize(0);
-            continue;
-        }
-        if (!objcpy(
-                &dBuffer, *sBuffer,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2FrameData::buffers["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-
-    if (!createParamsBlob(&d->configUpdate, s.configUpdate)) {
-        LOG(ERROR) << "Invalid C2FrameData::configUpdate.";
-        return false;
-    }
-
-    d->infoBuffers.resize(s.infoBuffers.size());
-    i = 0;
-    for (const C2InfoBuffer& sInfoBuffer : s.infoBuffers) {
-        InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
-        if (!objcpy(&dInfoBuffer, sInfoBuffer,
-                bufferPoolSender, baseBlocks, baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
-                       << i - 1 << "].";
-            return false;
-        }
-    }
-
-    return true;
-}
-
-} // unnamed namespace
-
 // DefaultBufferPoolSender's implementation
 
 DefaultBufferPoolSender::DefaultBufferPoolSender(
@@ -1058,757 +415,73 @@
         WorkBundle* d,
         const std::list<std::unique_ptr<C2Work>>& s,
         BufferPoolSender* bufferPoolSender) {
-    // baseBlocks holds a list of BaseBlock objects that Blocks can refer to.
-    std::list<BaseBlock> baseBlocks;
-
-    // baseBlockIndices maps a raw pointer to native_handle_t or BufferPoolData
-    // inside baseBlocks to the corresponding index into baseBlocks. The keys
-    // (pointers) are used to identify blocks that have the same "base block" in
-    // s, a list of C2Work objects. Because baseBlocks will be copied into a
-    // hidl_vec eventually, the values of baseBlockIndices are zero-based
-    // integer indices instead of list iterators.
-    //
-    // Note that the pointers can be raw because baseBlockIndices has a shorter
-    // lifespan than all of base blocks.
-    std::map<const void*, uint32_t> baseBlockIndices;
-
-    d->works.resize(s.size());
-    size_t i = 0;
-    for (const std::unique_ptr<C2Work>& sWork : s) {
-        Work &dWork = d->works[i++];
-        if (!sWork) {
-            LOG(WARNING) << "Null C2Work encountered.";
-            continue;
-        }
-
-        // chain info is not in use currently.
-
-        // input
-        if (!objcpy(&dWork.input, sWork->input,
-                bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
-            LOG(ERROR) << "Invalid C2Work::input.";
-            return false;
-        }
-
-        // worklets
-        if (sWork->worklets.size() == 0) {
-            LOG(DEBUG) << "Work with no worklets.";
-        } else {
-            // Parcel the worklets.
-            hidl_vec<Worklet> &dWorklets = dWork.worklets;
-            dWorklets.resize(sWork->worklets.size());
-            size_t j = 0;
-            for (const std::unique_ptr<C2Worklet>& sWorklet : sWork->worklets)
-            {
-                if (!sWorklet) {
-                    LOG(WARNING) << "Null C2Work::worklets["
-                                 << j << "].";
-                    continue;
-                }
-                Worklet &dWorklet = dWorklets[j++];
-
-                // component id
-                dWorklet.componentId = static_cast<uint32_t>(
-                        sWorklet->component);
-
-                // tunings
-                if (!createParamsBlob(&dWorklet.tunings, sWorklet->tunings)) {
-                    LOG(ERROR) << "Invalid C2Work::worklets["
-                               << j - 1 << "]->tunings.";
-                    return false;
-                }
-
-                // failures
-                dWorklet.failures.resize(sWorklet->failures.size());
-                size_t k = 0;
-                for (const std::unique_ptr<C2SettingResult>& sFailure :
-                        sWorklet->failures) {
-                    if (!sFailure) {
-                        LOG(WARNING) << "Null C2Work::worklets["
-                                     << j - 1 << "]->failures["
-                                     << k << "].";
-                        continue;
-                    }
-                    if (!objcpy(&dWorklet.failures[k++], *sFailure)) {
-                        LOG(ERROR) << "Invalid C2Work::worklets["
-                                   << j - 1 << "]->failures["
-                                   << k - 1 << "].";
-                        return false;
-                    }
-                }
-
-                // output
-                if (!objcpy(&dWorklet.output, sWorklet->output,
-                        bufferPoolSender, &baseBlocks, &baseBlockIndices)) {
-                    LOG(ERROR) << "Invalid C2Work::worklets["
-                               << j - 1 << "]->output.";
-                    return false;
-                }
-            }
-        }
-
-        // worklets processed
-        dWork.workletsProcessed = sWork->workletsProcessed;
-
-        // result
-        dWork.result = static_cast<Status>(sWork->result);
-    }
-
-    // Copy std::list<BaseBlock> to hidl_vec<BaseBlock>.
-    {
-        d->baseBlocks.resize(baseBlocks.size());
-        size_t i = 0;
-        for (const BaseBlock& baseBlock : baseBlocks) {
-            d->baseBlocks[i++] = baseBlock;
-        }
-    }
-
-    return true;
+    return ::android::objcpy(d, s, bufferPoolSender);
 }
 
-namespace /* unnamed */ {
-
-struct C2BaseBlock {
-    enum type_t {
-        LINEAR,
-        GRAPHIC,
-    };
-    type_t type;
-    std::shared_ptr<C2LinearBlock> linear;
-    std::shared_ptr<C2GraphicBlock> graphic;
-};
-
-// hidl_handle -> C2Fence
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-bool objcpy(C2Fence* d, const hidl_handle& s) {
-    const native_handle_t* handle = s.getNativeHandle();
-    *d = _C2FenceFactory::CreateFromNativeHandle(handle);
-    return true;
-}
-
-// C2LinearBlock, vector<C2Param*>, C2Fence -> C2Buffer
-bool createLinearBuffer(
-        std::shared_ptr<C2Buffer>* buffer,
-        const std::shared_ptr<C2LinearBlock>& block,
-        const std::vector<C2Param*>& meta,
-        const C2Fence& fence) {
-    // Check the block meta. It should have exactly 1 C2Info:
-    // C2Hidl_RangeInfo.
-    if ((meta.size() != 1) || !meta[0]) {
-        LOG(ERROR) << "Invalid C2LinearBlock::meta.";
-        return false;
-    }
-    if (meta[0]->size() != sizeof(C2Hidl_RangeInfo)) {
-        LOG(ERROR) << "Invalid range info in C2LinearBlock.";
-        return false;
-    }
-    C2Hidl_RangeInfo *rangeInfo =
-            reinterpret_cast<C2Hidl_RangeInfo*>(meta[0]);
-
-    // Create C2Buffer from C2LinearBlock.
-    *buffer = C2Buffer::CreateLinearBuffer(block->share(
-            rangeInfo->offset, rangeInfo->length,
-            fence));
-    if (!(*buffer)) {
-        LOG(ERROR) << "CreateLinearBuffer failed.";
-        return false;
-    }
-    return true;
-}
-
-// C2GraphicBlock, vector<C2Param*>, C2Fence -> C2Buffer
-bool createGraphicBuffer(
-        std::shared_ptr<C2Buffer>* buffer,
-        const std::shared_ptr<C2GraphicBlock>& block,
-        const std::vector<C2Param*>& meta,
-        const C2Fence& fence) {
-    // Check the block meta. It should have exactly 1 C2Info:
-    // C2Hidl_RectInfo.
-    if ((meta.size() != 1) || !meta[0]) {
-        LOG(ERROR) << "Invalid C2GraphicBlock::meta.";
-        return false;
-    }
-    if (meta[0]->size() != sizeof(C2Hidl_RectInfo)) {
-        LOG(ERROR) << "Invalid rect info in C2GraphicBlock.";
-        return false;
-    }
-    C2Hidl_RectInfo *rectInfo =
-            reinterpret_cast<C2Hidl_RectInfo*>(meta[0]);
-
-    // Create C2Buffer from C2GraphicBlock.
-    *buffer = C2Buffer::CreateGraphicBuffer(block->share(
-            C2Rect(rectInfo->width, rectInfo->height).
-            at(rectInfo->left, rectInfo->top),
-            fence));
-    if (!(*buffer)) {
-        LOG(ERROR) << "CreateGraphicBuffer failed.";
-        return false;
-    }
-    return true;
-}
-
-// Buffer -> C2Buffer
-// Note: The native handles will be cloned.
-bool objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-    *d = nullptr;
-
-    // Currently, a non-null C2Buffer must contain exactly 1 block.
-    if (s.blocks.size() == 0) {
-        return true;
-    } else if (s.blocks.size() != 1) {
-        LOG(ERROR) << "Invalid Buffer: "
-                      "Currently, a C2Buffer must contain exactly 1 block.";
-        return false;
-    }
-
-    const Block &sBlock = s.blocks[0];
-    if (sBlock.index >= baseBlocks.size()) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].index: "
-                      "Array index out of range.";
-        return false;
-    }
-    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
-
-    // Parse meta.
-    std::vector<C2Param*> sBlockMeta;
-    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].meta.";
-        return false;
-    }
-
-    // Copy fence.
-    C2Fence dFence;
-    if (!objcpy(&dFence, sBlock.fence)) {
-        LOG(ERROR) << "Invalid Buffer::blocks[0].fence.";
-        return false;
-    }
-
-    // Construct a block.
-    switch (baseBlock.type) {
-    case C2BaseBlock::LINEAR:
-        if (!createLinearBuffer(d, baseBlock.linear, sBlockMeta, dFence)) {
-            LOG(ERROR) << "Invalid C2BaseBlock::linear.";
-            return false;
-        }
-        break;
-    case C2BaseBlock::GRAPHIC:
-        if (!createGraphicBuffer(d, baseBlock.graphic, sBlockMeta, dFence)) {
-            LOG(ERROR) << "Invalid C2BaseBlock::graphic.";
-            return false;
-        }
-        break;
-    default:
-        LOG(ERROR) << "Invalid C2BaseBlock::type.";
-        return false;
-    }
-
-    // Parse info
-    std::vector<C2Param*> params;
-    if (!parseParamsBlob(&params, s.info)) {
-        LOG(ERROR) << "Invalid Buffer::info.";
-        return false;
-    }
-    for (C2Param* param : params) {
-        if (param == nullptr) {
-            LOG(ERROR) << "Null param in Buffer::info.";
-            return false;
-        }
-        std::shared_ptr<C2Param> c2param{
-                C2Param::Copy(*param).release()};
-        if (!c2param) {
-            LOG(ERROR) << "Invalid param in Buffer::info.";
-            return false;
-        }
-        c2_status_t status =
-                (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
-        if (status != C2_OK) {
-            LOG(ERROR) << "C2Buffer::setInfo failed.";
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// InfoBuffer -> C2InfoBuffer
-bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-
-    // Currently, a non-null C2InfoBufer must contain exactly 1 block.
-    if (s.buffer.blocks.size() == 0) {
-        return true;
-    } else if (s.buffer.blocks.size() != 1) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer "
-                      "Currently, a C2InfoBuffer must contain exactly 1 block.";
-        return false;
-    }
-
-    const Block &sBlock = s.buffer.blocks[0];
-    if (sBlock.index >= baseBlocks.size()) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
-                      "Array index out of range.";
-        return false;
-    }
-    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
-
-    // Parse meta.
-    std::vector<C2Param*> sBlockMeta;
-    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
-        return false;
-    }
-
-    // Copy fence.
-    C2Fence dFence;
-    if (!objcpy(&dFence, sBlock.fence)) {
-        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
-        return false;
-    }
-
-    // Construct a block.
-    switch (baseBlock.type) {
-    case C2BaseBlock::LINEAR:
-        if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
-            sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
-            C2Hidl_RangeInfo *rangeInfo =
-                    reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
-            d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
-                    s.index,
-                    baseBlock.linear->share(
-                            rangeInfo->offset, rangeInfo->length, dFence)));
-            return true;
-        }
-        LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
-        break;
-    case C2BaseBlock::GRAPHIC:
-        // It's not used now
-        LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
-        break;
-    default:
-        LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
-        break;
-    }
-
-    return false;
-}
-
-// FrameData -> C2FrameData
-bool objcpy(C2FrameData* d, const FrameData& s,
-        const std::vector<C2BaseBlock>& baseBlocks) {
-    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
-    if (!objcpy(&d->ordinal, s.ordinal)) {
-        LOG(ERROR) << "Invalid FrameData::ordinal.";
-        return false;
-    }
-    d->buffers.clear();
-    d->buffers.reserve(s.buffers.size());
-    for (const Buffer& sBuffer : s.buffers) {
-        std::shared_ptr<C2Buffer> dBuffer;
-        if (!objcpy(&dBuffer, sBuffer, baseBlocks)) {
-            LOG(ERROR) << "Invalid FrameData::buffers.";
-            return false;
-        }
-        d->buffers.emplace_back(dBuffer);
-    }
-
-    std::vector<C2Param*> params;
-    if (!parseParamsBlob(&params, s.configUpdate)) {
-        LOG(ERROR) << "Invalid FrameData::configUpdate.";
-        return false;
-    }
-    d->configUpdate.clear();
-    for (C2Param* param : params) {
-        d->configUpdate.emplace_back(C2Param::Copy(*param));
-        if (!d->configUpdate.back()) {
-            LOG(ERROR) << "Unexpected error while parsing "
-                          "FrameData::configUpdate.";
-            return false;
-        }
-    }
-
-    d->infoBuffers.clear();
-    if (s.infoBuffers.size() == 0) {
-        // InfoBuffer is optional
-        return true;
-    }
-    d->infoBuffers.reserve(s.infoBuffers.size());
-    for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
-        if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
-            LOG(ERROR) << "Invalid Framedata::infoBuffers.";
-            return false;
-        }
-    }
-    return true;
-}
-
-// BaseBlock -> C2BaseBlock
-bool objcpy(C2BaseBlock* d, const BaseBlock& s) {
-    switch (s.getDiscriminator()) {
-    case BaseBlock::hidl_discriminator::nativeBlock: {
-            if (s.nativeBlock() == nullptr) {
-                LOG(ERROR) << "Null BaseBlock::nativeBlock handle";
-                return false;
-            }
-            native_handle_t* sHandle =
-                    native_handle_clone(s.nativeBlock());
-            if (sHandle == nullptr) {
-                LOG(ERROR) << "Null BaseBlock::nativeBlock.";
-                return false;
-            }
-            const C2Handle *sC2Handle =
-                    reinterpret_cast<const C2Handle*>(sHandle);
-
-            d->linear = _C2BlockFactory::CreateLinearBlock(sC2Handle);
-            if (d->linear) {
-                d->type = C2BaseBlock::LINEAR;
-                return true;
-            }
-
-            d->graphic = _C2BlockFactory::CreateGraphicBlock(sC2Handle);
-            if (d->graphic) {
-                d->type = C2BaseBlock::GRAPHIC;
-                return true;
-            }
-
-            LOG(ERROR) << "Unknown handle type in BaseBlock::nativeBlock.";
-            if (sHandle) {
-                native_handle_close(sHandle);
-                native_handle_delete(sHandle);
-            }
-            return false;
-        }
-    case BaseBlock::hidl_discriminator::pooledBlock: {
-            const BufferStatusMessage &bpMessage =
-                    s.pooledBlock();
-            sp<ClientManager> bp = ClientManager::getInstance();
-            std::shared_ptr<BufferPoolData> bpData;
-            native_handle_t *cHandle;
-            ResultStatus bpStatus = bp->receive(
-                    bpMessage.connectionId,
-                    bpMessage.transactionId,
-                    bpMessage.bufferId,
-                    bpMessage.timestampUs,
-                    &cHandle,
-                    &bpData);
-            if (bpStatus != ResultStatus::OK) {
-                LOG(ERROR) << "Failed to receive buffer from bufferpool -- "
-                           << "resultStatus = " << underlying_value(bpStatus)
-                           << ".";
-                return false;
-            } else if (!bpData) {
-                LOG(ERROR) << "No data in bufferpool transaction.";
-                return false;
-            }
-
-            d->linear = _C2BlockFactory::CreateLinearBlock(cHandle, bpData);
-            if (d->linear) {
-                d->type = C2BaseBlock::LINEAR;
-                return true;
-            }
-
-            d->graphic = _C2BlockFactory::CreateGraphicBlock(cHandle, bpData);
-            if (d->graphic) {
-                d->type = C2BaseBlock::GRAPHIC;
-                return true;
-            }
-            if (cHandle) {
-                // Though we got cloned handle, creating block failed.
-                native_handle_close(cHandle);
-                native_handle_delete(cHandle);
-            }
-
-            LOG(ERROR) << "Unknown handle type in BaseBlock::pooledBlock.";
-            return false;
-        }
-    default:
-        LOG(ERROR) << "Unrecognized BaseBlock's discriminator with "
-                   << "underlying value "
-                   << underlying_value(s.getDiscriminator()) << ".";
-        return false;
-    }
-}
-
-} // unnamed namespace
-
 // WorkBundle -> std::list<std::unique_ptr<C2Work>>
 bool objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
-    // Convert BaseBlocks to C2BaseBlocks.
-    std::vector<C2BaseBlock> dBaseBlocks(s.baseBlocks.size());
-    for (size_t i = 0; i < s.baseBlocks.size(); ++i) {
-        if (!objcpy(&dBaseBlocks[i], s.baseBlocks[i])) {
-            LOG(ERROR) << "Invalid WorkBundle::baseBlocks["
-                       << i << "].";
-            return false;
-        }
-    }
-
-    d->clear();
-    for (const Work& sWork : s.works) {
-        d->emplace_back(std::make_unique<C2Work>());
-        C2Work& dWork = *d->back();
-
-        // chain info is not in use currently.
-
-        // input
-        if (!objcpy(&dWork.input, sWork.input, dBaseBlocks)) {
-            LOG(ERROR) << "Invalid Work::input.";
-            return false;
-        }
-
-        // worklet(s)
-        dWork.worklets.clear();
-        for (const Worklet& sWorklet : sWork.worklets) {
-            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
-
-            // component id
-            dWorklet->component = static_cast<c2_node_id_t>(
-                    sWorklet.componentId);
-
-            // tunings
-            if (!copyParamsFromBlob(&dWorklet->tunings, sWorklet.tunings)) {
-                LOG(ERROR) << "Invalid Worklet::tunings";
-                return false;
-            }
-
-            // failures
-            dWorklet->failures.clear();
-            dWorklet->failures.reserve(sWorklet.failures.size());
-            for (const SettingResult& sFailure : sWorklet.failures) {
-                std::unique_ptr<C2SettingResult> dFailure;
-                if (!objcpy(&dFailure, sFailure)) {
-                    LOG(ERROR) << "Invalid Worklet::failures.";
-                    return false;
-                }
-                dWorklet->failures.emplace_back(std::move(dFailure));
-            }
-
-            // output
-            if (!objcpy(&dWorklet->output, sWorklet.output, dBaseBlocks)) {
-                LOG(ERROR) << "Invalid Worklet::output.";
-                return false;
-            }
-
-            dWork.worklets.emplace_back(std::move(dWorklet));
-        }
-
-        // workletsProcessed
-        dWork.workletsProcessed = sWork.workletsProcessed;
-
-        // result
-        dWork.result = static_cast<c2_status_t>(sWork.result);
-    }
-
-    return true;
+    return ::android::objcpy(d, s);
 }
 
-constexpr size_t PARAMS_ALIGNMENT = 8;  // 64-bit alignment
-static_assert(PARAMS_ALIGNMENT % alignof(C2Param) == 0, "C2Param alignment mismatch");
-static_assert(PARAMS_ALIGNMENT % alignof(C2Info) == 0, "C2Param alignment mismatch");
-static_assert(PARAMS_ALIGNMENT % alignof(C2Tuning) == 0, "C2Param alignment mismatch");
-
 // Params -> std::vector<C2Param*>
 bool parseParamsBlob(std::vector<C2Param*> *params, const hidl_vec<uint8_t> &blob) {
-    // assuming blob is const here
-    size_t size = blob.size();
-    size_t ix = 0;
-    size_t old_ix = 0;
-    const uint8_t *data = blob.data();
-    C2Param *p = nullptr;
-
-    do {
-        p = C2ParamUtils::ParseFirst(data + ix, size - ix);
-        if (p) {
-            params->emplace_back(p);
-            old_ix = ix;
-            ix += p->size();
-            ix = align(ix, PARAMS_ALIGNMENT);
-            if (ix <= old_ix || ix > size) {
-                android_errorWriteLog(0x534e4554, "238083570");
-                break;
-            }
-        }
-    } while (p);
-
-    if (ix != size) {
-        LOG(ERROR) << "parseParamsBlob -- inconsistent sizes.";
-        return false;
-    }
-    return true;
+    return ::android::parseParamsBlob(params, blob);
 }
 
-namespace /* unnamed */ {
-
-/**
- * Concatenates a list of C2Params into a params blob. T is a container type
- * whose member type is compatible with C2Param*.
- *
- * \param[out] blob target blob
- * \param[in] params parameters to concatenate
- * \retval C2_OK if the blob was successfully created
- * \retval C2_BAD_VALUE if the blob was not successful created (this only
- *         happens if the parameters were not const)
- */
-template <typename T>
-bool _createParamsBlob(hidl_vec<uint8_t> *blob, const T &params) {
-    // assuming the parameter values are const
-    size_t size = 0;
-    for (const auto &p : params) {
-        if (!p) {
-            continue;
-        }
-        size += p->size();
-        size = align(size, PARAMS_ALIGNMENT);
-    }
-    blob->resize(size);
-    size_t ix = 0;
-    for (const auto &p : params) {
-        if (!p) {
-            continue;
-        }
-        // NEVER overwrite even if param values (e.g. size) changed
-        size_t paramSize = std::min(p->size(), size - ix);
-        std::copy(
-                reinterpret_cast<const uint8_t*>(&*p),
-                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
-                &(*blob)[ix]);
-        ix += paramSize;
-        ix = align(ix, PARAMS_ALIGNMENT);
-    }
-    blob->resize(ix);
-    if (ix != size) {
-        LOG(ERROR) << "createParamsBlob -- inconsistent sizes.";
-        return false;
-    }
-    return true;
-}
-
-/**
- * Parses a params blob and create a vector of new T objects that contain copies
- * of the params in the blob. T is C2Param or its compatible derived class.
- *
- * \param[out] params the resulting vector
- * \param[in] blob parameter blob to parse
- * \retval C2_OK if the full blob was parsed and params was constructed
- * \retval C2_BAD_VALUE otherwise
- */
-template <typename T>
-bool _copyParamsFromBlob(
-        std::vector<std::unique_ptr<T>>* params,
-        Params blob) {
-
-    std::vector<C2Param*> paramPointers;
-    if (!parseParamsBlob(&paramPointers, blob)) {
-        LOG(ERROR) << "copyParamsFromBlob -- failed to parse.";
-        return false;
-    }
-
-    params->resize(paramPointers.size());
-    size_t i = 0;
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            LOG(ERROR) << "copyParamsFromBlob -- null paramPointer.";
-            return false;
-        }
-        (*params)[i++].reset(reinterpret_cast<T*>(
-                C2Param::Copy(*paramPointer).release()));
-    }
-    return true;
-}
-
-} // unnamed namespace
-
 // std::vector<const C2Param*> -> Params
 bool createParamsBlob(
         hidl_vec<uint8_t> *blob,
         const std::vector<const C2Param*> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<C2Param*> -> Params
 bool createParamsBlob(
         hidl_vec<uint8_t> *blob,
         const std::vector<C2Param*> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::unique_ptr<C2Param>> -> Params
 bool createParamsBlob(
         hidl_vec<uint8_t> *blob,
         const std::vector<std::unique_ptr<C2Param>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::unique_ptr<C2Tuning>> -> Params
 bool createParamsBlob(
         hidl_vec<uint8_t> *blob,
         const std::vector<std::unique_ptr<C2Tuning>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // std::vector<std::shared_ptr<const C2Info>> -> Params
 bool createParamsBlob(
         hidl_vec<uint8_t> *blob,
         const std::vector<std::shared_ptr<const C2Info>> &params) {
-    return _createParamsBlob(blob, params);
+    return ::android::_createParamsBlob(blob, params);
 }
 
 // Params -> std::vector<std::unique_ptr<C2Param>>
 bool copyParamsFromBlob(
         std::vector<std::unique_ptr<C2Param>>* params,
         Params blob) {
-    return _copyParamsFromBlob(params, blob);
+    return ::android::_copyParamsFromBlob(params, blob);
 }
 
 // Params -> std::vector<std::unique_ptr<C2Tuning>>
 bool copyParamsFromBlob(
         std::vector<std::unique_ptr<C2Tuning>>* params,
         Params blob) {
-    return _copyParamsFromBlob(params, blob);
+    return ::android::_copyParamsFromBlob(params, blob);
 }
 
 // Params -> update std::vector<std::unique_ptr<C2Param>>
 bool updateParamsFromBlob(
         const std::vector<C2Param*>& params,
         const Params& blob) {
-    std::unordered_map<uint32_t, C2Param*> index2param;
-    for (C2Param* const& param : params) {
-        if (!param) {
-            LOG(ERROR) << "updateParamsFromBlob -- null output param.";
-            return false;
-        }
-        if (index2param.find(param->index()) == index2param.end()) {
-            index2param.emplace(param->index(), param);
-        }
-    }
-
-    std::vector<C2Param*> paramPointers;
-    if (!parseParamsBlob(&paramPointers, blob)) {
-        LOG(ERROR) << "updateParamsFromBlob -- failed to parse.";
-        return false;
-    }
-
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            LOG(ERROR) << "updateParamsFromBlob -- null input param.";
-            return false;
-        }
-        decltype(index2param)::iterator i = index2param.find(
-                paramPointer->index());
-        if (i == index2param.end()) {
-            LOG(DEBUG) << "updateParamsFromBlob -- index "
-                       << paramPointer->index() << " not found. Skipping...";
-            continue;
-        }
-        if (!i->second->updateFrom(*paramPointer)) {
-            LOG(ERROR) << "updateParamsFromBlob -- size mismatch: "
-                       << params.size() << " vs " << paramPointer->size()
-                       << " (index = " << i->first << ").";
-            return false;
-        }
-    }
-    return true;
+    return ::android::updateParamsFromBlob(params, blob);
 }
 
 // Convert BufferPool ResultStatus to c2_status_t.
@@ -1831,92 +504,35 @@
     }
 }
 
-namespace /* unnamed */ {
-
-template <typename BlockProcessor>
-void forEachBlock(C2FrameData& frameData,
-                  BlockProcessor process) {
-    for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) {
-        if (buffer) {
-            for (const C2ConstGraphicBlock& block :
-                    buffer->data().graphicBlocks()) {
-                process(block);
-            }
-        }
-    }
-}
-
-template <typename BlockProcessor>
-void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList,
-                  BlockProcessor process,
-                  bool processInput, bool processOutput) {
-    for (const std::unique_ptr<C2Work>& work : workList) {
-        if (!work) {
-            continue;
-        }
-        if (processInput) {
-            forEachBlock(work->input, process);
-        }
-        if (processOutput) {
-            for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
-                if (worklet) {
-                    forEachBlock(worklet->output,
-                                 process);
-                }
-            }
-        }
-    }
-}
-
-} // unnamed namespace
-
+// BufferQueue-Based Block Operations
 bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::BeginTransferBlockToClient(data);
-        return true;
-    }
-    return false;
+    return ::android::BeginTransferBufferQueueBlock(block);
 }
 
 void beginTransferBufferQueueBlocks(
         const std::list<std::unique_ptr<C2Work>>& workList,
-        bool processInput, bool processOutput) {
-    forEachBlock(workList, beginTransferBufferQueueBlock,
-                 processInput, processOutput);
+        bool processInput,
+        bool processOutput) {
+    return ::android::BeginTransferBufferQueueBlocks(
+            workList, processInput, processOutput);
 }
 
-bool endTransferBufferQueueBlock(
-        const C2ConstGraphicBlock& block,
-        bool transfer) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::EndTransferBlockToClient(data, transfer);
-        return true;
-    }
-    return false;
+bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block,
+                                 bool transfer) {
+    return ::android::EndTransferBufferQueueBlock(block, transfer);
 }
 
 void endTransferBufferQueueBlocks(
         const std::list<std::unique_ptr<C2Work>>& workList,
         bool transfer,
-        bool processInput, bool processOutput) {
-    forEachBlock(workList,
-                 std::bind(endTransferBufferQueueBlock,
-                           std::placeholders::_1, transfer),
-                 processInput, processOutput);
+        bool processInput,
+        bool processOutput) {
+    return ::android::EndTransferBufferQueueBlocks(
+            workList, transfer, processInput, processOutput);
 }
 
 bool displayBufferQueueBlock(const C2ConstGraphicBlock& block) {
-    std::shared_ptr<_C2BlockPoolData> data =
-            _C2BlockFactory::GetGraphicBlockPoolData(block);
-    if (data && _C2BlockFactory::GetBufferQueueData(data)) {
-        _C2BlockFactory::DisplayBlockToBufferQueue(data);
-        return true;
-    }
-    return false;
+    return ::android::DisplayBufferQueueBlock(block);
 }
 
 }  // namespace utils
diff --git a/media/codec2/hal/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hal/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 117d9ca..3dc5b29 100644
--- a/media/codec2/hal/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hal/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -438,6 +438,7 @@
                    std::ifstream& eleStream, android::Vector<FrameInfo>* Info, int offset,
                    int range, bool signalEOS = true) {
     typedef std::unique_lock<std::mutex> ULock;
+    static const size_t kPageSize = getpagesize();
     int frameID = offset;
     int maxRetry = 0;
     while (1) {
@@ -479,7 +480,7 @@
         ASSERT_EQ(eleStream.gcount(), size);
 
         work->input.buffers.clear();
-        auto alignedSize = ALIGN(size, PAGE_SIZE);
+        auto alignedSize = ALIGN(size, kPageSize);
         if (size) {
             std::shared_ptr<C2LinearBlock> block;
             ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock(
diff --git a/media/codec2/hal/hidl/1.1/utils/Android.bp b/media/codec2/hal/hidl/1.1/utils/Android.bp
index ed77a15..4f86511 100644
--- a/media/codec2/hal/hidl/1.1/utils/Android.bp
+++ b/media/codec2/hal/hidl/1.1/utils/Android.bp
@@ -52,12 +52,6 @@
         "libstagefright_bufferpool@2.0.1",
         "libui",
     ],
-
-    // Device does not boot when global ThinLTO is enabled for this library.
-    // http://b/170595429
-    lto: {
-        never: true,
-    },
 }
 
 
diff --git a/media/codec2/hal/hidl/1.1/utils/Component.cpp b/media/codec2/hal/hidl/1.1/utils/Component.cpp
index 2dd922f..d0f4f19 100644
--- a/media/codec2/hal/hidl/1.1/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.1/utils/Component.cpp
@@ -222,6 +222,21 @@
     return mInit;
 }
 
+void Component::onDeathReceived() {
+    {
+        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+        mClientDied = true;
+        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
+            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
+                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
+                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
+                bqPool->invalidate();
+            }
+        }
+    }
+    release();
+}
+
 // Methods from ::android::hardware::media::c2::V1_1::IComponent
 Return<Status> Component::queue(const WorkBundle& workBundle) {
     std::list<std::unique_ptr<C2Work>> c2works;
@@ -409,9 +424,19 @@
         blockPool = nullptr;
     }
     if (blockPool) {
-        mBlockPoolsMutex.lock();
-        mBlockPools.emplace(blockPool->getLocalId(), blockPool);
-        mBlockPoolsMutex.unlock();
+        bool emplaced = false;
+        {
+            mBlockPoolsMutex.lock();
+            if (!mClientDied) {
+                mBlockPools.emplace(blockPool->getLocalId(), blockPool);
+                emplaced = true;
+            }
+            mBlockPoolsMutex.unlock();
+        }
+        if (!emplaced) {
+            blockPool.reset();
+            status = C2_BAD_STATE;
+        }
     } else if (status == C2_OK) {
         status = C2_CORRUPTED;
     }
@@ -501,8 +526,8 @@
                 ) override {
             auto strongComponent = component.promote();
             if (strongComponent) {
-                LOG(INFO) << "Client died ! release the component !!";
-                strongComponent->release();
+                LOG(INFO) << "Client died ! notify and release the component !!";
+                strongComponent->onDeathReceived();
             } else {
                 LOG(ERROR) << "Client died ! no component to release !!";
             }
diff --git a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h
index 1c8c20c..f16de24 100644
--- a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h
+++ b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h
@@ -69,6 +69,8 @@
             const sp<::android::hardware::media::bufferpool::V2_0::
                 IClientManager>& clientPoolManager);
     c2_status_t status() const;
+    // Receives a death notification of the client.
+    void onDeathReceived();
 
     typedef ::android::hardware::graphics::bufferqueue::V1_0::
             IGraphicBufferProducer HGraphicBufferProducer1;
@@ -140,6 +142,7 @@
 
     using HwDeathRecipient = ::android::hardware::hidl_death_recipient;
     sp<HwDeathRecipient> mDeathRecipient;
+    bool mClientDied{false};
 };
 
 } // namespace utils
diff --git a/media/codec2/hal/hidl/1.2/utils/Android.bp b/media/codec2/hal/hidl/1.2/utils/Android.bp
index e4e4ad5..b92dc07 100644
--- a/media/codec2/hal/hidl/1.2/utils/Android.bp
+++ b/media/codec2/hal/hidl/1.2/utils/Android.bp
@@ -56,12 +56,6 @@
         "libstagefright_bufferpool@2.0.1",
         "libui",
     ],
-
-    // Device does not boot when global ThinLTO is enabled for this library.
-    // http://b/170595429
-    lto: {
-        never: true,
-    },
 }
 
 
diff --git a/media/codec2/hal/hidl/1.2/utils/Component.cpp b/media/codec2/hal/hidl/1.2/utils/Component.cpp
index 7994d32..036c900 100644
--- a/media/codec2/hal/hidl/1.2/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.2/utils/Component.cpp
@@ -222,6 +222,21 @@
     return mInit;
 }
 
+void Component::onDeathReceived() {
+    {
+        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+        mClientDied = true;
+        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
+            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
+                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
+                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
+                bqPool->invalidate();
+            }
+        }
+    }
+    release();
+}
+
 // Methods from ::android::hardware::media::c2::V1_1::IComponent
 Return<Status> Component::queue(const WorkBundle& workBundle) {
     std::list<std::unique_ptr<C2Work>> c2works;
@@ -409,9 +424,19 @@
         blockPool = nullptr;
     }
     if (blockPool) {
-        mBlockPoolsMutex.lock();
-        mBlockPools.emplace(blockPool->getLocalId(), blockPool);
-        mBlockPoolsMutex.unlock();
+        bool emplaced = false;
+        {
+            mBlockPoolsMutex.lock();
+            if (!mClientDied) {
+                mBlockPools.emplace(blockPool->getLocalId(), blockPool);
+                emplaced = true;
+            }
+            mBlockPoolsMutex.unlock();
+        }
+        if (!emplaced) {
+            blockPool.reset();
+            status = C2_BAD_STATE;
+        }
     } else if (status == C2_OK) {
         status = C2_CORRUPTED;
     }
@@ -532,8 +557,8 @@
                 ) override {
             auto strongComponent = component.promote();
             if (strongComponent) {
-                LOG(INFO) << "Client died ! release the component !!";
-                strongComponent->release();
+                LOG(INFO) << "Client died ! notify and release the component !!";
+                strongComponent->onDeathReceived();
             } else {
                 LOG(ERROR) << "Client died ! no component to release !!";
             }
diff --git a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/Component.h b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/Component.h
index d0972ee..6a73392 100644
--- a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/Component.h
+++ b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/Component.h
@@ -69,6 +69,8 @@
             const sp<::android::hardware::media::bufferpool::V2_0::
                 IClientManager>& clientPoolManager);
     c2_status_t status() const;
+    // Receives a death notification of the client.
+    void onDeathReceived();
 
     typedef ::android::hardware::graphics::bufferqueue::V1_0::
             IGraphicBufferProducer HGraphicBufferProducer1;
@@ -145,7 +147,7 @@
 
     using HwDeathRecipient = ::android::hardware::hidl_death_recipient;
     sp<HwDeathRecipient> mDeathRecipient;
-
+    bool mClientDied{false};
 };
 
 } // namespace utils
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index e4daf5c..d867eb1 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -52,7 +52,6 @@
         "android.hardware.drm@1.0",
         "android.hardware.media.c2@1.0",
         "android.hardware.media.omx@1.0",
-        "android.hardware.graphics.mapper@4.0",
         "libbase",
         "libbinder",
         "libcodec2",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 5e53acc..86fd8ab 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1808,6 +1808,10 @@
                            ACTION_CODE_FATAL);
         return;
     }
+
+    // clear the deadline after the component starts
+    setDeadline(TimePoint::max(), 0ms, "none");
+
     sp<AMessage> inputFormat;
     sp<AMessage> outputFormat;
     status_t err2 = OK;
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 228ad7e..3bb6593 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -26,9 +26,6 @@
 #include <android-base/properties.h>
 #include <android/hardware/cas/native/1.0/types.h>
 #include <android/hardware/drm/1.0/types.h>
-#include <android/hardware/graphics/common/1.2/types.h>
-#include <android/hardware/graphics/mapper/4.0/IMapper.h>
-#include <gralloctypes/Gralloc4.h>
 #include <hidlmemory/FrameworkUtils.h>
 #include <media/hardware/HardwareAPI.h>
 #include <media/stagefright/CodecBase.h>
@@ -38,6 +35,7 @@
 #include <media/stagefright/foundation/AUtils.h>
 #include <mediadrm/ICrypto.h>
 #include <nativebase/nativebase.h>
+#include <ui/GraphicBufferMapper.h>
 #include <ui/Fence.h>
 
 #include <C2AllocatorGralloc.h>
@@ -1039,34 +1037,15 @@
 }
 
 using ::aidl::android::hardware::graphics::common::Cta861_3;
-using ::aidl::android::hardware::graphics::common::Dataspace;
 using ::aidl::android::hardware::graphics::common::Smpte2086;
 
-using ::android::gralloc4::MetadataType_Cta861_3;
-using ::android::gralloc4::MetadataType_Dataspace;
-using ::android::gralloc4::MetadataType_Smpte2086;
-using ::android::gralloc4::MetadataType_Smpte2094_40;
-
-using ::android::hardware::Return;
-using ::android::hardware::hidl_vec;
-
-using Error4 = ::android::hardware::graphics::mapper::V4_0::Error;
-using IMapper4 = ::android::hardware::graphics::mapper::V4_0::IMapper;
-
 namespace {
 
-sp<IMapper4> GetMapper4() {
-    static ::android::base::NoDestructor<sp<IMapper4>> sMapper(IMapper4::getService());
-    return *sMapper;
-}
-
-class Gralloc4Buffer {
+class GrallocBuffer {
 public:
-    Gralloc4Buffer(const C2Handle *const handle) : mBuffer(nullptr) {
-        sp<IMapper4> mapper = GetMapper4();
-        if (!mapper) {
-            return;
-        }
+    GrallocBuffer(const C2Handle *const handle) : mBuffer(nullptr) {
+        GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+
         // Unwrap raw buffer handle from the C2Handle
         native_handle_t *nh = UnwrapNativeCodec2GrallocHandle(handle);
         if (!nh) {
@@ -1074,13 +1053,14 @@
         }
         // Import the raw handle so IMapper can use the buffer. The imported
         // handle must be freed when the client is done with the buffer.
-        mapper->importBuffer(
-                hardware::hidl_handle(nh),
-                [&](const Error4 &error, void *buffer) {
-                    if (error == Error4::NONE) {
-                        mBuffer = buffer;
-                    }
-                });
+        status_t status = mapper.importBufferNoValidate(
+                nh,
+                &mBuffer);
+
+        if (status != OK) {
+            ALOGE("Failed to import buffer. Status: %d.", status);
+            return;
+        }
 
         // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
         //         does not clone the fds. Thus we need to delete the handle
@@ -1088,19 +1068,19 @@
         native_handle_delete(nh);
     }
 
-    ~Gralloc4Buffer() {
-        sp<IMapper4> mapper = GetMapper4();
-        if (mapper && mBuffer) {
+    ~GrallocBuffer() {
+        GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+        if (mBuffer) {
             // Free the imported buffer handle. This does not release the
             // underlying buffer itself.
-            mapper->freeBuffer(mBuffer);
+            mapper.freeBuffer(mBuffer);
         }
     }
 
-    void *get() const { return mBuffer; }
+    buffer_handle_t get() const { return mBuffer; }
     operator bool() const { return (mBuffer != nullptr); }
 private:
-    void *mBuffer;
+    buffer_handle_t mBuffer;
 };
 
 }  // namspace
@@ -1110,69 +1090,48 @@
         std::shared_ptr<C2StreamHdrStaticMetadataInfo::input> *staticInfo,
         std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> *dynamicInfo) {
     c2_status_t err = C2_OK;
-    sp<IMapper4> mapper = GetMapper4();
-    Gralloc4Buffer buffer(handle);
-    if (!mapper || !buffer) {
+    GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+    GrallocBuffer buffer(handle);
+    if (!buffer) {
         // Gralloc4 not supported; nothing to do
         return err;
     }
-    Error4 mapperErr = Error4::NONE;
     if (staticInfo) {
-        ALOGV("Grabbing static HDR info from gralloc4 metadata");
+        ALOGV("Grabbing static HDR info from gralloc metadata");
         staticInfo->reset(new C2StreamHdrStaticMetadataInfo::input(0u));
         memset(&(*staticInfo)->mastering, 0, sizeof((*staticInfo)->mastering));
         (*staticInfo)->maxCll = 0;
         (*staticInfo)->maxFall = 0;
-        IMapper4::get_cb cb = [&mapperErr, staticInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
-            mapperErr = err;
-            if (err != Error4::NONE) {
-                return;
-            }
 
-            std::optional<Smpte2086> smpte2086;
-            gralloc4::decodeSmpte2086(vec, &smpte2086);
+        std::optional<Smpte2086> smpte2086;
+        status_t status = mapper.getSmpte2086(buffer.get(), &smpte2086);
+        if (status != OK) {
+            err = C2_CORRUPTED;
+        } else {
             if (smpte2086) {
-                (*staticInfo)->mastering.red.x    = smpte2086->primaryRed.x;
-                (*staticInfo)->mastering.red.y    = smpte2086->primaryRed.y;
-                (*staticInfo)->mastering.green.x  = smpte2086->primaryGreen.x;
-                (*staticInfo)->mastering.green.y  = smpte2086->primaryGreen.y;
-                (*staticInfo)->mastering.blue.x   = smpte2086->primaryBlue.x;
-                (*staticInfo)->mastering.blue.y   = smpte2086->primaryBlue.y;
-                (*staticInfo)->mastering.white.x  = smpte2086->whitePoint.x;
-                (*staticInfo)->mastering.white.y  = smpte2086->whitePoint.y;
+                  (*staticInfo)->mastering.red.x    = smpte2086->primaryRed.x;
+                  (*staticInfo)->mastering.red.y    = smpte2086->primaryRed.y;
+                  (*staticInfo)->mastering.green.x  = smpte2086->primaryGreen.x;
+                  (*staticInfo)->mastering.green.y  = smpte2086->primaryGreen.y;
+                  (*staticInfo)->mastering.blue.x   = smpte2086->primaryBlue.x;
+                  (*staticInfo)->mastering.blue.y   = smpte2086->primaryBlue.y;
+                  (*staticInfo)->mastering.white.x  = smpte2086->whitePoint.x;
+                  (*staticInfo)->mastering.white.y  = smpte2086->whitePoint.y;
 
-                (*staticInfo)->mastering.maxLuminance = smpte2086->maxLuminance;
-                (*staticInfo)->mastering.minLuminance = smpte2086->minLuminance;
-            } else {
-                mapperErr = Error4::BAD_VALUE;
+                  (*staticInfo)->mastering.maxLuminance = smpte2086->maxLuminance;
+                  (*staticInfo)->mastering.minLuminance = smpte2086->minLuminance;
             }
-        };
-        Return<void> ret = mapper->get(buffer.get(), MetadataType_Smpte2086, cb);
-        if (!ret.isOk()) {
-            err = C2_REFUSED;
-        } else if (mapperErr != Error4::NONE) {
-            err = C2_CORRUPTED;
         }
-        cb = [&mapperErr, staticInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
-            mapperErr = err;
-            if (err != Error4::NONE) {
-                return;
-            }
 
-            std::optional<Cta861_3> cta861_3;
-            gralloc4::decodeCta861_3(vec, &cta861_3);
-            if (cta861_3) {
-                (*staticInfo)->maxCll   = cta861_3->maxContentLightLevel;
-                (*staticInfo)->maxFall  = cta861_3->maxFrameAverageLightLevel;
-            } else {
-                mapperErr = Error4::BAD_VALUE;
-            }
-        };
-        ret = mapper->get(buffer.get(), MetadataType_Cta861_3, cb);
-        if (!ret.isOk()) {
-            err = C2_REFUSED;
-        } else if (mapperErr != Error4::NONE) {
+        std::optional<Cta861_3> cta861_3;
+        status = mapper.getCta861_3(buffer.get(), &cta861_3);
+        if (status != OK) {
             err = C2_CORRUPTED;
+        } else {
+            if (cta861_3) {
+                  (*staticInfo)->maxCll   = cta861_3->maxContentLightLevel;
+                  (*staticInfo)->maxFall  = cta861_3->maxFrameAverageLightLevel;
+            }
         }
     }
 
@@ -1181,23 +1140,19 @@
     }
 
     if (dynamicInfo) {
-        ALOGV("Grabbing dynamic HDR info from gralloc4 metadata");
+        ALOGV("Grabbing dynamic HDR info from gralloc metadata");
         dynamicInfo->reset();
-        IMapper4::get_cb cb = [&mapperErr, dynamicInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
-            mapperErr = err;
-            if (err != Error4::NONE) {
-                return;
-            }
-            if (!dynamicInfo) {
-                return;
-            }
-            *dynamicInfo = C2StreamHdrDynamicMetadataInfo::input::AllocShared(
-                    vec.size(), 0u, C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
-            memcpy((*dynamicInfo)->m.data, vec.data(), vec.size());
-        };
-        Return<void> ret = mapper->get(buffer.get(), MetadataType_Smpte2094_40, cb);
-        if (!ret.isOk() || mapperErr != Error4::NONE) {
+        std::optional<std::vector<uint8_t>> vec;
+        status_t status = mapper.getSmpte2094_40(buffer.get(), &vec);
+        if (status != OK) {
             dynamicInfo->reset();
+            err = C2_CORRUPTED;
+        } else {
+            if (vec) {
+                *dynamicInfo = C2StreamHdrDynamicMetadataInfo::input::AllocShared(
+                      vec->size(), 0u, C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
+                memcpy((*dynamicInfo)->m.data, vec->data(), vec->size());
+            }
         }
     }
 
@@ -1210,25 +1165,18 @@
         const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
         const C2Handle *const handle) {
     c2_status_t err = C2_OK;
-    sp<IMapper4> mapper = GetMapper4();
-    Gralloc4Buffer buffer(handle);
-    if (!mapper || !buffer) {
+    GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+    GrallocBuffer buffer(handle);
+    if (!buffer) {
         // Gralloc4 not supported; nothing to do
         return err;
     }
-    {
-        hidl_vec<uint8_t> metadata;
-        if (gralloc4::encodeDataspace(static_cast<Dataspace>(dataSpace), &metadata) == OK) {
-            Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Dataspace, metadata);
-            if (!ret.isOk()) {
-                err = C2_REFUSED;
-            } else if (ret != Error4::NONE) {
-                err = C2_CORRUPTED;
-            }
-        }
+    status_t status = mapper.setDataspace(buffer.get(), static_cast<ui::Dataspace>(dataSpace));
+    if (status != OK) {
+       err = C2_CORRUPTED;
     }
     if (staticInfo && *staticInfo) {
-        ALOGV("Setting static HDR info as gralloc4 metadata");
+        ALOGV("Setting static HDR info as gralloc metadata");
         std::optional<Smpte2086> smpte2086 = Smpte2086{
             {staticInfo->mastering.red.x, staticInfo->mastering.red.y},
             {staticInfo->mastering.green.x, staticInfo->mastering.green.y},
@@ -1237,7 +1185,6 @@
             staticInfo->mastering.maxLuminance,
             staticInfo->mastering.minLuminance,
         };
-        hidl_vec<uint8_t> vec;
         if (0.0 <= smpte2086->primaryRed.x && smpte2086->primaryRed.x <= 1.0
                 && 0.0 <= smpte2086->primaryRed.y && smpte2086->primaryRed.y <= 1.0
                 && 0.0 <= smpte2086->primaryGreen.x && smpte2086->primaryGreen.x <= 1.0
@@ -1246,12 +1193,9 @@
                 && 0.0 <= smpte2086->primaryBlue.y && smpte2086->primaryBlue.y <= 1.0
                 && 0.0 <= smpte2086->whitePoint.x && smpte2086->whitePoint.x <= 1.0
                 && 0.0 <= smpte2086->whitePoint.y && smpte2086->whitePoint.y <= 1.0
-                && 0.0 <= smpte2086->maxLuminance && 0.0 <= smpte2086->minLuminance
-                && gralloc4::encodeSmpte2086(smpte2086, &vec) == OK) {
-            Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Smpte2086, vec);
-            if (!ret.isOk()) {
-                err = C2_REFUSED;
-            } else if (ret != Error4::NONE) {
+                && 0.0 <= smpte2086->maxLuminance && 0.0 <= smpte2086->minLuminance) {
+            status = mapper.setSmpte2086(buffer.get(), smpte2086);
+            if (status != OK) {
                 err = C2_CORRUPTED;
             }
         }
@@ -1259,41 +1203,23 @@
             staticInfo->maxCll,
             staticInfo->maxFall,
         };
-        if (0.0 <= cta861_3->maxContentLightLevel && 0.0 <= cta861_3->maxFrameAverageLightLevel
-                && gralloc4::encodeCta861_3(cta861_3, &vec) == OK) {
-            Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Cta861_3, vec);
-            if (!ret.isOk()) {
-                err = C2_REFUSED;
-            } else if (ret != Error4::NONE) {
+        if (0.0 <= cta861_3->maxContentLightLevel && 0.0 <= cta861_3->maxFrameAverageLightLevel) {
+            status = mapper.setCta861_3(buffer.get(), cta861_3);
+            if (status != OK) {
                 err = C2_CORRUPTED;
             }
         }
     }
     if (dynamicInfo && *dynamicInfo && dynamicInfo->flexCount() > 0) {
-        ALOGV("Setting dynamic HDR info as gralloc4 metadata");
-        std::optional<IMapper4::MetadataType> metadataType;
-        switch (dynamicInfo->m.type_) {
-        case C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_10:
-            // TODO
-            break;
-        case C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40:
-            metadataType = MetadataType_Smpte2094_40;
-            break;
-        }
+        ALOGV("Setting dynamic HDR info as gralloc metadata");
+        if (dynamicInfo->m.type_ == C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40) {
+            std::optional<std::vector<uint8_t>> smpte2094_40 = std::vector<uint8_t>();
+            smpte2094_40->resize(dynamicInfo->flexCount());
+            memcpy(smpte2094_40->data(), dynamicInfo->m.data, dynamicInfo->flexCount());
 
-        if (metadataType) {
-            std::vector<uint8_t> smpte2094_40;
-            smpte2094_40.resize(dynamicInfo->flexCount());
-            memcpy(smpte2094_40.data(), dynamicInfo->m.data, dynamicInfo->flexCount());
-
-            hidl_vec<uint8_t> vec;
-            if (gralloc4::encodeSmpte2094_40({ smpte2094_40 }, &vec) == OK) {
-                Return<Error4> ret = mapper->set(buffer.get(), *metadataType, vec);
-                if (!ret.isOk()) {
-                    err = C2_REFUSED;
-                } else if (ret != Error4::NONE) {
-                    err = C2_CORRUPTED;
-                }
+            status = mapper.setSmpte2094_40(buffer.get(), smpte2094_40);
+            if (status != OK) {
+                err = C2_CORRUPTED;
             }
         } else {
             err = C2_BAD_VALUE;
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
index 332d3ac..43533fd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
@@ -31,11 +31,19 @@
 
 namespace android {
 
-bool isAtLeastT() {
+
+static bool isAtLeast(int version, const char *codeName) {
     char deviceCodeName[PROP_VALUE_MAX];
     __system_property_get("ro.build.version.codename", deviceCodeName);
-    return android_get_device_api_level() >= __ANDROID_API_T__ ||
-           !strcmp(deviceCodeName, "Tiramisu");
+    return android_get_device_api_level() >= version || !strcmp(deviceCodeName, codeName);
+}
+
+bool isAtLeastT() {
+    return isAtLeast(__ANDROID_API_T__, "Tiramisu");
+}
+
+bool isAtLeastU() {
+    return isAtLeast(__ANDROID_API_U__, "UpsideDownCake");
 }
 
 static bool isP010Allowed() {
@@ -82,7 +90,8 @@
         return false;
     }
 
-    const AHardwareBuffer_Desc desc = {
+    // Default scenario --- the consumer is display or GPU
+    const AHardwareBuffer_Desc consumableForDisplayOrGpu = {
             .width = 320,
             .height = 240,
             .format = format,
@@ -96,7 +105,46 @@
             .rfu1 = 0,
     };
 
-    return AHardwareBuffer_isSupported(&desc);
+    // The consumer is a HW encoder
+    const AHardwareBuffer_Desc consumableForHwEncoder = {
+            .width = 320,
+            .height = 240,
+            .format = format,
+            .layers = 1,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
+                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+                     AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY |
+                     AHARDWAREBUFFER_USAGE_VIDEO_ENCODE,
+            .stride = 0,
+            .rfu0 = 0,
+            .rfu1 = 0,
+    };
+
+    // The consumer is a SW encoder
+    const AHardwareBuffer_Desc consumableForSwEncoder = {
+            .width = 320,
+            .height = 240,
+            .format = format,
+            .layers = 1,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
+                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+                     AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY,
+            .stride = 0,
+            .rfu0 = 0,
+            .rfu1 = 0,
+    };
+    // Some devices running versions prior to Android U aren't guaranteed to advertise support
+    // for some color formats when the consumer is an encoder. Hence limit these checks to
+    // Android U and beyond.
+    if (isAtLeastU()) {
+        return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
+                && AHardwareBuffer_isSupported(&consumableForHwEncoder)
+                && AHardwareBuffer_isSupported(&consumableForSwEncoder);
+    } else {
+        return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu);
+    }
 }
 
 }  // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.h b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
index 98dd65b..9bb52bd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.h
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
@@ -23,6 +23,8 @@
 
 bool isAtLeastT();
 
+bool isAtLeastU();
+
 bool isVendorApiOrFirstApiAtLeastT();
 
 /**
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index ba25226..a59bd47 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -173,6 +173,7 @@
         "libbase", // for C2_LOG
         "liblog", // for ALOG
         "libcodec2",
+        "libcodec2_hal_common",
         "libcodec2_vndk",
         "libutils",
     ],
diff --git a/media/codec2/vndk/C2AllocatorIon.cpp b/media/codec2/vndk/C2AllocatorIon.cpp
index a6a733e..582a993 100644
--- a/media/codec2/vndk/C2AllocatorIon.cpp
+++ b/media/codec2/vndk/C2AllocatorIon.cpp
@@ -179,6 +179,7 @@
     static Impl *Alloc(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags, C2Allocator::id_t id);
 
     c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
+        static const size_t kPageSize = getpagesize();
         (void)fence; // TODO: wait for fence
         *addr = nullptr;
         if (!mMappings.lock()->empty()) {
@@ -201,7 +202,7 @@
             prot |= PROT_WRITE;
         }
 
-        size_t alignmentBytes = offset % PAGE_SIZE;
+        size_t alignmentBytes = offset % kPageSize;
         size_t mapOffset = offset - alignmentBytes;
         size_t mapSize = size + alignmentBytes;
         Mapping map = { nullptr, alignmentBytes, mapSize };
diff --git a/media/codec2/vndk/C2DmaBufAllocator.cpp b/media/codec2/vndk/C2DmaBufAllocator.cpp
index c470171..9baf8d8 100644
--- a/media/codec2/vndk/C2DmaBufAllocator.cpp
+++ b/media/codec2/vndk/C2DmaBufAllocator.cpp
@@ -170,6 +170,7 @@
 
 c2_status_t C2DmaBufAllocation::map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence* fence,
                                     void** addr) {
+    static const size_t kPageSize = getpagesize();
     (void)fence;  // TODO: wait for fence
     *addr = nullptr;
     if (!mMappings.lock()->empty()) {
@@ -192,7 +193,7 @@
         prot |= PROT_WRITE;
     }
 
-    size_t alignmentBytes = offset % PAGE_SIZE;
+    size_t alignmentBytes = offset % kPageSize;
     size_t mapOffset = offset - alignmentBytes;
     size_t mapSize = size + alignmentBytes;
     Mapping map = {nullptr, alignmentBytes, mapSize};
diff --git a/media/codec2/vndk/include/C2BqBufferPriv.h b/media/codec2/vndk/include/C2BqBufferPriv.h
index 29aad5e..320b192 100644
--- a/media/codec2/vndk/include/C2BqBufferPriv.h
+++ b/media/codec2/vndk/include/C2BqBufferPriv.h
@@ -103,6 +103,13 @@
 
     virtual void getConsumerUsage(uint64_t *consumerUsage);
 
+    /**
+     * Invalidate the class.
+     *
+     * After the call, fetchGraphicBlock() will return C2_BAD_STATE.
+     */
+    virtual void invalidate();
+
 private:
     const std::shared_ptr<C2Allocator> mAllocator;
     const local_id_t mLocalId;
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index f2cd585..5fb0c8f 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -601,6 +601,9 @@
         static int kMaxIgbpRetryDelayUs = 10000;
 
         std::unique_lock<std::mutex> lock(mMutex);
+        if (mInvalidated) {
+            return C2_BAD_STATE;
+        }
         if (mLastDqLogTs == 0) {
             mLastDqLogTs = getTimestampNow();
         } else {
@@ -746,6 +749,11 @@
         *consumeUsage = mConsumerUsage;
     }
 
+    void invalidate() {
+        std::scoped_lock<std::mutex> lock(mMutex);
+        mInvalidated = true;
+    }
+
 private:
     friend struct C2BufferQueueBlockPoolData;
 
@@ -783,6 +791,7 @@
     // if the token has been expired, the buffers will not call IGBP::cancelBuffer()
     // when they are no longer used.
     std::shared_ptr<int> mIgbpValidityToken;
+    bool mInvalidated{false};
 };
 
 C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(
@@ -1103,3 +1112,9 @@
     }
 }
 
+void C2BufferQueueBlockPool::invalidate() {
+    if (mImpl) {
+        mImpl->invalidate();
+    }
+}
+
diff --git a/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp b/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
index d55a3d8..d8c2292 100644
--- a/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
+++ b/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
@@ -114,8 +114,8 @@
 }
 
 namespace {
-    constexpr int kSpinNumForLock = 100;
-    constexpr int kSpinNumForUnlock = 200;
+    constexpr int kSpinNumForLock = 0;
+    constexpr int kSpinNumForUnlock = 0;
 
     enum : uint32_t {
         FUTEX_UNLOCKED = 0,
@@ -125,32 +125,65 @@
 }
 
 int C2SyncVariables::lock() {
-    uint32_t old;
+    uint32_t old = FUTEX_UNLOCKED;
+
+    // see if we can lock uncontended immediately (if previously unlocked)
+    if (mLock.compare_exchange_strong(old, FUTEX_LOCKED_UNCONTENDED)) {
+        return 0;
+    }
+
+    // spin to see if we can get it with a short wait without involving kernel
     for (int i = 0; i < kSpinNumForLock; i++) {
-        old = 0;
+        sched_yield();
+
+        old = FUTEX_UNLOCKED;
         if (mLock.compare_exchange_strong(old, FUTEX_LOCKED_UNCONTENDED)) {
             return 0;
         }
-        sched_yield();
     }
 
-    if (old == FUTEX_LOCKED_UNCONTENDED)
+    // still locked, if other side thinks it was uncontended, now it is contended, so let them
+    // know that they need to wake us up.
+    if (old == FUTEX_LOCKED_UNCONTENDED) {
         old = mLock.exchange(FUTEX_LOCKED_CONTENDED);
+        // It is possible that the other holder released the lock at this very moment (and old
+        // becomes UNLOCKED), If so, we will not involve the kernel to wait for the lock to be
+        // released, but are still marking our lock contended (even though we are the only
+        // holders.)
+    }
 
-    while (old) {
-        (void) syscall(__NR_futex, &mLock, FUTEX_WAIT, FUTEX_LOCKED_CONTENDED, NULL, NULL, 0);
+    // while the futex is still locked by someone else
+    while (old != FUTEX_UNLOCKED) {
+        // wait until other side releases the lock (and still contented)
+        (void)syscall(__NR_futex, &mLock, FUTEX_WAIT, FUTEX_LOCKED_CONTENDED, NULL, NULL, 0);
+        // try to relock
         old = mLock.exchange(FUTEX_LOCKED_CONTENDED);
     }
     return 0;
 }
 
 int C2SyncVariables::unlock() {
-    if (mLock.exchange(FUTEX_UNLOCKED) == FUTEX_LOCKED_UNCONTENDED) return 0;
+    // TRICKY: here we assume that we are holding this lock
 
+    // unlock the lock immediately (since we were holding it)
+    // If it is (still) locked uncontested, we are done (no need to involve the kernel)
+    if (mLock.exchange(FUTEX_UNLOCKED) == FUTEX_LOCKED_UNCONTENDED) {
+        return 0;
+    }
+
+    // We don't need to spin for unlock as here we know already we have a waiter who we need to
+    // wake up. This code was here in case someone just happened to lock this lock (uncontested)
+    // before we would wake up other waiters to avoid a syscall. It is unsure if this ever gets
+    // exercised or if this is the behavior we want. (Note that if this code is removed, the same
+    // situation is still handled in lock() by the woken up waiter that realizes that the lock is
+    // now taken.)
     for (int i = 0; i < kSpinNumForUnlock; i++) {
-        if (mLock.load()) {
+        // here we seem to check if someone relocked this lock, and if they relocked uncontested,
+        // we up it to contested (since there are other waiters.)
+        if (mLock.load() != FUTEX_UNLOCKED) {
             uint32_t old = FUTEX_LOCKED_UNCONTENDED;
             mLock.compare_exchange_strong(old, FUTEX_LOCKED_CONTENDED);
+            // this is always true here so we return immediately
             if (old) {
                 return 0;
             }
@@ -158,7 +191,8 @@
         sched_yield();
     }
 
-    (void) syscall(__NR_futex, &mLock, FUTEX_WAKE, 1, NULL, NULL, 0);
+    // wake up one waiter
+    (void)syscall(__NR_futex, &mLock, FUTEX_WAKE, 1, NULL, NULL, 0);
     return 0;
 }
 
diff --git a/media/img_utils/src/FileInput.cpp b/media/img_utils/src/FileInput.cpp
index 4c85a51..1eb614b 100644
--- a/media/img_utils/src/FileInput.cpp
+++ b/media/img_utils/src/FileInput.cpp
@@ -33,12 +33,12 @@
 
 status_t FileInput::open() {
     if (mOpen) {
-        ALOGW("%s: Open called when file %s already open.", __FUNCTION__, mPath.string());
+        ALOGW("%s: Open called when file %s already open.", __FUNCTION__, mPath.c_str());
         return OK;
     }
     mFp = ::fopen(mPath, "rb");
     if (!mFp) {
-        ALOGE("%s: Could not open file %s", __FUNCTION__, mPath.string());
+        ALOGE("%s: Could not open file %s", __FUNCTION__, mPath.c_str());
         return BAD_VALUE;
     }
     mOpen = true;
@@ -47,14 +47,14 @@
 
 ssize_t FileInput::read(uint8_t* buf, size_t offset, size_t count) {
     if (!mOpen) {
-        ALOGE("%s: Could not read file %s, file not open.", __FUNCTION__, mPath.string());
+        ALOGE("%s: Could not read file %s, file not open.", __FUNCTION__, mPath.c_str());
         return BAD_VALUE;
     }
 
     size_t bytesRead = ::fread(buf + offset, sizeof(uint8_t), count, mFp);
     int error = ::ferror(mFp);
     if (error != 0) {
-        ALOGE("%s: Error %d occurred while reading file %s.", __FUNCTION__, error, mPath.string());
+        ALOGE("%s: Error %d occurred while reading file %s.", __FUNCTION__, error, mPath.c_str());
         return BAD_VALUE;
     }
 
@@ -68,13 +68,13 @@
 
 status_t FileInput::close() {
     if(!mOpen) {
-        ALOGW("%s: Close called when file %s already close.", __FUNCTION__, mPath.string());
+        ALOGW("%s: Close called when file %s already close.", __FUNCTION__, mPath.c_str());
         return OK;
     }
 
     status_t ret = OK;
     if(::fclose(mFp) != 0) {
-        ALOGE("%s: Failed to close file %s.", __FUNCTION__, mPath.string());
+        ALOGE("%s: Failed to close file %s.", __FUNCTION__, mPath.c_str());
         ret = BAD_VALUE;
     }
     mOpen = false;
diff --git a/media/img_utils/src/FileOutput.cpp b/media/img_utils/src/FileOutput.cpp
index 0346762..5e37324 100644
--- a/media/img_utils/src/FileOutput.cpp
+++ b/media/img_utils/src/FileOutput.cpp
@@ -25,19 +25,19 @@
 
 FileOutput::~FileOutput() {
     if (mOpen) {
-        ALOGW("%s: Destructor called with %s still open.", __FUNCTION__, mPath.string());
+        ALOGW("%s: Destructor called with %s still open.", __FUNCTION__, mPath.c_str());
         close();
     }
 }
 
 status_t FileOutput::open() {
     if (mOpen) {
-        ALOGW("%s: Open called when file %s already open.", __FUNCTION__, mPath.string());
+        ALOGW("%s: Open called when file %s already open.", __FUNCTION__, mPath.c_str());
         return OK;
     }
     mFp = ::fopen(mPath, "wb");
     if (!mFp) {
-        ALOGE("%s: Could not open file %s", __FUNCTION__, mPath.string());
+        ALOGE("%s: Could not open file %s", __FUNCTION__, mPath.c_str());
         return BAD_VALUE;
     }
     mOpen = true;
@@ -46,7 +46,7 @@
 
 status_t FileOutput::write(const uint8_t* buf, size_t offset, size_t count) {
     if (!mOpen) {
-        ALOGE("%s: Could not write file %s, file not open.", __FUNCTION__, mPath.string());
+        ALOGE("%s: Could not write file %s, file not open.", __FUNCTION__, mPath.c_str());
         return BAD_VALUE;
     }
 
@@ -54,7 +54,7 @@
 
     int error = ::ferror(mFp);
     if (error != 0) {
-        ALOGE("%s: Error %d occurred while writing file %s.", __FUNCTION__, error, mPath.string());
+        ALOGE("%s: Error %d occurred while writing file %s.", __FUNCTION__, error, mPath.c_str());
         return BAD_VALUE;
     }
     return OK;
@@ -62,13 +62,13 @@
 
 status_t FileOutput::close() {
     if(!mOpen) {
-        ALOGW("%s: Close called when file %s already close.", __FUNCTION__, mPath.string());
+        ALOGW("%s: Close called when file %s already close.", __FUNCTION__, mPath.c_str());
         return OK;
     }
 
     status_t ret = OK;
     if(::fclose(mFp) != 0) {
-        ALOGE("%s: Failed to close file %s.", __FUNCTION__, mPath.string());
+        ALOGE("%s: Failed to close file %s.", __FUNCTION__, mPath.c_str());
         ret = BAD_VALUE;
     }
     mOpen = false;
diff --git a/media/img_utils/src/TiffIfd.cpp b/media/img_utils/src/TiffIfd.cpp
index 3fb00cc..b272814 100644
--- a/media/img_utils/src/TiffIfd.cpp
+++ b/media/img_utils/src/TiffIfd.cpp
@@ -377,7 +377,7 @@
     size_t s = mEntries.size();
     ALOGI("[ifd: %x, num_entries: %zu, entries:\n", getId(), s);
     for(size_t i = 0; i < s; ++i) {
-        ALOGI("\t%s", mEntries[i]->toString().string());
+        ALOGI("\t%s", mEntries[i]->toString().c_str());
     }
     ALOGI(", next_ifd: %x]", ((mNextIfd != NULL) ? mNextIfd->getId() : 0));
 }
diff --git a/media/janitors/avic_OWNERS b/media/janitors/avic_OWNERS
index eca9978..81aac3a 100644
--- a/media/janitors/avic_OWNERS
+++ b/media/janitors/avic_OWNERS
@@ -3,4 +3,3 @@
 arifdikici@google.com
 dichenzhang@google.com
 kyslov@google.com
-richardxie@google.com
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
index e0c87f7..17bc7dd 100644
--- a/media/janitors/media_solutions_OWNERS
+++ b/media/janitors/media_solutions_OWNERS
@@ -15,6 +15,7 @@
 bachinger@google.com
 christosts@google.com
 ibaker@google.com
+jbibik@google.com
 michaelkatz@google.com
 rohks@google.com
 tianyifeng@google.com
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f07ea1d..073a030 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -760,7 +760,7 @@
                         mInput, mLatency, mSelectedDeviceId, mRoutedDeviceId);
     result.appendFormat("  mic direction(%d) mic field dimension(%f)",
                         mSelectedMicDirection, mSelectedMicFieldDimension);
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 7cec2e8..6616197 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -87,7 +87,7 @@
 void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) {
     if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) {
         ALOGE("setAudioFlingerBinder: received a binder of type %s",
-              String8(audioFlinger->getInterfaceDescriptor()).string());
+              String8(audioFlinger->getInterfaceDescriptor()).c_str());
         return;
     }
     Mutex::Autolock _l(gLock);
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 359c140..f3539a1 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -3035,7 +3035,7 @@
     param.addInt(String8(AudioParameter::keyPresentationId), presentationId);
     param.addInt(String8(AudioParameter::keyProgramId), programId);
     ALOGV("%s(%d): PresentationId/ProgramId[%s]",
-            __func__, mPortId, param.toString().string());
+            __func__, mPortId, param.toString().c_str());
 
     status_t status;
     mAudioTrack->setParameters(param.toString().c_str(), &status);
@@ -3478,7 +3478,7 @@
     if (output != AUDIO_IO_HANDLE_NONE) {
         return AudioSystem::getParameters(output, keys);
     } else {
-        return String8::empty();
+        return String8();
     }
 }
 
@@ -3524,7 +3524,7 @@
                         mLatency, mSelectedDeviceId, mRoutedDeviceId);
     result.appendFormat("  output(%d) AF latency (%u) AF frame count(%zu) AF SampleRate(%u)\n",
                         mOutput, mAfLatency, mAfFrameCount, mAfSampleRate);
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 976a532..9a46b20 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -143,7 +143,8 @@
 }
 
 AudioDeviceDescription make_ADD_RSubmixIn() {
-    return make_AudioDeviceDescription(AudioDeviceType::IN_SUBMIX);
+    return make_AudioDeviceDescription(AudioDeviceType::IN_SUBMIX,
+                                       AudioDeviceDescription::CONNECTION_VIRTUAL());
 }
 
 AudioDeviceDescription make_ADD_DefaultOut() {
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 2bb6afc..af70c39 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -125,6 +125,15 @@
     dst->append(base::StringPrintf(
                     "%*sEncapsulation modes: %u, metadata types: %u\n", spaces, "",
                     mEncapsulationModes, mEncapsulationMetadataTypes));
+    if (!mEncodedFormats.empty()) {
+        std::string s;
+        for (const auto& format : mEncodedFormats) {
+            if (!s.empty()) s.append(", ");
+            s.append(audio_format_to_string(format));
+        }
+        dst->append(base::StringPrintf(
+                        "%*sEncoded formats: %s\n", spaces, "", s.c_str()));
+    }
 
     std::string portStr;
     AudioPort::dump(&portStr, spaces, nullptr, verbose);
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.cpp b/media/libaudiohal/impl/ConversionHelperAidl.cpp
index 7197bf2..46abfda 100644
--- a/media/libaudiohal/impl/ConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperAidl.cpp
@@ -69,7 +69,7 @@
         // Re-parse the vendor-provided string to ensure that it is correct.
         AudioParameter reparse(String8(vendorParameters.c_str()));
         if (reparse.size() != 0) {
-            if (!values->empty()) {
+            if (values->length() > 0) {
                 values->append(";");
             }
             values->append(reparse.toString().c_str());
diff --git a/media/libaudiohal/impl/CoreConversionHelperHidl.cpp b/media/libaudiohal/impl/CoreConversionHelperHidl.cpp
index 2ac8a42..b801187 100644
--- a/media/libaudiohal/impl/CoreConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/CoreConversionHelperHidl.cpp
@@ -69,7 +69,7 @@
             keepValueParam.add(key, value);
             key = keepValueParam.toString();
         }
-        (*hidlKeys)[i] = key.string();
+        (*hidlKeys)[i] = key.c_str();
     }
     return OK;
 }
@@ -84,8 +84,8 @@
         String8 key, value;
         status_t status = params.getAt(i, key, value);
         if (status != OK) return status;
-        (*hidlParams)[i].key = key.string();
-        (*hidlParams)[i].value = value.string();
+        (*hidlParams)[i].key = key.c_str();
+        (*hidlParams)[i].value = value.c_str();
     }
     return OK;
 }
@@ -97,7 +97,7 @@
     for (size_t i = 0; i < parameters.size(); ++i) {
         params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
     }
-    values->setTo(params.toString());
+    *values = params.toString();
 }
 
 CoreConversionHelperHidl::CoreConversionHelperHidl(std::string_view className)
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index ae15190..c911ac8 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -293,6 +293,9 @@
     if (status_t status = filterAndUpdateScreenParameters(parameters); status != OK) {
         ALOGW("%s: filtering or updating screen parameters failed: %d", __func__, status);
     }
+    if (status_t status = filterAndUpdateTelephonyParameters(parameters); status != OK) {
+        ALOGW("%s: filtering or updating telephony parameters failed: %d", __func__, status);
+    }
     return parseAndSetVendorParameters(mVendorExt, mModule, parameters);
 }
 
@@ -1370,6 +1373,52 @@
     return OK;
 }
 
+status_t DeviceHalAidl::filterAndUpdateTelephonyParameters(AudioParameter &parameters) {
+    TIME_CHECK();
+    using TtyMode = ITelephony::TelecomConfig::TtyMode;
+    ITelephony::TelecomConfig telConfig;
+    (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
+                    parameters, String8(AudioParameter::keyTtyMode),
+                    [&telConfig](const String8& mode) {
+                        if (mode == AudioParameter::valueTtyModeOff) {
+                            telConfig.ttyMode = TtyMode::OFF;
+                            return OK;
+                        } else if (mode == AudioParameter::valueTtyModeFull) {
+                            telConfig.ttyMode = TtyMode::FULL;
+                            return OK;
+                        } else if (mode == AudioParameter::valueTtyModeHco) {
+                            telConfig.ttyMode = TtyMode::HCO;
+                            return OK;
+                        } else if (mode == AudioParameter::valueTtyModeVco) {
+                            telConfig.ttyMode = TtyMode::VCO;
+                            return OK;
+                        }
+                        ALOGE("setParameters: parameter key \"%s\" has invalid value \"%s\"",
+                                AudioParameter::keyTtyMode, mode.c_str());
+                        return BAD_VALUE;
+                    }));
+    (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
+                    parameters, String8(AudioParameter::keyHacSetting),
+                    [&telConfig](const String8& onOrOff) {
+                        if (onOrOff == AudioParameter::valueHacOn) {
+                            telConfig.isHacEnabled = Boolean{ .value = true };
+                            return OK;
+                        } else if (onOrOff == AudioParameter::valueHacOff) {
+                            telConfig.isHacEnabled = Boolean{ .value = false };
+                            return OK;
+                        }
+                        ALOGE("setParameters: parameter key \"%s\" has invalid value \"%s\"",
+                                AudioParameter::keyHacSetting, onOrOff.c_str());
+                        return BAD_VALUE;
+                    }));
+    if (mTelephony != nullptr && telConfig != ITelephony::TelecomConfig{}) {
+        ITelephony::TelecomConfig newTelConfig;
+        return statusTFromBinderStatus(
+                mTelephony->setTelecomConfig(telConfig, &newTelConfig));
+    }
+    return OK;
+}
+
 status_t DeviceHalAidl::findOrCreatePatch(
         const AudioPatch& requestedPatch, AudioPatch* patch, bool* created) {
     std::set<int32_t> sourcePortConfigIds(requestedPatch.sourcePortConfigIds.begin(),
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 74a8b51..8f27369 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -224,6 +224,7 @@
     status_t filterAndUpdateBtLeParameters(AudioParameter &parameters);
     status_t filterAndUpdateBtScoParameters(AudioParameter &parameters);
     status_t filterAndUpdateScreenParameters(AudioParameter &parameters);
+    status_t filterAndUpdateTelephonyParameters(AudioParameter &parameters);
     status_t findOrCreatePatch(
         const std::set<int32_t>& sourcePortConfigIds,
         const std::set<int32_t>& sinkPortConfigIds,
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index f00b1a0..a8f9f7e 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -14,7 +14,10 @@
  * limitations under the License.
  */
 
+#include <algorithm>
+#include <map>
 #include <memory>
+#include <string>
 
 #define LOG_TAG "DevicesFactoryHalAidl"
 //#define LOG_NDEBUG 0
@@ -75,6 +78,21 @@
                 if (strcmp(instance, "default") == 0) instance = "primary";
                 static_cast<decltype(names)>(context)->push_back(instance);
             });
+    std::sort(names->begin(), names->end(), [](const std::string& lhs,
+                    const std::string& rhs) {
+        // This order corresponds to the canonical order of modules as specified in
+        // the reference 'audio_policy_configuration_7_0.xml' file.
+        static const std::map<std::string, int> kPriorities{
+            { "primary", 0 }, { "a2dp", 1 }, { "usb", 2 }, { "r_submix", 3 },
+            { "bluetooth", 4 }, { "hearing_aid", 5 }, { "msd", 6 }, { "stub", 7 }
+        };
+        auto lhsIt = kPriorities.find(lhs);
+        auto rhsIt = kPriorities.find(rhs);
+        if (lhsIt != kPriorities.end() && rhsIt != kPriorities.end()) {
+            return lhsIt->second < rhsIt->second;
+        }
+        return lhsIt != kPriorities.end();
+    });
     return OK;
 }
 
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 8a582a5..4e34fca 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -25,6 +25,7 @@
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionNdk.h>
 #include <media/AidlConversionEffect.h>
+#include <media/AudioContainers.h>
 #include <system/audio_effects/effect_visualizer.h>
 
 #include <utils/Log.h>
@@ -61,6 +62,7 @@
                 {EFFECT_CMD_RESET, &EffectConversionHelperAidl::handleReset},
                 {EFFECT_CMD_ENABLE, &EffectConversionHelperAidl::handleEnable},
                 {EFFECT_CMD_DISABLE, &EffectConversionHelperAidl::handleDisable},
+                {EFFECT_CMD_SET_AUDIO_MODE, &EffectConversionHelperAidl::handleSetAudioMode},
                 {EFFECT_CMD_SET_AUDIO_SOURCE, &EffectConversionHelperAidl::handleSetAudioSource},
                 {EFFECT_CMD_SET_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
                 {EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
@@ -208,12 +210,12 @@
             mEffect->close();
             return status;
         }
-        mCommon = common;
     } else if (mCommon != common) {
         ALOGI("%s at state %s, setParameter", __func__, android::internal::ToString(state).c_str());
-        Parameter aidlParam = UNION_MAKE(Parameter, common, mCommon);
+        Parameter aidlParam = UNION_MAKE(Parameter, common, common);
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
     }
+    mCommon = common;
 
     return *static_cast<int32_t*>(pReplyData) = OK;
 }
@@ -279,6 +281,10 @@
               pReplyData);
         return BAD_VALUE;
     }
+    if (!getDescriptor().common.flags.audioSourceIndication) {
+        ALOGW("%s parameter no audioSourceIndication, skipping", __func__);
+        return OK;
+    }
 
     audio_source_t source = *(audio_source_t*)pCmdData;
     AudioSource aidlSource =
@@ -295,6 +301,10 @@
               pReplyData);
         return BAD_VALUE;
     }
+    if (!getDescriptor().common.flags.audioModeIndication) {
+        ALOGW("%s parameter no audioModeIndication, skipping", __func__);
+        return OK;
+    }
     audio_mode_t mode = *(audio_mode_t *)pCmdData;
     AudioMode aidlMode =
             VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
@@ -310,9 +320,26 @@
               pReplyData);
         return BAD_VALUE;
     }
-    // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
-    // const auto& legacyDevice = *(uint32_t*)(pCmdData);
+    if (!getDescriptor().common.flags.deviceIndication) {
+        ALOGW("%s parameter no deviceIndication, skipping", __func__);
+        return OK;
+    }
+    // convert from bitmask of audio_devices_t to std::vector<AudioDeviceDescription>
+    auto legacyDevices = *(uint32_t*)(pCmdData);
+    // extract the input bit and remove it from bitmasks
+    const auto inputBit = legacyDevices & AUDIO_DEVICE_BIT_IN;
+    legacyDevices &= ~AUDIO_DEVICE_BIT_IN;
     std::vector<AudioDeviceDescription> aidlDevices;
+    while (legacyDevices) {
+        // get audio_devices_t represented by the last true bit and convert to AIDL
+        const auto lowestBitDevice = legacyDevices & -legacyDevices;
+        AudioDeviceDescription deviceDesc = VALUE_OR_RETURN_STATUS(
+                ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(
+                        static_cast<audio_devices_t>(lowestBitDevice | inputBit)));
+        aidlDevices.emplace_back(deviceDesc);
+        legacyDevices -= lowestBitDevice;
+    }
+
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
             mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
     return *static_cast<int32_t*>(pReplyData) = OK;
@@ -351,9 +378,14 @@
     if (mIsProxyEffect) {
         ALOGI("%s offload param offload %s ioHandle %d", __func__,
               offload->isOffload ? "true" : "false", offload->ioHandle);
-        mCommon.ioHandle = offload->ioHandle;
         const auto& effectProxy = std::static_pointer_cast<EffectProxy>(mEffect);
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(effectProxy->setOffloadParam(offload)));
+        if (mCommon.ioHandle != offload->ioHandle) {
+            ALOGI("%s ioHandle update [%d to %d]", __func__, mCommon.ioHandle, offload->ioHandle);
+            mCommon.ioHandle = offload->ioHandle;
+            Parameter aidlParam = UNION_MAKE(Parameter, common, mCommon);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
+        }
         // update FMQs if the effect instance already open
         if (State state; effectProxy->getState(&state).isOk() && state != State::INIT) {
             mStatusQ = effectProxy->getStatusMQ();
@@ -430,5 +462,19 @@
             (mIsProxyEffect && std::static_pointer_cast<EffectProxy>(mEffect)->isBypassing()));
 }
 
+Descriptor EffectConversionHelperAidl::getDescriptor() const {
+    if (!mIsProxyEffect) {
+        return mDesc;
+    }
+
+    Descriptor desc;
+    if (const auto status = mEffect->getDescriptor(&desc); !status.isOk()) {
+        ALOGE("%s failed to get proxy descriptor (%d:%s), using default", __func__,
+              status.getStatus(), status.getMessage());
+        return mDesc;
+    }
+    return desc;
+}
+
 }  // namespace effect
 }  // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 7c8f11b..85e877e 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -43,6 +43,8 @@
     std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; }
     bool isBypassing() const;
 
+    ::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const;
+
   protected:
     const int32_t mSessionId;
     const int32_t mIoId;
@@ -134,7 +136,6 @@
     virtual status_t visualizerMeasure(uint32_t* replySize __unused, void* pReplyData __unused) {
         return BAD_VALUE;
     }
-
 };
 
 }  // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index ae4a530..642d352 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -56,6 +56,7 @@
 using ::aidl::android::hardware::audio::effect::Descriptor;
 using ::aidl::android::hardware::audio::effect::IEffect;
 using ::aidl::android::hardware::audio::effect::IFactory;
+using ::aidl::android::hardware::audio::effect::State;
 
 namespace android {
 namespace effect {
@@ -68,7 +69,6 @@
       mEffect(effect),
       mSessionId(sessionId),
       mIoId(ioId),
-      mDesc(desc),
       mIsProxyEffect(isProxyEffect) {
     createAidlConversion(effect, sessionId, ioId, desc);
 }
@@ -165,13 +165,21 @@
 
 // write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
 status_t EffectHalAidl::process() {
+    State state = State::INIT;
+    if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
+        state != State::PROCESSING) {
+        ALOGI("%s skipping %s process because it's %s", __func__,
+              mConversion->getDescriptor().common.name.c_str(),
+              mConversion->isBypassing()
+                      ? "bypassing"
+                      : aidl::android::hardware::audio::effect::toString(state).c_str());
+        return OK;
+    }
+
     auto statusQ = mConversion->getStatusMQ();
     auto inputQ = mConversion->getInputMQ();
     auto outputQ = mConversion->getOutputMQ();
     auto efGroup = mConversion->getEventFlagGroup();
-    if (mConversion->isBypassing()) {
-        return OK;
-    }
     if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
         !outputQ->isValid() || !efGroup) {
         ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
@@ -217,8 +225,8 @@
         return INVALID_OPERATION;
     }
 
-    ALOGD("%s %s consumed %zu produced %zu", __func__, mDesc.common.name.c_str(), floatsToWrite,
-          floatsToRead);
+    ALOGD("%s %s consumed %zu produced %zu", __func__,
+          mConversion->getDescriptor().common.name.c_str(), floatsToWrite, floatsToRead);
     return OK;
 }
 
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 1b7a3d6..bbcb7e2 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -72,7 +72,6 @@
     const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
     const int32_t mSessionId;
     const int32_t mIoId;
-    const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
     const bool mIsProxyEffect;
 
     std::unique_ptr<EffectConversionHelperAidl> mConversion;
diff --git a/media/libaudiohal/impl/EffectProxy.cpp b/media/libaudiohal/impl/EffectProxy.cpp
index fac03b7..7b5e195 100644
--- a/media/libaudiohal/impl/EffectProxy.cpp
+++ b/media/libaudiohal/impl/EffectProxy.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <algorithm>
+#include <cstddef>
 #include <iterator>
 #include <memory>
 #define LOG_TAG "EffectProxy"
@@ -92,11 +93,13 @@
     }
 
     mActiveSubIdx = std::distance(mSubEffects.begin(), itor);
-    ALOGV("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
+    ALOGI("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
           offload->isOffload ? "" : "non-", mActiveSubIdx,
           ::android::audio::utils::toString(mSubEffects[mActiveSubIdx].descriptor.common.id.uuid)
                   .c_str());
-    return ndk::ScopedAStatus::ok();
+    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
+        return effect->setParameter(Parameter::make<Parameter::offload>(offload->isOffload));
+    });
 }
 
 // EffectProxy go over sub-effects and call IEffect interfaces
@@ -134,8 +137,8 @@
 }
 
 ndk::ScopedAStatus EffectProxy::getDescriptor(Descriptor* desc) {
-    desc->common = mDescriptorCommon;
-    desc->capability = mSubEffects[mActiveSubIdx].descriptor.capability;
+    *desc = mSubEffects[mActiveSubIdx].descriptor;
+    desc->common.id.uuid = desc->common.id.proxy.value();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -229,7 +232,10 @@
     }
 
     // proceed with others
-    for (size_t i = 0; i < mSubEffects.size() && i != mActiveSubIdx; i++) {
+    for (size_t i = 0; i < mSubEffects.size(); i++) {
+        if (i == mActiveSubIdx) {
+            continue;
+        }
         if (!mSubEffects[i].handle) {
             ALOGE("%s null sub-effect interface for %s", __func__,
                   mSubEffects[i].descriptor.common.id.uuid.toString().c_str());
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 57395fa..87aaeac 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -287,7 +287,7 @@
         if (const auto uuid =
                     ::aidl::android::aidl2legacy_AudioUuid_audio_uuid_t(desc.common.id.uuid);
             uuid.ok()) {
-            static_cast<effectsConfig::EffectImpl>(effect).uuid = uuid.value();
+            static_cast<effectsConfig::EffectImpl&>(effect).uuid = uuid.value();
             return std::make_shared<const effectsConfig::Effect>(effect);
         } else {
             return nullptr;
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 80e19a0..f9aea37 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -267,7 +267,11 @@
     if (status_t status = updateCountersIfNeeded(&reply); status != OK) {
         return status;
     }
-    *latency = std::max<int32_t>(0, reply.latencyMs);
+
+    *latency = std::clamp(std::max<int32_t>(0, reply.latencyMs), 1, 3000);
+    ALOGW_IF(reply.latencyMs != static_cast<int32_t>(*latency),
+             "Suspicious latency value reported by HAL: %d, clamped to %u", reply.latencyMs,
+             *latency);
     return OK;
 }
 
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
index 92b77d8..f5640b8 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
@@ -67,7 +67,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, vendor,
                                                 ext);
             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
index 1363ba4..03606f4 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
@@ -90,7 +90,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1,
                                                           automaticGainControlV1, vendor, ext);
             return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
index b35a1c6..b9a5b02 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
@@ -68,7 +68,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV2, automaticGainControlV2,
                                                 vendor, ext);
             break;
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
index 7c6a5a2..8df56b0 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
@@ -66,7 +66,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
index b57971c..2b98e21 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
@@ -60,7 +60,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(Downmix, downmix, vendor, ext);
         }
     }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
index fe845ab..89f8b83 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
@@ -119,7 +119,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam =
                     MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, vendor, ext);
             break;
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
index 754da43..fcade68 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
@@ -168,7 +168,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(EnvironmentalReverb,
                                                           environmentalReverb, vendor, ext);
             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
index fc867c7..ca6ff88 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
@@ -103,7 +103,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
index 73430ba..bdee7b6 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
@@ -79,7 +79,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(HapticGenerator, hapticGenerator, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
index 31eec65..a0526e6 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
@@ -58,7 +58,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(LoudnessEnhancer, loudnessEnhancer, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
index 7c34ed7..bf75e4a 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
@@ -63,7 +63,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(NoiseSuppression, noiseSuppression, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
index e936aef..3cac591 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
@@ -61,7 +61,7 @@
     } else {
         // for vendor extension, copy data area to the DefaultExtension, parameter ignored
         VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
         aidlParam = MAKE_SPECIFIC_PARAMETER(PresetReverb, presetReverb, vendor, ext);
     }
 
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
index eadd6c3..ff0c32b 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
@@ -44,7 +44,7 @@
 
 status_t AidlConversionSpatializer::setParameter(EffectParamReader& param) {
     Parameter aidlParam = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::legacy2aidl_EffectParameterReader_ParameterExtension(param));
+            ::aidl::android::legacy2aidl_EffectParameterReader_Parameter(param));
     return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
 }
 
@@ -64,8 +64,7 @@
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
     // copy the AIDL extension data back to effect_param_t
     return VALUE_OR_RETURN_STATUS(
-            ::aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(aidlParam,
-                                                                                  param));
+            ::aidl::android::aidl2legacy_Parameter_EffectParameterWriter(aidlParam, param));
 }
 
 } // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
index 488d5cd..2c29c7d 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
@@ -52,20 +52,19 @@
  */
 status_t AidlConversionVendorExtension::setParameter(EffectParamReader& param) {
     Parameter aidlParam = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::legacy2aidl_EffectParameterReader_ParameterExtension(param));
+            ::aidl::android::legacy2aidl_EffectParameterReader_Parameter(param));
     return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
 }
 
 status_t AidlConversionVendorExtension::getParameter(EffectParamWriter& param) {
     VendorExtension extId = VALUE_OR_RETURN_STATUS(
-            aidl::android::legacy2aidl_EffectParameterReader_Param_VendorExtension(param));
+            aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
     Parameter::Id id = UNION_MAKE(Parameter::Id, vendorEffectTag, extId);
     Parameter aidlParam;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
     // copy the AIDL extension data back to effect_param_t
     return VALUE_OR_RETURN_STATUS(
-            ::aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(aidlParam,
-                                                                                  param));
+            ::aidl::android::aidl2legacy_Parameter_EffectParameterWriter(aidlParam, param));
 }
 
 } // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
index c95c3a9..cad0068 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
@@ -77,7 +77,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
index b4440ee..18d0d95 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
@@ -75,7 +75,7 @@
         default: {
             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
             VendorExtension ext = VALUE_OR_RETURN_STATUS(
-                    aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+                    aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
             aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, vendor, ext);
             break;
         }
diff --git a/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
index ea20794..adff110 100644
--- a/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
+++ b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
@@ -452,7 +452,7 @@
     String8 values;
     EXPECT_EQ(OK, mDevice->getParameters(String8("random_name"), &values));
     EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
-    EXPECT_TRUE(values.empty());
+    EXPECT_EQ(0UL, values.length());
 }
 
 class DeviceHalAidlVendorParametersTest : public testing::Test {
diff --git a/media/libaudiohal/tests/EffectProxy_test.cpp b/media/libaudiohal/tests/EffectProxy_test.cpp
index 8668e85..2953b0a 100644
--- a/media/libaudiohal/tests/EffectProxy_test.cpp
+++ b/media/libaudiohal/tests/EffectProxy_test.cpp
@@ -53,7 +53,9 @@
     void SetUp() override {
         auto serviceName = android::getAidlHalInstanceNames(IFactory::descriptor);
         // only unit test with the first one in case more than one EffectFactory service exist
-        ASSERT_NE(0ul, serviceName.size());
+        if (0ul == serviceName.size()) {
+            GTEST_SKIP() << "EffectFactory not available on device, skipping";
+        }
         mFactory = IFactory::fromBinder(
                 ndk::SpAIBinder(AServiceManager_waitForService(serviceName[0].c_str())));
         ASSERT_NE(nullptr, mFactory);
@@ -157,6 +159,7 @@
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
         offloadParam.isOffload = true;
+        offloadParam.ioHandle++;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
         EXPECT_TRUE(proxy->close().isOk());
         EXPECT_TRUE(proxy->destroy().isOk());
@@ -189,21 +192,21 @@
     Parameter::Common common = createParamCommon();
     IEffect::OpenEffectReturn ret;
     Parameter::VolumeStereo volumeStereo({.left = .1f, .right = -0.8f});
-    Parameter param = Parameter::make<Parameter::volumeStereo>(volumeStereo);
-    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter expect = Parameter::make<Parameter::volumeStereo>(volumeStereo);
+    const Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
     State state;
     for (const auto& itor : proxyMap) {
-        Parameter expect;
+        Parameter getParam = Parameter::make<Parameter::offload>(true);
         auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
         effect_offload_param_t offloadParam{true, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
 
         EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
 
-        EXPECT_TRUE(proxy->setParameter(param).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param) << " EXPECTED: " << expect.toString()
-                                 << "\nACTUAL: " << param.toString();
+        EXPECT_TRUE(proxy->setParameter(expect).isOk());
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam)
+                << " EXPECTED: " << expect.toString() << "\nACTUAL: " << getParam.toString();
 
         EXPECT_TRUE(proxy->command(CommandId::START).isOk());
         EXPECT_TRUE(proxy->getState(&state).isOk());
@@ -225,25 +228,25 @@
     Parameter::Common common = createParamCommon();
     IEffect::OpenEffectReturn ret;
     Parameter::VolumeStereo volumeStereo({.left = .5f, .right = .8f});
-    Parameter param = Parameter::make<Parameter::volumeStereo>(volumeStereo);
-    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter expect = Parameter::make<Parameter::volumeStereo>(volumeStereo);
+    const Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
     for (const auto& itor : proxyMap) {
-        Parameter expect;
+        Parameter getParam = Parameter::make<Parameter::offload>(true);
         auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
         EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
-        EXPECT_TRUE(proxy->setParameter(param).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->setParameter(expect).isOk());
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         offloadParam.isOffload = true;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         EXPECT_TRUE(proxy->close().isOk());
         EXPECT_TRUE(proxy->destroy().isOk());
@@ -271,13 +274,9 @@
 
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getState(&state).isOk());
-        EXPECT_EQ(State::PROCESSING, state);
 
         offloadParam.isOffload = true;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getState(&state).isOk());
-        EXPECT_EQ(State::PROCESSING, state);
 
         EXPECT_TRUE(proxy->command(CommandId::STOP).isOk());
         EXPECT_TRUE(proxy->getState(&state).isOk());
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index 63f895f..0cb654c 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -16,6 +16,7 @@
 
 //#define LOG_NDEBUG 0
 #include <algorithm>
+#include <array>
 #include <cstddef>
 #include <cstdint>
 #include <cstring>
@@ -24,8 +25,11 @@
 #define LOG_TAG "EffectsFactoryHalInterfaceTest"
 
 #include <aidl/android/media/audio/common/AudioUuid.h>
+#include <gtest/gtest.h>
 #include <media/AidlConversionCppNdk.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/audio_aidl_utils.h>
+#include <system/audio_effect.h>
 #include <system/audio_effects/audio_effects_utils.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio_effects/effect_agc.h>
@@ -36,17 +40,15 @@
 #include <system/audio_effects/effect_hapticgenerator.h>
 #include <system/audio_effects/effect_loudnessenhancer.h>
 #include <system/audio_effects/effect_ns.h>
-#include <system/audio_effect.h>
-
-#include <gtest/gtest.h>
 #include <utils/RefBase.h>
 #include <vibrator/ExternalVibrationUtils.h>
 
 namespace android {
 
+using ::aidl::android::media::audio::common::AudioUuid;
+using ::android::audio::utils::toString;
 using effect::utils::EffectParamReader;
 using effect::utils::EffectParamWriter;
-using ::aidl::android::media::audio::common::AudioUuid;
 
 // EffectsFactoryHalInterface
 TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
@@ -195,7 +197,8 @@
 
 static const effect_uuid_t EXTEND_EFFECT_TYPE_UUID = {
         0xfa81dbde, 0x588b, 0x11ed, 0x9b6a, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-
+constexpr std::array<uint8_t, 10> kVendorExtensionData({0xff, 0x5, 0x50, 0xab, 0xcd, 0x00, 0xbd,
+                                                        0xdb, 0xee, 0xff});
 std::vector<EffectParamTestTuple> testPairs = {
         std::make_tuple(FX_IID_AEC,
                         createEffectParamCombination(AEC_PARAM_ECHO_DELAY, 0xff /* echoDelayMs */,
@@ -203,12 +206,9 @@
         std::make_tuple(FX_IID_AGC,
                         createEffectParamCombination(AGC_PARAM_TARGET_LEVEL, 20 /* targetLevel */,
                                                      sizeof(int16_t) /* returnValueSize */)),
-        std::make_tuple(FX_IID_AGC2, createEffectParamCombination(
-                                             AGC2_PARAM_FIXED_DIGITAL_GAIN, 15 /* digitalGainDb */,
-                                             sizeof(int32_t) /* returnValueSize */)),
         std::make_tuple(SL_IID_BASSBOOST,
                         createEffectParamCombination(BASSBOOST_PARAM_STRENGTH, 20 /* strength */,
-                                                     sizeof(int32_t) /* returnValueSize */)),
+                                                     sizeof(int16_t) /* returnValueSize */)),
         std::make_tuple(EFFECT_UIID_DOWNMIX,
                         createEffectParamCombination(DOWNMIX_PARAM_TYPE, DOWNMIX_TYPE_FOLD,
                                                      sizeof(int16_t) /* returnValueSize */)),
@@ -217,13 +217,6 @@
                                 std::array<uint32_t, 2>({DP_PARAM_INPUT_GAIN, 0 /* channel */}),
                                 30 /* gainDb */, sizeof(int32_t) /* returnValueSize */)),
         std::make_tuple(
-                FX_IID_HAPTICGENERATOR,
-                createEffectParamCombination(
-                        HG_PARAM_HAPTIC_INTENSITY,
-                        std::array<uint32_t, 2>(
-                                {1, uint32_t(::android::os::HapticScale::HIGH) /* scale */}),
-                        0 /* returnValueSize */)),
-        std::make_tuple(
                 FX_IID_LOUDNESS_ENHANCER,
                 createEffectParamCombination(LOUDNESS_ENHANCER_PARAM_TARGET_GAIN_MB, 5 /* gain */,
                                              sizeof(int32_t) /* returnValueSize */)),
@@ -231,7 +224,8 @@
                         createEffectParamCombination(NS_PARAM_LEVEL, 1 /* level */,
                                                      sizeof(int32_t) /* returnValueSize */)),
         std::make_tuple(&EXTEND_EFFECT_TYPE_UUID,
-                        createEffectParamCombination(1, 0xbead, sizeof(int32_t)))};
+                        createEffectParamCombination(8, kVendorExtensionData,
+                                                     sizeof(kVendorExtensionData)))};
 
 class libAudioHalEffectParamTest : public ::testing::TestWithParam<EffectParamTestTuple> {
   public:
@@ -255,7 +249,9 @@
           }()) {}
 
     void SetUp() override {
-        ASSERT_NE(0ul, mDescs.size());
+        if (0ul == mDescs.size()) {
+            GTEST_SKIP() << "Effect type not available on device, skipping";
+        }
         for (const auto& desc : mDescs) {
             sp<EffectHalInterface> interface = createEffectHal(desc);
             ASSERT_NE(nullptr, interface);
@@ -264,9 +260,11 @@
     }
 
     void initEffect(const sp<EffectHalInterface>& interface) {
-        uint32_t initReply = 0;
-        uint32_t initReplySize = sizeof(initReply);
-        ASSERT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &initReplySize, &initReply));
+        uint32_t reply = 0;
+        uint32_t replySize = sizeof(reply);
+        ASSERT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &replySize, &reply));
+        ASSERT_EQ(OK, interface->command(EFFECT_CMD_SET_CONFIG, sizeof(mEffectConfig),
+                                         &mEffectConfig, &replySize, &reply));
     }
 
     void TearDown() override {
@@ -311,7 +309,7 @@
             std::vector<uint8_t> response(mCombination->valueSize);
             EXPECT_EQ(OK, parameterGet.readFromValue(response.data(), mCombination->valueSize))
                     << " try get valueSize " << mCombination->valueSize << " from "
-                    << parameterGet.toString();
+                    << parameterGet.toString() << " set " << parameterSet->toString();
             EXPECT_EQ(response, mExpectedValue);
         }
     }
@@ -323,6 +321,23 @@
     const std::vector<uint8_t> mExpectedValue;
     const std::vector<effect_descriptor_t> mDescs;
     std::vector<sp<EffectHalInterface>> mHalInterfaces;
+    effect_config_t mEffectConfig = {.inputCfg = {.accessMode = EFFECT_BUFFER_ACCESS_READ,
+                                                  .format = AUDIO_FORMAT_PCM_FLOAT,
+                                                  .bufferProvider.getBuffer = nullptr,
+                                                  .bufferProvider.releaseBuffer = nullptr,
+                                                  .bufferProvider.cookie = nullptr,
+                                                  .mask = EFFECT_CONFIG_ALL,
+                                                  .samplingRate = 48000,
+                                                  .channels = AUDIO_CHANNEL_IN_STEREO},
+
+                                     .outputCfg = {.accessMode = EFFECT_BUFFER_ACCESS_WRITE,
+                                                   .format = AUDIO_FORMAT_PCM_FLOAT,
+                                                   .bufferProvider.getBuffer = nullptr,
+                                                   .bufferProvider.releaseBuffer = nullptr,
+                                                   .bufferProvider.cookie = nullptr,
+                                                   .mask = EFFECT_CONFIG_ALL,
+                                                   .samplingRate = 48000,
+                                                   .channels = AUDIO_CHANNEL_OUT_STEREO}};
 };
 
 TEST_P(libAudioHalEffectParamTest, setAndGetParam) {
@@ -332,13 +347,52 @@
     }
 }
 
+TEST_P(libAudioHalEffectParamTest, deviceIndicationUpdate) {
+    for (auto& interface : mHalInterfaces) {
+        EXPECT_NO_FATAL_FAILURE(initEffect(interface));
+
+        // output device
+        uint32_t deviceTypes = AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_BLE_SPEAKER;
+        status_t cmdStatus;
+        uint32_t replySize = sizeof(cmdStatus);
+        EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_DEVICE, sizeof(uint32_t), &deviceTypes,
+                                         &replySize, &cmdStatus));
+        // input device
+        deviceTypes = AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+        EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_DEVICE, sizeof(uint32_t), &deviceTypes,
+                                         &replySize, &cmdStatus));
+    }
+}
+
+TEST_P(libAudioHalEffectParamTest, audioModeIndicationUpdate) {
+    for (auto& interface : mHalInterfaces) {
+        EXPECT_NO_FATAL_FAILURE(initEffect(interface));
+        uint32_t mode = AUDIO_MODE_IN_CALL;
+        status_t cmdStatus;
+        uint32_t replySize = sizeof(cmdStatus);
+        EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_AUDIO_MODE, sizeof(uint32_t), &mode,
+                                         &replySize, &cmdStatus));
+    }
+}
+
+TEST_P(libAudioHalEffectParamTest, audioSourceIndicationUpdate) {
+    for (auto& interface : mHalInterfaces) {
+        EXPECT_NO_FATAL_FAILURE(initEffect(interface));
+        uint32_t source = AUDIO_SOURCE_MIC;
+        status_t cmdStatus;
+        uint32_t replySize = sizeof(cmdStatus);
+        EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_AUDIO_SOURCE, sizeof(uint32_t), &source,
+                                         &replySize, &cmdStatus));
+    }
+}
+
 INSTANTIATE_TEST_SUITE_P(
         libAudioHalEffectParamTest, libAudioHalEffectParamTest, ::testing::ValuesIn(testPairs),
         [](const testing::TestParamInfo<libAudioHalEffectParamTest::ParamType>& info) {
             AudioUuid uuid = ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(
                                      *std::get<TUPLE_UUID>(info.param))
                                      .value();
-            std::string name = "UUID_" + uuid.toString();
+            std::string name = "UUID_" + toString(uuid);
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/media/libdatasource/DataSourceFactory.cpp b/media/libdatasource/DataSourceFactory.cpp
index f91e3ea..81a6cd0 100644
--- a/media/libdatasource/DataSourceFactory.cpp
+++ b/media/libdatasource/DataSourceFactory.cpp
@@ -92,7 +92,7 @@
 
         source = NuCachedSource2::Create(
                 mediaHTTP,
-                cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+                cacheConfig.isEmpty() ? NULL : cacheConfig.c_str(),
                 disconnectAtHighwatermark);
     } else if (!strncasecmp("data:", uri, 5)) {
         source = DataURISource::Create(uri);
diff --git a/media/libdatasource/MediaHTTP.cpp b/media/libdatasource/MediaHTTP.cpp
index 58c1ce8..b1f2140 100644
--- a/media/libdatasource/MediaHTTP.cpp
+++ b/media/libdatasource/MediaHTTP.cpp
@@ -156,7 +156,7 @@
 
 String8 MediaHTTP::getUri() {
     if (mInitCheck != OK) {
-        return String8::empty();
+        return String8();
     }
 
     String8 uri;
diff --git a/media/libdatasource/NuCachedSource2.cpp b/media/libdatasource/NuCachedSource2.cpp
index 6d63ffb..4e71d5f 100644
--- a/media/libdatasource/NuCachedSource2.cpp
+++ b/media/libdatasource/NuCachedSource2.cpp
@@ -225,7 +225,7 @@
     // IMediaHTTPConnection::readAt and therefore call back into JAVA.
     mLooper->start(false /* runOnCallingThread */, true /* canCallJava */);
 
-    mName = String8::format("NuCachedSource2(%s)", mSource->toString().string());
+    mName = String8::format("NuCachedSource2(%s)", mSource->toString().c_str());
 }
 
 NuCachedSource2::~NuCachedSource2() {
@@ -765,7 +765,7 @@
 
         headers->removeItemsAt(index);
 
-        ALOGV("Using special cache config '%s'", cacheConfig->string());
+        ALOGV("Using special cache config '%s'", cacheConfig->c_str());
     }
 
     if ((index = headers->indexOfKey(
diff --git a/media/libdatasource/OWNERS b/media/libdatasource/OWNERS
new file mode 100644
index 0000000..0e49ed8
--- /dev/null
+++ b/media/libdatasource/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 610698
+
+# Exclude /media/OWNERS but include top-level OWNERS
+set noparent
+include platform/frameworks/av:/OWNERS
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
\ No newline at end of file
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
index eb7ab1a..3148d36 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-#include "BundleTypes.h"
-#define LOG_TAG "EffectBundleAidl"
-#include <Utils.h>
 #include <algorithm>
+#include <limits.h>
 #include <unordered_set>
+#define LOG_TAG "EffectBundleAidl"
 
-#include <android-base/logging.h>
-#include <fmq/AidlMessageQueue.h>
 #include <audio_effects/effect_bassboost.h>
 #include <audio_effects/effect_equalizer.h>
 #include <audio_effects/effect_virtualizer.h>
-
-#include "EffectBundleAidl.h"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
 #include <LVM.h>
-#include <limits.h>
+#include <Utils.h>
+
+#include "BundleTypes.h"
+#include "EffectBundleAidl.h"
 
 using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostBundle;
 using aidl::android::hardware::audio::effect::Descriptor;
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
index 73141b6..b49d109 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -14,20 +14,21 @@
  * limitations under the License.
  */
 
-#include "ReverbTypes.h"
-#define LOG_TAG "EffectReverb"
-#include <Utils.h>
 #include <algorithm>
+#include <limits.h>
 #include <unordered_set>
 
-#include <android-base/logging.h>
-#include <fmq/AidlMessageQueue.h>
+#define LOG_TAG "EffectReverb"
+
 #include <audio_effects/effect_bassboost.h>
 #include <audio_effects/effect_equalizer.h>
 #include <audio_effects/effect_virtualizer.h>
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <Utils.h>
 
 #include "EffectReverb.h"
-#include <limits.h>
+#include "ReverbTypes.h"
 
 using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::EffectReverb;
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 1551e33..8d408dd 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -165,6 +165,7 @@
             pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
     if (pConfig->inputCfg.format != kProcessFormat) return -EINVAL;
 
+    pContext->mChannelCount = channelCount;
     pContext->mConfig = *pConfig;
 
     Visualizer_reset(pContext);
@@ -229,8 +230,6 @@
     pContext->mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED;
 
     // measurement initialization
-    pContext->mChannelCount =
-            audio_channel_count_from_out_mask(pContext->mConfig.inputCfg.channels);
     pContext->mMeasurementMode = MEASUREMENT_MODE_NONE;
     pContext->mMeasurementWindowSizeInBuffers = MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS;
     pContext->mMeasurementBufferIdx = 0;
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index eb436d1..8485ac0 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -304,7 +304,7 @@
     }
     for (size_t i = 0; i < tracks.size(); i++) {
         const String8 desc = trackDescriptions.itemAt(i);
-        str.appendFormat("    track {%s} ", desc.string());
+        str.appendFormat("    track {%s} ", desc.c_str());
         wp<IMediaSource> wSource = tracks.itemAt(i);
         if (wSource == NULL) {
             str.append(": null\n");
@@ -339,7 +339,7 @@
             if (source != NULL) {
                 instance.trackDescriptions.push_front(source->getFormat()->toString());
             } else {
-                instance.trackDescriptions.push_front(String8::empty());
+                instance.trackDescriptions.push_front(String8());
             }
             break;
         }
@@ -386,7 +386,7 @@
             }
         }
     }
-    write(fd, out.string(), out.size());
+    write(fd, out.c_str(), out.size());
     return OK;
 }
 
diff --git a/media/libmedia/IMediaHTTPConnection.cpp b/media/libmedia/IMediaHTTPConnection.cpp
index 8cbb4c2..b029b97 100644
--- a/media/libmedia/IMediaHTTPConnection.cpp
+++ b/media/libmedia/IMediaHTTPConnection.cpp
@@ -54,8 +54,8 @@
         tmp = String16("");
         if (headers != NULL) {
             for (size_t i = 0; i < headers->size(); ++i) {
-                String16 key(headers->keyAt(i).string());
-                String16 val(headers->valueAt(i).string());
+                String16 key(headers->keyAt(i).c_str());
+                String16 val(headers->valueAt(i).c_str());
 
                 tmp.append(key);
                 tmp.append(String16(": "));
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 86427ed..cdb1837 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -218,7 +218,7 @@
             } else {
                 mMetadata.replaceValueFor(keyCode, value);
             }
-            return mMetadata.valueFor(keyCode).string();
+            return mMetadata.valueFor(keyCode).c_str();
         } else {
             return NULL;
         }
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index e191999..755a147 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -255,7 +255,7 @@
 
     status_t setParameters(const String8& params)
     {
-        ALOGV("setParameter(%s)", params.string());
+        ALOGV("setParameter(%s)", params.c_str());
         Parcel data, reply;
         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
         data.writeString8(params);
@@ -275,7 +275,7 @@
 
     status_t setClientName(const String16& clientName)
     {
-        ALOGV("setClientName(%s)", String8(clientName).string());
+        ALOGV("setClientName(%s)", String8(clientName).c_str());
         Parcel data, reply;
         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
         data.writeString16(clientName);
diff --git a/media/libmedia/OWNERS b/media/libmedia/OWNERS
new file mode 100644
index 0000000..e932382
--- /dev/null
+++ b/media/libmedia/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 610698
+
+# Exclude /media/OWNERS but include top-level OWNERS
+set noparent
+include platform/frameworks/av:/OWNERS
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/libmedia/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
index 37cb059..af25015 100644
--- a/media/libmedia/include/media/omx/1.0/Conversion.h
+++ b/media/libmedia/include/media/omx/1.0/Conversion.h
@@ -811,11 +811,11 @@
  */
 // convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
 inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
-    t->mName = l.mName.string();
+    t->mName = l.mName.c_str();
     t->mRoles.resize(l.mRoles.size());
     size_t i = 0;
     for (auto& role : l.mRoles) {
-        t->mRoles[i++] = role.string();
+        t->mRoles[i++] = role.c_str();
     }
     return true;
 }
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index bd06fb6..48f5e4b 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -472,7 +472,7 @@
 }
 
 status_t MediaRecorder::setParameters(const String8& params) {
-    ALOGV("setParameters(%s)", params.string());
+    ALOGV("setParameters(%s)", params.c_str());
     if (mMediaRecorder == NULL) {
         ALOGE("media recorder is not initialized yet");
         return INVALID_OPERATION;
@@ -496,7 +496,7 @@
 
     status_t ret = mMediaRecorder->setParameters(params);
     if (OK != ret) {
-        ALOGE("setParameters(%s) failed: %d", params.string(), ret);
+        ALOGE("setParameters(%s) failed: %d", params.c_str(), ret);
         // Do not change our current state to MEDIA_RECORDER_ERROR, failures
         // of the only currently supported parameters, "max-duration" and
         // "max-filesize" are _not_ fatal.
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index 3832e90..f21ea53 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -43,6 +43,14 @@
 const char * const AudioParameter::keyBtHfpEnable = AUDIO_PARAMETER_KEY_HFP_ENABLE;
 const char * const AudioParameter::keyBtHfpSamplingRate = AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE;
 const char * const AudioParameter::keyBtHfpVolume = AUDIO_PARAMETER_KEY_HFP_VOLUME;
+const char * const AudioParameter::keyTtyMode = AUDIO_PARAMETER_KEY_TTY_MODE;
+const char * const AudioParameter::valueTtyModeOff = AUDIO_PARAMETER_VALUE_TTY_OFF;
+const char * const AudioParameter::valueTtyModeFull = AUDIO_PARAMETER_VALUE_TTY_FULL;
+const char * const AudioParameter::valueTtyModeHco = AUDIO_PARAMETER_VALUE_TTY_HCO;
+const char * const AudioParameter::valueTtyModeVco = AUDIO_PARAMETER_VALUE_TTY_VCO;
+const char * const AudioParameter::keyHacSetting = AUDIO_PARAMETER_KEY_HAC;
+const char * const AudioParameter::valueHacOff = AUDIO_PARAMETER_VALUE_HAC_OFF;
+const char * const AudioParameter::valueHacOn = AUDIO_PARAMETER_VALUE_HAC_ON;
 const char * const AudioParameter::keyHwAvSync = AUDIO_PARAMETER_HW_AV_SYNC;
 const char * const AudioParameter::keyPresentationId = AUDIO_PARAMETER_STREAM_PRESENTATION_ID;
 const char * const AudioParameter::keyProgramId = AUDIO_PARAMETER_STREAM_PROGRAM_ID;
@@ -88,7 +96,7 @@
     mKeyValuePairs = keyValuePairs;
     char *last;
 
-    strcpy(str, keyValuePairs.string());
+    strcpy(str, keyValuePairs.c_str());
     char *pair = strtok_r(str, ";", &last);
     while (pair != NULL) {
         if (strlen(pair) != 0) {
@@ -200,7 +208,7 @@
     value = 0;
     if (result == NO_ERROR) {
         int val;
-        if (sscanf(str8.string(), "%d", &val) == 1) {
+        if (sscanf(str8.c_str(), "%d", &val) == 1) {
             value = val;
         } else {
             result = INVALID_OPERATION;
@@ -216,7 +224,7 @@
     value = 0;
     if (result == NO_ERROR) {
         float val;
-        if (sscanf(str8.string(), "%f", &val) == 1) {
+        if (sscanf(str8.c_str(), "%f", &val) == 1) {
             value = val;
         } else {
             result = INVALID_OPERATION;
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 3eee854..21d5117 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -69,6 +69,16 @@
     static const char * const keyBtHfpSamplingRate;
     static const char * const keyBtHfpVolume;
 
+    static const char * const keyTtyMode;
+    static const char * const valueTtyModeOff;
+    static const char * const valueTtyModeFull;
+    static const char * const valueTtyModeHco;
+    static const char * const valueTtyModeVco;
+
+    static const char * const keyHacSetting;
+    static const char * const valueHacOff;
+    static const char * const valueHacOn;
+
     //  keyHwAvSync: get HW synchronization source identifier from a device
     //  keyMonoOutput: Enable mono audio playback
     //  keyStreamHwAvSync: set HW synchronization source identifier on a stream
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 266cb17..44e78d6 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -17,7 +17,8 @@
     ],
 }
 
-cc_library {
+filegroup {
+    name: "libmediaplayerservice_sources",
 
     srcs: [
         "ActivityManager.cpp",
@@ -30,6 +31,14 @@
         "StagefrightRecorder.cpp",
         "TestPlayerStub.cpp",
     ],
+}
+
+cc_defaults {
+    name: "libmediaplayerservice_defaults",
+
+    srcs: [
+        ":libmediaplayerservice_sources",
+    ],
 
     shared_libs: [
         "android.hardware.media.c2@1.0",
@@ -83,6 +92,24 @@
         "framework-permission-aidl-cpp",
     ],
 
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+    },
+}
+
+cc_library {
+    name: "libmediaplayerservice",
+
+    defaults: [
+        "libmediaplayerservice_defaults",
+    ],
+
     export_shared_lib_headers: [
         "libmedia",
         "framework-permission-aidl-cpp",
@@ -92,22 +119,9 @@
         "libmediautils_headers",
     ],
 
-    local_include_dirs: ["include"],
-
     export_include_dirs: [
         ".",
     ],
 
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    name: "libmediaplayerservice",
-
-    sanitize: {
-        cfi: true,
-    },
-
+    local_include_dirs: ["include"],
 }
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 3f08be5..91599e7 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -237,7 +237,7 @@
     if (hasFlattenedTag) {
         // the tags are UTF16, convert to UTF8
         String16 tags = parcel.readString16();
-        ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
+        ssize_t realTagSize = utf16_to_utf8_length(tags.c_str(), tags.size());
         if (realTagSize <= 0) {
             strcpy(attributes->tags, "");
         } else {
@@ -245,7 +245,7 @@
             // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
             size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
                     AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
-            utf16_to_utf8(tags.string(), tagSize, attributes->tags,
+            utf16_to_utf8(tags.c_str(), tagSize, attributes->tags,
                     sizeof(attributes->tags) / sizeof(attributes->tags[0]));
         }
     } else {
@@ -434,7 +434,7 @@
         }
     }
     result.append("\n");
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
 }
 
 
@@ -549,7 +549,7 @@
             mAuxEffectId, mSendLevel);
     result.append(buffer);
 
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     if (mTrack != 0) {
         mTrack->dump(fd, args);
     }
@@ -584,7 +584,7 @@
     } else {
         result.append("  lock is taken, no dump from player and audio output\n");
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     if (p != NULL) {
         p->dump(fd, args);
@@ -644,7 +644,7 @@
                 snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n",
                         c->mAttributionSource.pid);
                 result.append(buffer);
-                write(fd, result.string(), result.size());
+                write(fd, result.c_str(), result.size());
                 result = "\n";
                 c->dump(fd, args);
 
@@ -746,7 +746,7 @@
             result.append(s.c_str(), s.size());
         }
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     return NO_ERROR;
 }
@@ -1249,7 +1249,7 @@
         const BufferingSettings& buffering)
 {
     ALOGV("[%d] setBufferingSettings{%s}",
-            mConnId, buffering.toString().string());
+            mConnId, buffering.toString().c_str());
     sp<MediaPlayerBase> p = getPlayer();
     if (p == 0) return UNKNOWN_ERROR;
     return p->setBufferingSettings(buffering);
@@ -1264,7 +1264,7 @@
     status_t ret = p->getBufferingSettings(buffering);
     if (ret == NO_ERROR) {
         ALOGV("[%d] getBufferingSettings{%s}",
-                mConnId, buffering->toString().string());
+                mConnId, buffering->toString().c_str());
     } else {
         ALOGE("[%d] getBufferingSettings returned %d", mConnId, ret);
     }
@@ -2008,7 +2008,7 @@
 String8  MediaPlayerService::AudioOutput::getParameters(const String8& keys)
 {
     Mutex::Autolock lock(mLock);
-    if (mTrack == 0) return String8::empty();
+    if (mTrack == 0) return String8();
     return mTrack->getParameters(keys);
 }
 
@@ -2627,6 +2627,16 @@
     Mutex::Autolock lock(mLock);
     ALOGV("AudioOutput::applyVolumeShaper");
 
+    if (configuration == nullptr) {
+        ALOGE("AudioOutput::applyVolumeShaper Null configuration parameter");
+        return VolumeShaper::Status(BAD_VALUE);
+    }
+
+    if (operation == nullptr) {
+        ALOGE("AudioOutput::applyVolumeShaper Null operation parameter");
+        return VolumeShaper::Status(BAD_VALUE);
+    }
+
     mVolumeHandler->setIdIfNecessary(configuration);
 
     VolumeShaper::Status status;
@@ -3053,4 +3063,11 @@
     }
     return NO_ERROR;
 }
+
+#ifdef FUZZ_MODE_MEDIA_PLAYER_SERVICE
+sp<MediaPlayerService> MediaPlayerService::createForFuzzTesting() {
+    return sp<MediaPlayerService>::make();
+}
+#endif // FUZZ_MODE_MEDIA_PLAYER_SERVICE
+
 } // namespace android
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 52c2f79..cb544bd 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -508,6 +508,12 @@
                 SortedVector< wp<Client> >  mClients;
                 SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
                 int32_t                     mNextConnId;
+
+#ifdef FUZZ_MODE_MEDIA_PLAYER_SERVICE
+public:
+    friend class sp<MediaPlayerService>;
+    static sp<MediaPlayerService> createForFuzzTesting();
+#endif // FUZZ_MODE_MEDIA_PLAYER_SERVICE
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 58fc06d..d6b1c90 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -245,7 +245,7 @@
 }
 
 status_t MediaRecorderClient::setParameters(const String8& params) {
-    ALOGV("setParameters(%s)", params.string());
+    ALOGV("setParameters(%s)", params.c_str());
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
@@ -519,7 +519,7 @@
 }
 
 status_t MediaRecorderClient::setClientName(const String16& clientName) {
-    ALOGV("setClientName(%s)", String8(clientName).string());
+    ALOGV("setClientName(%s)", String8(clientName).c_str());
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index fb228ca..9e289d0 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -67,7 +67,7 @@
     result.append(" MetadataRetrieverClient\n");
     snprintf(buffer, 255, "  pid(%d)\n", mPid);
     result.append(buffer);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     write(fd, "\n", 1);
     return NO_ERROR;
 }
diff --git a/media/libmediaplayerservice/OWNERS b/media/libmediaplayerservice/OWNERS
new file mode 100644
index 0000000..e932382
--- /dev/null
+++ b/media/libmediaplayerservice/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 610698
+
+# Exclude /media/OWNERS but include top-level OWNERS
+set noparent
+include platform/frameworks/av:/OWNERS
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index db979d7..6b79653 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -472,7 +472,7 @@
         return NULL;
     }
 
-    return mMetaData.valueAt(index).string();
+    return mMetaData.valueAt(index).c_str();
 }
 
 void StagefrightMetadataRetriever::parseColorAspects(const sp<MetaData>& meta) {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index cb2007d..89348a4 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -519,7 +519,7 @@
 // Trim both leading and trailing whitespace from the given string.
 static void TrimString(String8 *s) {
     size_t num_bytes = s->bytes();
-    const char *data = s->string();
+    const char *data = s->c_str();
 
     size_t leading_space = 0;
     while (leading_space < num_bytes && isspace(data[leading_space])) {
@@ -531,7 +531,7 @@
         --i;
     }
 
-    s->setTo(String8(&data[leading_space], i - leading_space));
+    *s = String8(&data[leading_space], i - leading_space);
 }
 
 status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) {
@@ -823,9 +823,9 @@
 }
 
 status_t StagefrightRecorder::setParamRtpLocalIp(const String8 &localIp) {
-    ALOGV("setParamVideoLocalIp: %s", localIp.string());
+    ALOGV("setParamVideoLocalIp: %s", localIp.c_str());
 
-    mLocalIp.setTo(localIp.string());
+    mLocalIp = localIp.c_str();
     return OK;
 }
 
@@ -837,9 +837,9 @@
 }
 
 status_t StagefrightRecorder::setParamRtpRemoteIp(const String8 &remoteIp) {
-    ALOGV("setParamVideoRemoteIp: %s", remoteIp.string());
+    ALOGV("setParamVideoRemoteIp: %s", remoteIp.c_str());
 
-    mRemoteIp.setTo(remoteIp.string());
+    mRemoteIp = remoteIp.c_str();
     return OK;
 }
 
@@ -929,197 +929,197 @@
 }
 
 status_t StagefrightRecorder::setLogSessionId(const String8 &log_session_id) {
-    ALOGV("setLogSessionId: %s", log_session_id.string());
+    ALOGV("setLogSessionId: %s", log_session_id.c_str());
 
     // TODO: validity check that log_session_id is a 32-byte hex digit.
-    mLogSessionId.setTo(log_session_id.string());
+    mLogSessionId = log_session_id.c_str();
     return OK;
 }
 
 status_t StagefrightRecorder::setParameter(
         const String8 &key, const String8 &value) {
-    ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
+    ALOGV("setParameter: key (%s) => value (%s)", key.c_str(), value.c_str());
     if (key == "max-duration") {
         int64_t max_duration_ms;
-        if (safe_strtoi64(value.string(), &max_duration_ms)) {
+        if (safe_strtoi64(value.c_str(), &max_duration_ms)) {
             return setParamMaxFileDurationUs(1000LL * max_duration_ms);
         }
     } else if (key == "max-filesize") {
         int64_t max_filesize_bytes;
-        if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
+        if (safe_strtoi64(value.c_str(), &max_filesize_bytes)) {
             return setParamMaxFileSizeBytes(max_filesize_bytes);
         }
     } else if (key == "interleave-duration-us") {
         int32_t durationUs;
-        if (safe_strtoi32(value.string(), &durationUs)) {
+        if (safe_strtoi32(value.c_str(), &durationUs)) {
             return setParamInterleaveDuration(durationUs);
         }
     } else if (key == "param-movie-time-scale") {
         int32_t timeScale;
-        if (safe_strtoi32(value.string(), &timeScale)) {
+        if (safe_strtoi32(value.c_str(), &timeScale)) {
             return setParamMovieTimeScale(timeScale);
         }
     } else if (key == "param-use-64bit-offset") {
         int32_t use64BitOffset;
-        if (safe_strtoi32(value.string(), &use64BitOffset)) {
+        if (safe_strtoi32(value.c_str(), &use64BitOffset)) {
             return setParam64BitFileOffset(use64BitOffset != 0);
         }
     } else if (key == "param-geotag-longitude") {
         int64_t longitudex10000;
-        if (safe_strtoi64(value.string(), &longitudex10000)) {
+        if (safe_strtoi64(value.c_str(), &longitudex10000)) {
             return setParamGeoDataLongitude(longitudex10000);
         }
     } else if (key == "param-geotag-latitude") {
         int64_t latitudex10000;
-        if (safe_strtoi64(value.string(), &latitudex10000)) {
+        if (safe_strtoi64(value.c_str(), &latitudex10000)) {
             return setParamGeoDataLatitude(latitudex10000);
         }
     } else if (key == "param-track-time-status") {
         int64_t timeDurationUs;
-        if (safe_strtoi64(value.string(), &timeDurationUs)) {
+        if (safe_strtoi64(value.c_str(), &timeDurationUs)) {
             return setParamTrackTimeStatus(timeDurationUs);
         }
     } else if (key == "audio-param-sampling-rate") {
         int32_t sampling_rate;
-        if (safe_strtoi32(value.string(), &sampling_rate)) {
+        if (safe_strtoi32(value.c_str(), &sampling_rate)) {
             return setParamAudioSamplingRate(sampling_rate);
         }
     } else if (key == "audio-param-number-of-channels") {
         int32_t number_of_channels;
-        if (safe_strtoi32(value.string(), &number_of_channels)) {
+        if (safe_strtoi32(value.c_str(), &number_of_channels)) {
             return setParamAudioNumberOfChannels(number_of_channels);
         }
     } else if (key == "audio-param-encoding-bitrate") {
         int32_t audio_bitrate;
-        if (safe_strtoi32(value.string(), &audio_bitrate)) {
+        if (safe_strtoi32(value.c_str(), &audio_bitrate)) {
             return setParamAudioEncodingBitRate(audio_bitrate);
         }
     } else if (key == "audio-param-time-scale") {
         int32_t timeScale;
-        if (safe_strtoi32(value.string(), &timeScale)) {
+        if (safe_strtoi32(value.c_str(), &timeScale)) {
             return setParamAudioTimeScale(timeScale);
         }
     } else if (key == "video-param-encoding-bitrate") {
         int32_t video_bitrate;
-        if (safe_strtoi32(value.string(), &video_bitrate)) {
+        if (safe_strtoi32(value.c_str(), &video_bitrate)) {
             return setParamVideoEncodingBitRate(video_bitrate);
         }
     } else if (key == "video-param-bitrate-mode") {
         int32_t video_bitrate_mode;
-        if (safe_strtoi32(value.string(), &video_bitrate_mode)) {
+        if (safe_strtoi32(value.c_str(), &video_bitrate_mode)) {
             return setParamVideoBitRateMode(video_bitrate_mode);
         }
     } else if (key == "video-param-rotation-angle-degrees") {
         int32_t degrees;
-        if (safe_strtoi32(value.string(), &degrees)) {
+        if (safe_strtoi32(value.c_str(), &degrees)) {
             return setParamVideoRotation(degrees);
         }
     } else if (key == "video-param-i-frames-interval") {
         int32_t seconds;
-        if (safe_strtoi32(value.string(), &seconds)) {
+        if (safe_strtoi32(value.c_str(), &seconds)) {
             return setParamVideoIFramesInterval(seconds);
         }
     } else if (key == "video-param-encoder-profile") {
         int32_t profile;
-        if (safe_strtoi32(value.string(), &profile)) {
+        if (safe_strtoi32(value.c_str(), &profile)) {
             return setParamVideoEncoderProfile(profile);
         }
     } else if (key == "video-param-encoder-level") {
         int32_t level;
-        if (safe_strtoi32(value.string(), &level)) {
+        if (safe_strtoi32(value.c_str(), &level)) {
             return setParamVideoEncoderLevel(level);
         }
     } else if (key == "video-param-camera-id") {
         int32_t cameraId;
-        if (safe_strtoi32(value.string(), &cameraId)) {
+        if (safe_strtoi32(value.c_str(), &cameraId)) {
             return setParamVideoCameraId(cameraId);
         }
     } else if (key == "video-param-time-scale") {
         int32_t timeScale;
-        if (safe_strtoi32(value.string(), &timeScale)) {
+        if (safe_strtoi32(value.c_str(), &timeScale)) {
             return setParamVideoTimeScale(timeScale);
         }
     } else if (key == "time-lapse-enable") {
         int32_t captureFpsEnable;
-        if (safe_strtoi32(value.string(), &captureFpsEnable)) {
+        if (safe_strtoi32(value.c_str(), &captureFpsEnable)) {
             return setParamCaptureFpsEnable(captureFpsEnable);
         }
     } else if (key == "time-lapse-fps") {
         double fps;
-        if (safe_strtod(value.string(), &fps)) {
+        if (safe_strtod(value.c_str(), &fps)) {
             return setParamCaptureFps(fps);
         }
     } else if (key == "rtp-param-local-ip") {
         return setParamRtpLocalIp(value);
     } else if (key == "rtp-param-local-port") {
         int32_t localPort;
-        if (safe_strtoi32(value.string(), &localPort)) {
+        if (safe_strtoi32(value.c_str(), &localPort)) {
             return setParamRtpLocalPort(localPort);
         }
     } else if (key == "rtp-param-remote-ip") {
         return setParamRtpRemoteIp(value);
     } else if (key == "rtp-param-remote-port") {
         int32_t remotePort;
-        if (safe_strtoi32(value.string(), &remotePort)) {
+        if (safe_strtoi32(value.c_str(), &remotePort)) {
             return setParamRtpRemotePort(remotePort);
         }
     } else if (key == "rtp-param-self-id") {
         int32_t selfID;
         int64_t temp;
-        if (safe_strtoi64(value.string(), &temp)) {
+        if (safe_strtoi64(value.c_str(), &temp)) {
             selfID = static_cast<int32_t>(temp);
             return setParamSelfID(selfID);
         }
     } else if (key == "rtp-param-opponent-id") {
         int32_t opnId;
         int64_t temp;
-        if (safe_strtoi64(value.string(), &temp)) {
+        if (safe_strtoi64(value.c_str(), &temp)) {
             opnId = static_cast<int32_t>(temp);
             return setParamVideoOpponentID(opnId);
         }
     } else if (key == "rtp-param-payload-type") {
         int32_t payloadType;
-        if (safe_strtoi32(value.string(), &payloadType)) {
+        if (safe_strtoi32(value.c_str(), &payloadType)) {
             return setParamPayloadType(payloadType);
         }
     } else if (key == "rtp-param-ext-cvo-extmap") {
         int32_t extmap;
-        if (safe_strtoi32(value.string(), &extmap)) {
+        if (safe_strtoi32(value.c_str(), &extmap)) {
             return setRTPCVOExtMap(extmap);
         }
     } else if (key == "rtp-param-ext-cvo-degrees") {
         int32_t degrees;
-        if (safe_strtoi32(value.string(), &degrees)) {
+        if (safe_strtoi32(value.c_str(), &degrees)) {
             return setRTPCVODegrees(degrees);
         }
     } else if (key == "video-param-request-i-frame") {
         return requestIDRFrame();
     } else if (key == "rtp-param-set-socket-dscp") {
         int32_t dscp;
-        if (safe_strtoi32(value.string(), &dscp)) {
+        if (safe_strtoi32(value.c_str(), &dscp)) {
             return setParamRtpDscp(dscp);
         }
     } else if (key == "rtp-param-set-socket-ecn") {
         int32_t targetEcn;
-        if (safe_strtoi32(value.string(), &targetEcn)) {
+        if (safe_strtoi32(value.c_str(), &targetEcn)) {
             return setParamRtpEcn(targetEcn);
         }
     } else if (key == "rtp-param-set-socket-network") {
         int64_t networkHandle;
-        if (safe_strtoi64(value.string(), &networkHandle)) {
+        if (safe_strtoi64(value.c_str(), &networkHandle)) {
             return setSocketNetwork(networkHandle);
         }
     } else if (key == "log-session-id") {
         return setLogSessionId(value);
     } else {
-        ALOGE("setParameter: failed to find key %s", key.string());
+        ALOGE("setParameter: failed to find key %s", key.c_str());
     }
     return BAD_VALUE;
 }
 
 status_t StagefrightRecorder::setParameters(const String8 &params) {
-    ALOGV("setParameters: %s", params.string());
-    const char *cparams = params.string();
+    ALOGV("setParameters: %s", params.c_str());
+    const char *cparams = params.c_str();
     const char *key_start = cparams;
     for (;;) {
         const char *equal_pos = strchr(key_start, '=');
@@ -1137,9 +1137,9 @@
         const char *semicolon_pos = strchr(value_start, ';');
         String8 value;
         if (semicolon_pos == NULL) {
-            value.setTo(value_start);
+            value = value_start;
         } else {
-            value.setTo(value_start, semicolon_pos - value_start);
+            value = String8(value_start, semicolon_pos - value_start);
         }
         if (setParameter(key, value) != OK) {
             return BAD_VALUE;
@@ -2680,7 +2680,7 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
     result.append(buffer);
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     return OK;
 }
 }  // namespace android
diff --git a/media/libmediaplayerservice/fuzzer/Android.bp b/media/libmediaplayerservice/fuzzer/Android.bp
index 5e95c87..017f403 100644
--- a/media/libmediaplayerservice/fuzzer/Android.bp
+++ b/media/libmediaplayerservice/fuzzer/Android.bp
@@ -175,3 +175,26 @@
         "libstagefright_httplive",
     ],
 }
+
+cc_fuzz {
+    name: "media_player_service_fuzzer",
+    defaults: [
+        "service_fuzzer_defaults",
+        "libmediaplayerservice_defaults",
+        "fuzzer_disable_leaks",
+    ],
+    srcs: [
+        "media_player_service_fuzzer.cpp",
+    ],
+    fuzz_config: {
+        cc: [
+            "kyslov@google.com",
+            "ibaker@google.com",
+        ],
+        triage_assignee: "waghpawan@google.com",
+    },
+    cflags: [
+        "-DFUZZ_MODE_MEDIA_PLAYER_SERVICE",
+    ],
+    include_dirs: ["frameworks/av/media/libmediaplayerservice/"],
+}
diff --git a/media/libmediaplayerservice/fuzzer/media_player_service_fuzzer.cpp b/media/libmediaplayerservice/fuzzer/media_player_service_fuzzer.cpp
new file mode 100644
index 0000000..4e3b0fe
--- /dev/null
+++ b/media/libmediaplayerservice/fuzzer/media_player_service_fuzzer.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <MediaPlayerService.h>
+
+using android::fuzzService;
+using android::MediaPlayerService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto service = MediaPlayerService::createForFuzzTesting();
+    fuzzService(service, FuzzedDataProvider(data, size));
+    return 0;
+}
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index fb20aab..be1aa00 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -149,7 +149,7 @@
         virtual bool        needsTrailingPadding() { return true; }
 
         virtual status_t    setParameters(const String8& /* keyValuePairs */) { return NO_ERROR; }
-        virtual String8     getParameters(const String8& /* keys */) { return String8::empty(); }
+        virtual String8     getParameters(const String8& /* keys */) { return String8(); }
 
         virtual media::VolumeShaper::Status applyVolumeShaper(
                                     const sp<media::VolumeShaper::Configuration>& configuration,
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 1358faa..991c77b 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -270,7 +270,7 @@
     }
 
     ALOGV("initFromDataSource mSources.size(): %zu  mIsSecure: %d  mime[0]: %s", mSources.size(),
-            mIsSecure, (mMimes.isEmpty() ? "NONE" : mMimes[0].string()));
+            mIsSecure, (mMimes.isEmpty() ? "NONE" : mMimes[0].c_str()));
 
     if (mSources.size() == 0) {
         ALOGE("b/23705695");
@@ -292,12 +292,12 @@
         *buffering = mBufferingSettings;
     }
 
-    ALOGV("getBufferingSettings{%s}", buffering->toString().string());
+    ALOGV("getBufferingSettings{%s}", buffering->toString().c_str());
     return OK;
 }
 
 status_t NuPlayer::GenericSource::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
+    ALOGV("setBufferingSettings{%s}", buffering.toString().c_str());
 
     Mutex::Autolock _l(mLock);
     mBufferingSettings = buffering;
@@ -1619,7 +1619,7 @@
         return status;
     }
     ALOGV("prepareDrm: createCryptoAndPlugin succeeded for uuid: %s",
-            DrmUUID::toHexString(uuid).string());
+            DrmUUID::toHexString(uuid).c_str());
 
     *outCrypto = crypto;
     // as long a there is an active crypto
@@ -1632,7 +1632,7 @@
     }
 
     // first mime in this list is either the video track, or the first audio track
-    const char *mime = mMimes[0].string();
+    const char *mime = mMimes[0].c_str();
     mIsSecure = crypto->requiresSecureDecoderComponent(mime);
     ALOGV("prepareDrm: requiresSecureDecoderComponent mime: %s  isSecure: %d",
             mime, mIsSecure);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 485923f..a625893 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -370,7 +370,7 @@
 }
 
 void NuPlayer::setDataSourceAsync(const String8& rtpParams) {
-    ALOGD("setDataSourceAsync for RTP = %s", rtpParams.string());
+    ALOGD("setDataSourceAsync for RTP = %s", rtpParams.c_str());
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
 
     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index a964d4f..8525192 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -89,8 +89,8 @@
         drmSchemes.add(_uuid);
 
         ALOGV("ParsePSSH[%zu]: %s: %s", numentries,
-                _uuid.toHexString().string(),
-                DrmUUID::arrayToHex(data, datalen).string()
+                _uuid.toHexString().c_str(),
+                DrmUUID::arrayToHex(data, datalen).c_str()
              );
 
         numentries++;
@@ -167,7 +167,7 @@
     parcel->writeByteArray(psshsize, (const uint8_t*)pssh);
 
     ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %zu %s", psshsize,
-            DrmUUID::arrayToHex((uint8_t*)pssh, psshsize).string());
+            DrmUUID::arrayToHex((uint8_t*)pssh, psshsize).c_str());
 
     // 2) supportedDRMs
     Vector<DrmUUID> supportedDRMs = getSupportedDrmSchemes(pssh, psshsize);
@@ -177,7 +177,7 @@
         parcel->writeByteArray(DrmUUID::UUID_SIZE, uuid.ptr());
 
         ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  supportedScheme[%zu] %s", i,
-                uuid.toHexString().string());
+                uuid.toHexString().c_str());
     }
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index bcb4756..3d4e955 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -132,6 +132,7 @@
       mMediaClock(mediaClock),
       mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
       mAudioFirstAnchorTimeMediaUs(-1),
+      mAudioAnchorTimeMediaUs(-1),
       mAnchorTimeMediaUs(-1),
       mAnchorNumFramesWritten(-1),
       mVideoLateByUs(0LL),
@@ -433,6 +434,7 @@
 // Called on renderer looper.
 void NuPlayer::Renderer::clearAnchorTime() {
     mMediaClock->clearAnchor();
+    mAudioAnchorTimeMediaUs = -1;
     mAnchorTimeMediaUs = -1;
     mAnchorNumFramesWritten = -1;
 }
@@ -1286,7 +1288,7 @@
     Mutex::Autolock autoLock(mLock);
     // TRICKY: vorbis decoder generates multiple frames with the same
     // timestamp, so only update on the first frame with a given timestamp
-    if (mediaTimeUs == mAnchorTimeMediaUs) {
+    if (mediaTimeUs == mAudioAnchorTimeMediaUs) {
         return;
     }
     setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
@@ -1324,6 +1326,7 @@
         }
     }
     mAnchorNumFramesWritten = mNumFramesWritten;
+    mAudioAnchorTimeMediaUs = mediaTimeUs;
     mAnchorTimeMediaUs = mediaTimeUs;
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.cpp b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
index fd03150..9a33120 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
@@ -56,7 +56,7 @@
       mReceivedFirstRTPPacket(false),
       mPausing(false),
       mPauseGeneration(0) {
-    ALOGD("RTPSource initialized with rtpParams=%s", rtpParams.string());
+    ALOGD("RTPSource initialized with rtpParams=%s", rtpParams.c_str());
 }
 
 NuPlayer::RTPSource::~RTPSource() {
@@ -661,7 +661,7 @@
 }
 
 status_t NuPlayer::RTPSource::setParameter(const String8 &key, const String8 &value) {
-    ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
+    ALOGV("setParameter: key (%s) => value (%s)", key.c_str(), value.c_str());
 
     bool isAudioKey = key.contains("audio");
     TrackInfo *info = NULL;
@@ -684,12 +684,12 @@
     if (key == "rtp-param-mime-type") {
         info->mMimeType = value;
 
-        const char *mime = value.string();
+        const char *mime = value.c_str();
         const char *delimiter = strchr(mime, '/');
         info->mCodecName = delimiter ? (delimiter + 1) : "<none>";
 
         ALOGV("rtp-param-mime-type: mMimeType (%s) => mCodecName (%s)",
-                info->mMimeType.string(), info->mCodecName.string());
+                info->mMimeType.c_str(), info->mCodecName.c_str());
     } else if (key == "video-param-decoder-profile") {
         info->mCodecProfile = atoi(value);
     } else if (key == "video-param-decoder-level") {
@@ -732,8 +732,8 @@
 }
 
 status_t NuPlayer::RTPSource::setParameters(const String8 &params) {
-    ALOGV("setParameters: %s", params.string());
-    const char *cparams = params.string();
+    ALOGV("setParameters: %s", params.c_str());
+    const char *cparams = params.c_str();
     const char *key_start = cparams;
     for (;;) {
         const char *equal_pos = strchr(key_start, '=');
@@ -751,9 +751,9 @@
         const char *semicolon_pos = strchr(value_start, ';');
         String8 value;
         if (semicolon_pos == NULL) {
-            value.setTo(value_start);
+            value = value_start;
         } else {
-            value.setTo(value_start, semicolon_pos - value_start);
+            value = String8(value_start, semicolon_pos - value_start);
         }
         if (setParameter(key, value) != OK) {
             return BAD_VALUE;
@@ -784,7 +784,7 @@
 //static
 void NuPlayer::RTPSource::TrimString(String8 *s) {
     size_t num_bytes = s->bytes();
-    const char *data = s->string();
+    const char *data = s->c_str();
 
     size_t leading_space = 0;
     while (leading_space < num_bytes && isspace(data[leading_space])) {
@@ -796,7 +796,7 @@
         --i;
     }
 
-    s->setTo(String8(&data[leading_space], i - leading_space));
+    *s = String8(&data[leading_space], i - leading_space);
 }
 
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
index f0c0a35..574ad3d 100644
--- a/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/include/nuplayer/NuPlayerRenderer.h
@@ -179,6 +179,9 @@
     float mVideoFpsHint;
 
     int64_t mAudioFirstAnchorTimeMediaUs;
+    // previous audio anchor timestamp, in media time base.
+    int64_t mAudioAnchorTimeMediaUs;
+    // previous anchor timestamp (audio or video), in media time base.
     int64_t mAnchorTimeMediaUs;
     int64_t mAnchorNumFramesWritten;
     int64_t mVideoLateByUs;
diff --git a/media/libnblog/PerformanceAnalysis.cpp b/media/libnblog/PerformanceAnalysis.cpp
index e91a511..507295a 100644
--- a/media/libnblog/PerformanceAnalysis.cpp
+++ b/media/libnblog/PerformanceAnalysis.cpp
@@ -409,7 +409,7 @@
 
 // Writes a string into specified file descriptor
 void dumpLine(int fd, int indent, const String8 &body) {
-    dprintf(fd, "%.*s%s \n", indent, "", body.string());
+    dprintf(fd, "%.*s%s \n", indent, "", body.c_str());
 }
 
 } // namespace ReportPerformance
diff --git a/media/libnblog/Reader.cpp b/media/libnblog/Reader.cpp
index d6232d4..a7d6ca2 100644
--- a/media/libnblog/Reader.cpp
+++ b/media/libnblog/Reader.cpp
@@ -283,7 +283,7 @@
             break;
         }
         if (!body.isEmpty()) {
-            dprintf(fd, "%.*s%s %s\n", (int)indent, "", timestamp.string(), body.string());
+            dprintf(fd, "%.*s%s %s\n", (int)indent, "", timestamp.c_str(), body.c_str());
             body.clear();
         }
         timestamp.clear();
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index eb3cb45..ede4855 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -38,7 +38,7 @@
     mName = String8::format("CallbackDataSource(%d->%d, %s)",
             getpid(),
             IPCThreadState::self()->getCallingPid(),
-            mIDataSource->toString().string());
+            mIDataSource->toString().c_str());
 
 }
 
@@ -120,7 +120,7 @@
 
 TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
     : mSource(source), mCachedOffset(0), mCachedSize(0) {
-    mName = String8::format("TinyCacheSource(%s)", mSource->toString().string());
+    mName = String8::format("TinyCacheSource(%s)", mSource->toString().c_str());
 }
 
 status_t TinyCacheSource::initCheck() const {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 967c316..4441121 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -32,6 +32,7 @@
 #include <media/stagefright/MetaData.h>
 #include <camera/Camera.h>
 #include <camera/CameraParameters.h>
+#include <camera/StringUtils.h>
 #include <gui/Surface.h>
 #include <utils/String8.h>
 #include <cutils/properties.h>
@@ -146,7 +147,7 @@
 
 status_t CameraSource::isCameraAvailable(
     const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
-    int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) {
+    int32_t cameraId, const std::string& clientName, uid_t clientUid, pid_t clientPid) {
 
     if (camera == 0) {
         mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid,
@@ -535,7 +536,7 @@
     status_t err = OK;
 
     if ((err = isCameraAvailable(camera, proxy, cameraId,
-            clientName, clientUid, clientPid)) != OK) {
+            toStdString(clientName), clientUid, clientPid)) != OK) {
         ALOGE("Camera connection could not be established.");
         return err;
     }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 2cd3768..e399cbe 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -612,7 +612,7 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     mStarted: %s\n", mStarted? "true": "false");
     result.append(buffer);
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     for (List<Track *>::iterator it = mTracks.begin();
          it != mTracks.end(); ++it) {
         (*it)->dump(fd, args);
@@ -634,7 +634,7 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "       duration encoded : %" PRId64 " us\n", mTrackDurationUs);
     result.append(buffer);
-    ::write(fd, result.string(), result.size());
+    ::write(fd, result.c_str(), result.size());
     return OK;
 }
 
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e0ebc11..2af88d0d 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>
@@ -291,6 +291,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 +307,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 +357,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 +391,94 @@
     }
 
 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(), mCookie);
+            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;
+    BinderDiedContext* mCookie;
 };
 
 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))),
+    mCookie(nullptr) {
     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 +491,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.
+    mCookie = new BinderDiedContext{.mRMServiceProxy = weak_from_this()};
+    // Register for the callbacks by linking to death notification.
+    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), mCookie);
+
+    // 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 +549,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 +648,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 +1164,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) {
@@ -1134,7 +1257,7 @@
 
 void MediaCodec::updateMediametrics() {
     if (mMetricsHandle == 0) {
-        ALOGW("no metrics handle found");
+        ALOGV("no metrics handle found");
         return;
     }
 
@@ -1496,7 +1619,7 @@
 }
 
 void MediaCodec::flushMediametrics() {
-    ALOGD("flushMediametrics");
+    ALOGV("flushMediametrics");
 
     // update does its own mutex locking
     updateMediametrics();
@@ -2230,9 +2353,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);
@@ -2833,9 +2958,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/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 2520e2a..1c72a65 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -242,22 +242,22 @@
                 continue;
             }
             void *libHandle = android_dlopen_ext(
-                    libPath.string(),
+                    libPath.c_str(),
                     RTLD_NOW | RTLD_LOCAL, dlextinfo);
             if (libHandle == nullptr) {
-                ALOGI("dlopen(%s) reported error %s", libPath.string(), strerror(errno));
+                ALOGI("dlopen(%s) reported error %s", libPath.c_str(), strerror(errno));
                 continue;
             }
 
             GetExtractorDef getDef =
                 (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
             if (getDef == nullptr) {
-                ALOGI("no sniffer found in %s", libPath.string());
+                ALOGI("no sniffer found in %s", libPath.c_str());
                 dlclose(libHandle);
                 continue;
             }
 
-            ALOGV("registering sniffer for %s", libPath.string());
+            ALOGV("registering sniffer for %s", libPath.c_str());
             RegisterExtractor(
                     new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
         }
@@ -387,7 +387,7 @@
             out.append("  (no plugins registered)\n");
         }
     }
-    write(fd, out.string(), out.size());
+    write(fd, out.c_str(), out.size());
     return OK;
 }
 
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 28ca9ff..19e3e6a 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -164,7 +164,7 @@
 
 const char* NuMediaExtractor::getName() const {
     Mutex::Autolock autoLock(mLock);
-    return mImpl == nullptr ? nullptr : mName.string();
+    return mImpl == nullptr ? nullptr : mName.c_str();
 }
 
 static String8 arrayToString(const std::vector<uint8_t> &array) {
diff --git a/media/libstagefright/OWNERS b/media/libstagefright/OWNERS
index f02e168..df61c29 100644
--- a/media/libstagefright/OWNERS
+++ b/media/libstagefright/OWNERS
@@ -9,3 +9,4 @@
 include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
 
 per-file Camera*.cpp = file:/camera/OWNERS
+per-file Camera*.h = file:/camera/OWNERS
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index 574fc1a..5ade29b 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -102,7 +102,12 @@
 static std::mutex pending_mutex;
 static std::condition_variable pending_added;
 
-static void* closing_thread_func(void *arg) {
+static void* closingThreadWorker(void *arg) {
+    // simplifies debugging to name the thread
+    if (pthread_setname_np(pthread_self(), "mediaCloser")) {
+        ALOGW("Failed to set thread name on thread for closing data sources");
+    }
+
     while (true) {
         sp<DataSource> ds = nullptr;
         std::unique_lock _lk(pending_mutex);
@@ -124,7 +129,7 @@
 
 // this can be '&ds' as long as the pending.push_back() bumps the
 // reference counts to ensure the object lives long enough
-static void start_close_thread(sp<DataSource> &ds) {
+static void asyncDataSourceClose(sp<DataSource> &ds) {
 
     // make sure we have our (single) worker thread
     static std::once_flag sCheckOnce;
@@ -132,7 +137,7 @@
         pthread_attr_t attr;
         pthread_attr_init(&attr);
         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-        pthread_create(&myThread, &attr, closing_thread_func, nullptr);
+        pthread_create(&myThread, &attr, closingThreadWorker, nullptr);
         pthread_attr_destroy(&attr);
     });
 
@@ -149,7 +154,7 @@
     int8_t new_scheme = property_get_bool("debug.mediaextractor.delayedclose", 1);
     if (new_scheme != 0) {
         ALOGV("deferred close()");
-        start_close_thread(mSource);
+        asyncDataSourceClose(mSource);
         mSource.clear();
     } else {
         ALOGV("immediate close()");
diff --git a/media/libstagefright/http/Android.bp b/media/libstagefright/http/Android.bp
index f25318d..4383d6f 100644
--- a/media/libstagefright/http/Android.bp
+++ b/media/libstagefright/http/Android.bp
@@ -37,10 +37,4 @@
         ],
         cfi: true,
     },
-
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-    },
 }
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 68f1de9..a15b66d 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -265,7 +265,7 @@
 #endif
 
     sp<M3UParser> playlist =
-        new M3UParser(actualUrl.string(), buffer->data(), buffer->size());
+        new M3UParser(actualUrl.c_str(), buffer->data(), buffer->size());
 
     if (playlist->initCheck() != OK) {
         ALOGE("failed to parse .m3u8 playlist");
diff --git a/media/libstagefright/include/media/stagefright/CameraSource.h b/media/libstagefright/include/media/stagefright/CameraSource.h
index e8770ed..fcd17b9 100644
--- a/media/libstagefright/include/media/stagefright/CameraSource.h
+++ b/media/libstagefright/include/media/stagefright/CameraSource.h
@@ -259,7 +259,7 @@
     status_t isCameraAvailable(const sp<hardware::ICamera>& camera,
                                const sp<ICameraRecordingProxy>& proxy,
                                int32_t cameraId,
-                               const String16& clientName,
+                               const std::string& clientName,
                                uid_t clientUid,
                                pid_t clientPid);
 
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 52d7d3d..05bc9cc 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -472,7 +472,7 @@
     sp<AMessage> mAsyncReleaseCompleteNotification;
     sp<AMessage> mOnFirstTunnelFrameReadyNotification;
 
-    sp<ResourceManagerServiceProxy> mResourceManagerProxy;
+    std::shared_ptr<ResourceManagerServiceProxy> mResourceManagerProxy;
 
     Domain mDomain;
     AString mLogSessionId;
diff --git a/media/libstagefright/include/media/stagefright/RemoteDataSource.h b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
index d605cda..621d772 100644
--- a/media/libstagefright/include/media/stagefright/RemoteDataSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
@@ -106,7 +106,7 @@
         if (mMemory.get() == nullptr) {
             ALOGE("Failed to allocate memory!");
         }
-        mName = String8::format("RemoteDataSource(%s)", mSource->toString().string());
+        mName = String8::format("RemoteDataSource(%s)", mSource->toString().c_str());
     }
 
     DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
diff --git a/media/libstagefright/omx/OMXStore.cpp b/media/libstagefright/omx/OMXStore.cpp
index 0906433..b2d5a70 100644
--- a/media/libstagefright/omx/OMXStore.cpp
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -167,7 +167,7 @@
 
         if (mPluginByComponentName.indexOfKey(name8) >= 0) {
             ALOGE("A component of name '%s' already exists, ignoring this one.",
-                 name8.string());
+                 name8.c_str());
 
             continue;
         }
@@ -263,7 +263,7 @@
     const String8 &name8 = mPluginByComponentName.keyAt(index);
 
     CHECK(size >= 1 + name8.size());
-    strcpy(name, name8.string());
+    strcpy(name, name8.c_str());
 
     return OMX_ErrorNone;
 }
diff --git a/media/libstagefright/omx/OmxGraphicBufferSource.cpp b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
index 33481e3..5d653bc 100644
--- a/media/libstagefright/omx/OmxGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
@@ -85,6 +85,18 @@
         int32_t bufferCount,
         uint32_t frameWidth,
         uint32_t frameHeight,
+        uint32_t consumerUsage) {
+    uint64_t consumerUsage64 = static_cast<uint64_t>(consumerUsage);
+    return configure(omxNode, dataSpace, bufferCount,
+                     frameWidth, frameHeight, consumerUsage64);
+}
+
+status_t OmxGraphicBufferSource::configure(
+        const sp<IOmxNodeWrapper>& omxNode,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
         uint64_t consumerUsage) {
     if (omxNode == NULL) {
         return BAD_VALUE;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index 1c3cb4e..a6e23ed 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -540,11 +540,11 @@
  */
 // convert: IOMX::ComponentInfo -> IOmx::ComponentInfo
 inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) {
-    t->mName = l.mName.string();
+    t->mName = l.mName.c_str();
     t->mRoles.resize(l.mRoles.size());
     size_t i = 0;
     for (auto& role : l.mRoles) {
-        t->mRoles[i++] = role.string();
+        t->mRoles[i++] = role.c_str();
     }
     return true;
 }
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
index a23efac..8b920c1 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
@@ -63,7 +63,19 @@
     // ------------------------------
 
     // Configure the buffer source to be used with an OMX node with the default
-    // data space.
+    // data space.(32-bit consumerUsage flag, for vendor partition
+    // compatibility)
+    [[deprecated("use configure() with a 64-bit consumerUsage flag instead")]]
+    status_t configure(
+        const sp<IOmxNodeWrapper> &omxNode,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
+        uint32_t consumerUsage);
+
+    // Configure the buffer source to be used with an OMX node with the default
+    // data space. (64-bit consumerUsage flag)
     status_t configure(
         const sp<IOmxNodeWrapper> &omxNode,
         int32_t dataSpace,
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 039991c..b9bea1a 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -789,7 +789,7 @@
     for (List<IOMX::ComponentInfo>::iterator it = componentInfos.begin();
          it != componentInfos.end(); ++it) {
         const IOMX::ComponentInfo &info = *it;
-        const char *componentName = info.mName.string();
+        const char *componentName = info.mName.c_str();
 
         if (strncmp(componentName, "OMX.google.", 11)) {
             continue;
@@ -797,7 +797,7 @@
 
         for (List<String8>::const_iterator role_it = info.mRoles.begin();
              role_it != info.mRoles.end(); ++role_it) {
-            const char *componentRole = (*role_it).string();
+            const char *componentRole = (*role_it).c_str();
 
             err = test(componentName, componentRole);
 
diff --git a/media/libstagefright/renderfright/gl/GLExtensions.cpp b/media/libstagefright/renderfright/gl/GLExtensions.cpp
index 2924b0e..4717c68 100644
--- a/media/libstagefright/renderfright/gl/GLExtensions.cpp
+++ b/media/libstagefright/renderfright/gl/GLExtensions.cpp
@@ -68,19 +68,19 @@
 }
 
 char const* GLExtensions::getVendor() const {
-    return mVendor.string();
+    return mVendor.c_str();
 }
 
 char const* GLExtensions::getRenderer() const {
-    return mRenderer.string();
+    return mRenderer.c_str();
 }
 
 char const* GLExtensions::getVersion() const {
-    return mVersion.string();
+    return mVersion.c_str();
 }
 
 char const* GLExtensions::getExtensions() const {
-    return mExtensions.string();
+    return mExtensions.c_str();
 }
 
 void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExtensions) {
@@ -123,11 +123,11 @@
 }
 
 char const* GLExtensions::getEGLVersion() const {
-    return mEGLVersion.string();
+    return mEGLVersion.c_str();
 }
 
 char const* GLExtensions::getEGLExtensions() const {
-    return mEGLExtensions.string();
+    return mEGLExtensions.c_str();
 }
 
 } // namespace gl
diff --git a/media/libstagefright/renderfright/gl/ProgramCache.cpp b/media/libstagefright/renderfright/gl/ProgramCache.cpp
index af55172..350f0b7 100644
--- a/media/libstagefright/renderfright/gl/ProgramCache.cpp
+++ b/media/libstagefright/renderfright/gl/ProgramCache.cpp
@@ -62,7 +62,7 @@
         return out;
     }
     friend inline Formatter& operator<<(Formatter& out, const String8& in) {
-        return operator<<(out, in.string());
+        return operator<<(out, in.c_str());
     }
     friend inline Formatter& operator<<(Formatter& to, FormaterManipFunc func) {
         return (*func)(to);
@@ -778,7 +778,7 @@
     // fragment shader
     String8 fs = generateFragmentShader(needs);
 
-    return std::make_unique<Program>(needs, vs.string(), fs.string());
+    return std::make_unique<Program>(needs, vs.c_str(), fs.c_str());
 }
 
 void ProgramCache::useProgram(EGLContext context, const Description& description) {
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index 100c0cd..fc9f58e 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -203,12 +203,12 @@
                     seqNum, mNextExpectedSeqNo,
                     baseJbTimeMs, dynamicJbTimeMs, tryJbTimeMs, JITTER_MULTIPLE);
         if (isSecondLineBroken) {
-            ALOGE("%s", info.string());
+            ALOGE("%s", info.c_str());
             printNowTimeMs(startTimeMs, nowTimeMs, playedTimeMs);
             printRTPTime(rtpTime, playedTimeRtp, expiredTimeRtp, isExpired);
 
         }  else {
-            ALOGW("%s", info.string());
+            ALOGW("%s", info.c_str());
         }
     }
 
diff --git a/media/libstagefright/rtsp/AHEVCAssembler.cpp b/media/libstagefright/rtsp/AHEVCAssembler.cpp
index 7b5c24a..06f19ab 100644
--- a/media/libstagefright/rtsp/AHEVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AHEVCAssembler.cpp
@@ -213,12 +213,12 @@
                     seqNum, mNextExpectedSeqNo,
                     baseJbTimeMs, dynamicJbTimeMs, tryJbTimeMs, JITTER_MULTIPLE);
         if (isSecondLineBroken) {
-            ALOGE("%s", info.string());
+            ALOGE("%s", info.c_str());
             printNowTimeMs(startTimeMs, nowTimeMs, playedTimeMs);
             printRTPTime(rtpTime, playedTimeRtp, expiredTimeRtp, isExpired);
 
         }  else {
-            ALOGW("%s", info.string());
+            ALOGW("%s", info.c_str());
         }
     }
 
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 41f2d67..41e9aff 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -1647,11 +1647,11 @@
         memset(&mRTCPAddr6, 0, sizeof(mRTCPAddr6));
 
         mLocalAddr6.sin6_family = AF_INET6;
-        inet_pton(AF_INET6, localIp.string(), &mLocalAddr6.sin6_addr);
+        inet_pton(AF_INET6, localIp.c_str(), &mLocalAddr6.sin6_addr);
         mLocalAddr6.sin6_port = htons((uint16_t)localPort);
 
         mRTPAddr6.sin6_family = AF_INET6;
-        inet_pton(AF_INET6, remoteIp.string(), &mRTPAddr6.sin6_addr);
+        inet_pton(AF_INET6, remoteIp.c_str(), &mRTPAddr6.sin6_addr);
         mRTPAddr6.sin6_port = htons((uint16_t)remotePort);
 
         mRTCPAddr6 = mRTPAddr6;
@@ -1662,11 +1662,11 @@
         memset(&mRTCPAddr, 0, sizeof(mRTCPAddr));
 
         mLocalAddr.sin_family = AF_INET;
-        mLocalAddr.sin_addr.s_addr = inet_addr(localIp.string());
+        mLocalAddr.sin_addr.s_addr = inet_addr(localIp.c_str());
         mLocalAddr.sin_port = htons((uint16_t)localPort);
 
         mRTPAddr.sin_family = AF_INET;
-        mRTPAddr.sin_addr.s_addr = inet_addr(remoteIp.string());
+        mRTPAddr.sin_addr.s_addr = inet_addr(remoteIp.c_str());
         mRTPAddr.sin_port = htons((uint16_t)remotePort);
 
         mRTCPAddr = mRTPAddr;
@@ -1679,9 +1679,9 @@
     int sizeSockSt = mIsIPv6 ? sizeof(mLocalAddr6) : sizeof(mLocalAddr);
 
     if (bind(mRTPSocket, localAddr, sizeSockSt) == -1) {
-        ALOGE("failed to bind rtp %s:%d err=%s", localIp.string(), localPort, strerror(errno));
+        ALOGE("failed to bind rtp %s:%d err=%s", localIp.c_str(), localPort, strerror(errno));
     } else {
-        ALOGD("succeed to bind rtp %s:%d", localIp.string(), localPort);
+        ALOGD("succeed to bind rtp %s:%d", localIp.c_str(), localPort);
     }
 
     if (mIsIPv6)
@@ -1690,9 +1690,9 @@
         mLocalAddr.sin_port = htons((uint16_t)(localPort + 1));
 
     if (bind(mRTCPSocket, localAddr, sizeSockSt) == -1) {
-        ALOGE("failed to bind rtcp %s:%d err=%s", localIp.string(), localPort + 1, strerror(errno));
+        ALOGE("failed to bind rtcp %s:%d err=%s", localIp.c_str(), localPort + 1, strerror(errno));
     } else {
-        ALOGD("succeed to bind rtcp %s:%d", localIp.string(), localPort + 1);
+        ALOGD("succeed to bind rtcp %s:%d", localIp.c_str(), localPort + 1);
     }
 }
 
diff --git a/media/module/bqhelper/GraphicBufferSource.cpp b/media/module/bqhelper/GraphicBufferSource.cpp
index 4bb2215..82ddbc0 100644
--- a/media/module/bqhelper/GraphicBufferSource.cpp
+++ b/media/module/bqhelper/GraphicBufferSource.cpp
@@ -1150,6 +1150,18 @@
         int32_t bufferCount,
         uint32_t frameWidth,
         uint32_t frameHeight,
+        uint32_t consumerUsage) {
+    uint64_t consumerUsage64 = static_cast<uint64_t>(consumerUsage);
+    return configure(component, dataSpace, bufferCount,
+                     frameWidth, frameHeight, consumerUsage64);
+}
+
+status_t GraphicBufferSource::configure(
+        const sp<ComponentWrapper>& component,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
         uint64_t consumerUsage) {
     if (component == NULL) {
         return BAD_VALUE;
diff --git a/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
index 4e4fbfd..5225a48 100644
--- a/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
+++ b/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
@@ -122,7 +122,19 @@
     // ------------------------------
 
     // Configure the buffer source to be used with a component with the default
-    // data space.
+    // data space. (32-bit consumerUsage flag, for vendor partition
+    // compatibility)
+    [[deprecated("use configure() with a 64-bit consumerUsage flag instead")]]
+    status_t configure(
+        const sp<ComponentWrapper> &component,
+        int32_t dataSpace,
+        int32_t bufferCount,
+        uint32_t frameWidth,
+        uint32_t frameHeight,
+        uint32_t consumerUsage);
+
+    // Configure the buffer source to be used with a component with the default
+    // data space. (64-bit consumerUsage flag)
     status_t configure(
         const sp<ComponentWrapper> &component,
         int32_t dataSpace,
diff --git a/media/module/codecs/m4v_h263/OWNERS b/media/module/codecs/m4v_h263/OWNERS
new file mode 100644
index 0000000..e537138
--- /dev/null
+++ b/media/module/codecs/m4v_h263/OWNERS
@@ -0,0 +1,4 @@
+# owners for frameworks/av/media/module/codecs/m4v_h263
+include platform/frameworks/av:/media/janitors/avic_OWNERS
+include platform/frameworks/av:/media/janitors/codec_OWNERS
+essick@google.com
diff --git a/media/module/extractors/OWNERS b/media/module/extractors/OWNERS
new file mode 100644
index 0000000..8d39dcb
--- /dev/null
+++ b/media/module/extractors/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 817235
+
+# Exclude /media/OWNERS but include top-level OWNERS
+set noparent
+include platform/frameworks/av:/OWNERS
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/module/extractors/mp3/MP3Extractor.cpp b/media/module/extractors/mp3/MP3Extractor.cpp
index 328b790..d0e9852 100644
--- a/media/module/extractors/mp3/MP3Extractor.cpp
+++ b/media/module/extractors/mp3/MP3Extractor.cpp
@@ -379,8 +379,8 @@
             String8 commentdesc;
             String8 commentvalue;
             com->getString(&commentdesc, &commentvalue);
-            const char * desc = commentdesc.string();
-            const char * value = commentvalue.string();
+            const char * desc = commentdesc.c_str();
+            const char * value = commentvalue.c_str();
 
             // first 3 characters are the language, which we don't care about
             if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) {
@@ -652,7 +652,7 @@
         it->getString(&s);
         delete it;
 
-        AMediaFormat_setString(meta, kMap[i].key, s.string());
+        AMediaFormat_setString(meta, kMap[i].key, s.c_str());
     }
 
     size_t dataSize;
diff --git a/media/module/extractors/mp4/ItemTable.cpp b/media/module/extractors/mp4/ItemTable.cpp
index 444664c..7fe5ba7 100644
--- a/media/module/extractors/mp4/ItemTable.cpp
+++ b/media/module/extractors/mp4/ItemTable.cpp
@@ -1111,7 +1111,7 @@
         }
         buf.push_back(tmp);
         if (tmp == 0) {
-            out->setTo(buf.array());
+            *out = buf.array();
 
             *offset = newOffset;
             *size = stopOffset - newOffset;
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 38cf29d..ecd937d 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -847,7 +847,7 @@
     struct tm* tm = gmtime(&time_1970);
     if (tm != NULL &&
             strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
-        s->setTo(tmp);
+        *s = tmp;
         return true;
     }
     return false;
@@ -1794,7 +1794,7 @@
                 String8 mimeFormat(str + 8 + encoding_length + 1,
                         chunk_data_size - 8 - encoding_length - 1);
                 AMediaFormat_setString(mLastTrack->meta,
-                        AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+                        AMEDIAFORMAT_KEY_MIME, mimeFormat.c_str());
             }
             break;
         }
@@ -2813,7 +2813,7 @@
 
             String8 s;
             if (convertTimeToDate(creationTime, &s)) {
-                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DATE, s.string());
+                AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DATE, s.c_str());
             }
 
             break;
@@ -4082,10 +4082,10 @@
             buffer[size] = '\0';
             switch (mPath[5]) {
                 case FOURCC("mean"):
-                    mLastCommentMean.setTo((const char *)buffer + 4);
+                    mLastCommentMean = ((const char *)buffer + 4);
                     break;
                 case FOURCC("name"):
-                    mLastCommentName.setTo((const char *)buffer + 4);
+                    mLastCommentName = ((const char *)buffer + 4);
                     break;
                 case FOURCC("data"):
                     if (size < 8) {
@@ -4094,7 +4094,7 @@
                         ALOGE("b/24346430");
                         return ERROR_MALFORMED;
                     }
-                    mLastCommentData.setTo((const char *)buffer + 8);
+                    mLastCommentData = ((const char *)buffer + 8);
                     break;
             }
 
@@ -4368,7 +4368,7 @@
         } else {
             // Convert from UTF-16 string to UTF-8 string.
             String8 tmpUTF8str(framedata, len16);
-            AMediaFormat_setString(mFileMetaData, metadataKey, tmpUTF8str.string());
+            AMediaFormat_setString(mFileMetaData, metadataKey, tmpUTF8str.c_str());
         }
     }
 
diff --git a/media/module/foundation/ALooperRoster.cpp b/media/module/foundation/ALooperRoster.cpp
index 5625c7f..daa90be 100644
--- a/media/module/foundation/ALooperRoster.cpp
+++ b/media/module/foundation/ALooperRoster.cpp
@@ -180,7 +180,7 @@
         }
         s.append("\n");
     }
-    (void)write(fd, s.string(), s.size());
+    (void)write(fd, s.c_str(), s.size());
 }
 
 }  // namespace android
diff --git a/media/module/foundation/AString.cpp b/media/module/foundation/AString.cpp
index a5e0ff8..2f8011d 100644
--- a/media/module/foundation/AString.cpp
+++ b/media/module/foundation/AString.cpp
@@ -70,7 +70,7 @@
     : mData(NULL),
       mSize(0),
       mAllocSize(1) {
-    setTo(from.string(), from.length());
+    setTo(from.c_str(), from.length());
 }
 
 AString::AString(const AString &from)
diff --git a/media/module/foundation/MetaDataBase.cpp b/media/module/foundation/MetaDataBase.cpp
index 3370748..da383fa 100644
--- a/media/module/foundation/MetaDataBase.cpp
+++ b/media/module/foundation/MetaDataBase.cpp
@@ -434,7 +434,7 @@
         char cc[5];
         MakeFourCCString(key, cc);
         const typed_data &item = mInternalData->mItems.valueAt(i);
-        s.appendFormat("%s: %s", cc, item.asString(false).string());
+        s.appendFormat("%s: %s", cc, item.asString(false).c_str());
         if (i != 0) {
             s.append(", ");
         }
@@ -448,7 +448,7 @@
         char cc[5];
         MakeFourCCString(key, cc);
         const typed_data &item = mInternalData->mItems.valueAt(i);
-        ALOGI("%s: %s", cc, item.asString(true /* verbose */).string());
+        ALOGI("%s: %s", cc, item.asString(true /* verbose */).c_str());
     }
 }
 
diff --git a/media/module/foundation/tests/Base64_test.cpp b/media/module/foundation/tests/Base64_test.cpp
index 7a4289e..a3f93d9 100644
--- a/media/module/foundation/tests/Base64_test.cpp
+++ b/media/module/foundation/tests/Base64_test.cpp
@@ -49,7 +49,7 @@
                 paddedText.append(kBase64Padding);
             }
         }
-        sp<ABuffer> result = decodeBase64(AString(paddedText.string()));
+        sp<ABuffer> result = decodeBase64(AString(paddedText.c_str()));
 
         ASSERT_EQ(AStringUtils::Compare(expected[i].c_str(),
                 reinterpret_cast<char*>(result->data()),
diff --git a/media/module/id3/ID3.cpp b/media/module/id3/ID3.cpp
index 1f3cad9..aaaeeaf 100644
--- a/media/module/id3/ID3.cpp
+++ b/media/module/id3/ID3.cpp
@@ -535,40 +535,40 @@
 }
 
 void ID3::Iterator::getID(String8 *id) const {
-    id->setTo("");
+    *id = "";
 
     if (mFrameData == NULL) {
         return;
     }
 
     if (mParent.mVersion == ID3_V2_2) {
-        id->setTo((const char *)&mParent.mData[mOffset], 3);
+        *id = String8((const char *)&mParent.mData[mOffset], 3);
     } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) {
-        id->setTo((const char *)&mParent.mData[mOffset], 4);
+        *id = String8((const char *)&mParent.mData[mOffset], 4);
     } else {
         CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1);
 
         switch (mOffset) {
             case 3:
-                id->setTo("TT2");
+                *id = "TT2";
                 break;
             case 33:
-                id->setTo("TP1");
+                *id = "TP1";
                 break;
             case 63:
-                id->setTo("TAL");
+                *id = "TAL";
                 break;
             case 93:
-                id->setTo("TYE");
+                *id = "TYE";
                 break;
             case 97:
-                id->setTo("COM");
+                *id = "COM";
                 break;
             case 126:
-                id->setTo("TRK");
+                *id = "TRK";
                 break;
             case 127:
-                id->setTo("TCO");
+                *id = "TCO";
                 break;
             default:
                 CHECK(!"should not be here.");
@@ -590,7 +590,7 @@
 // followed by more data. The data following the \0 can be retrieved by setting
 // "otherdata" to true.
 void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
-    id->setTo("");
+    *id = "";
 
     const uint8_t *frameData = mFrameData;
     if (frameData == NULL) {
@@ -605,13 +605,13 @@
             char tmp[16];
             snprintf(tmp, sizeof(tmp), "%d", (int)*frameData);
 
-            id->setTo(tmp);
+            *id = tmp;
             return;
         }
 
         // this is supposed to be ISO-8859-1, but pass it up as-is to the caller, who will figure
         // out the real encoding
-        id->setTo((const char*)frameData, mFrameSize);
+        *id = String8((const char*)frameData, mFrameSize);
         return;
     }
 
@@ -640,10 +640,10 @@
 
     if (encoding == 0x00) {
         // supposedly ISO 8859-1
-        id->setTo((const char*)frameData + 1, n);
+        *id = String8((const char*)frameData + 1, n);
     } else if (encoding == 0x03) {
         // supposedly UTF-8
-        id->setTo((const char *)(frameData + 1), n);
+        *id = String8((const char *)(frameData + 1), n);
     } else if (encoding == 0x02) {
         // supposedly UTF-16 BE, no byte order mark.
         // API wants number of characters, not number of bytes...
@@ -662,7 +662,7 @@
             framedata = framedatacopy;
         }
 #endif
-        id->setTo(framedata, len);
+        *id = String8(framedata, len);
         if (framedatacopy != NULL) {
             delete[] framedatacopy;
         }
@@ -715,13 +715,13 @@
                 for (int i = 0; i < len; i++) {
                     frame8[i] = framedata[i];
                 }
-                id->setTo(frame8, len);
+                *id = String8(frame8, len);
                 delete [] frame8;
             } else {
-                id->setTo(framedata, len);
+                *id = String8(framedata, len);
             }
         } else {
-            id->setTo(framedata, len);
+            *id = String8(framedata, len);
         }
 
         if (framedatacopy != NULL) {
@@ -948,7 +948,7 @@
 const void *
 ID3::getAlbumArt(size_t *length, String8 *mime) const {
     *length = 0;
-    mime->setTo("");
+    *mime = "";
 
     Iterator it(
             *this,
@@ -971,7 +971,7 @@
                 ALOGW("bogus album art size: mime");
                 return NULL;
             }
-            mime->setTo((const char *)&data[consumed]);
+            *mime = (const char *)&data[consumed];
             consumed += mimeLen;
 
 #if 0
@@ -1008,11 +1008,11 @@
             }
 
             if (!memcmp(&data[1], "PNG", 3)) {
-                mime->setTo("image/png");
+                *mime = "image/png";
             } else if (!memcmp(&data[1], "JPG", 3)) {
-                mime->setTo("image/jpeg");
+                *mime = "image/jpeg";
             } else if (!memcmp(&data[1], "-->", 3)) {
-                mime->setTo("text/plain");
+                *mime = "text/plain";
             } else {
                 return NULL;
             }
diff --git a/media/module/id3/test/ID3Test.cpp b/media/module/id3/test/ID3Test.cpp
index a0a84ec..9da28d2 100644
--- a/media/module/id3/test/ID3Test.cpp
+++ b/media/module/id3/test/ID3Test.cpp
@@ -94,7 +94,7 @@
                 String8 text;
                 countTextFrames++;
                 it.getString(&text);
-                ALOGV("Found text frame %s : %s \n", id.string(), text.string());
+                ALOGV("Found text frame %s : %s \n", id.c_str(), text.c_str());
             }
             it.next();
         }
@@ -106,10 +106,10 @@
             ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
             it.getString(&text);
             // if the tag has a value
-            if (strcmp(text.string(), "")) {
+            if (strcmp(text.c_str(), "")) {
                 countTextFrames++;
                 ALOGV("ID: %s\n", id.c_str());
-                ALOGV("Text string: %s\n", text.string());
+                ALOGV("Text string: %s\n", text.c_str());
             }
             it.next();
         }
@@ -134,7 +134,7 @@
 
     if (albumArtPresent) {
         if (data) {
-            ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
+            ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.c_str());
         }
         ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
     } else {
@@ -168,7 +168,7 @@
             String8 mime;
             const void *data = tag.getAlbumArt(&dataSize, &mime);
             if (data) {
-                ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
+                ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.c_str());
 #if (LOG_NDEBUG == 0)
                 hexdump(data, dataSize > 128 ? 128 : dataSize);
 #endif
diff --git a/media/module/id3/testid3.cpp b/media/module/id3/testid3.cpp
index 5cd51cf..e4f524b 100644
--- a/media/module/id3/testid3.cpp
+++ b/media/module/id3/testid3.cpp
@@ -90,9 +90,9 @@
                 String8 text;
                 it.getString(&text);
 
-                printf("  found text frame '%s': %s\n", id.string(), text.string());
+                printf("  found text frame '%s': %s\n", id.c_str(), text.c_str());
             } else {
-                printf("  found frame '%s'.\n", id.string());
+                printf("  found frame '%s'.\n", id.c_str());
             }
 
             it.next();
@@ -104,7 +104,7 @@
 
         if (data) {
             printf("found album art: size=%zu mime='%s'\n", dataSize,
-                   mime.string());
+                   mime.c_str());
 
             hexdump(data, dataSize > 128 ? 128 : dataSize);
         }
diff --git a/media/module/libmediatranscoding/TranscodingClientManager.cpp b/media/module/libmediatranscoding/TranscodingClientManager.cpp
index 6dbcaf9..18702a4 100644
--- a/media/module/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/module/libmediatranscoding/TranscodingClientManager.cpp
@@ -354,7 +354,7 @@
         result.append(buffer);
     }
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 bool TranscodingClientManager::isTrustedCaller(pid_t pid, uid_t uid) {
diff --git a/media/module/libmediatranscoding/TranscodingSessionController.cpp b/media/module/libmediatranscoding/TranscodingSessionController.cpp
index ea3e518..e9d19d3 100644
--- a/media/module/libmediatranscoding/TranscodingSessionController.cpp
+++ b/media/module/libmediatranscoding/TranscodingSessionController.cpp
@@ -421,7 +421,7 @@
         dumpSession_l(session, result, true /*closedSession*/);
     }
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 /*
diff --git a/media/module/service.mediatranscoding/MediaTranscodingService.cpp b/media/module/service.mediatranscoding/MediaTranscodingService.cpp
index 2a20981..2c73f3e 100644
--- a/media/module/service.mediatranscoding/MediaTranscodingService.cpp
+++ b/media/module/service.mediatranscoding/MediaTranscodingService.cpp
@@ -110,7 +110,7 @@
                     "Permission Denial: "
                     "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
                     AIBinder_getCallingPid(), AIBinder_getCallingUid());
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
             return PERMISSION_DENIED;
         }
     }
@@ -120,7 +120,7 @@
 
     snprintf(buffer, SIZE, "MediaTranscodingService: %p\n", this);
     result.append(buffer);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     Vector<String16> args;
     mClientManager->dumpAllClients(fd, args);
diff --git a/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
index 8e17f55..723bd77 100644
--- a/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
+++ b/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
@@ -76,7 +76,7 @@
     PermissionController pc;
     uid = pc.getPackageUid(packageName, 0);
     if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(packageName).string());
+        ALOGE("Unknown package: '%s'", String8(packageName).c_str());
         return BAD_VALUE;
     }
 
diff --git a/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
index f5faf77..83c6076 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
@@ -212,7 +212,7 @@
                     if (mFdp.ConsumeBool()) {
                         std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
                         android::String16 s(str.c_str());
-                        char16_t* data = const_cast<char16_t*>(s.string());
+                        char16_t* data = const_cast<char16_t*>(s.c_str());
                         mtpDataPacket.putString(reinterpret_cast<uint16_t*>(data));
                     } else {
                         mtpDataPacket.putString(static_cast<uint16_t*>(nullptr));
diff --git a/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
index b4e659c..6300256 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
@@ -101,7 +101,7 @@
                     std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
                     android::String16 s(str.c_str());
                     if (mFdp.ConsumeBool()) {
-                        data = const_cast<char16_t*>(s.string());
+                        data = const_cast<char16_t*>(s.c_str());
                     }
 
                     if (mFdp.ConsumeBool()) {
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index fded4f5..8b9dde3 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -161,11 +161,6 @@
         "libgui",
     ],
 
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-    },
     version_script: "libmediandk.map.txt",
     stubs: {
         symbol_file: "libmediandk.map.txt",
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 067c8f4..caee37d 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -344,7 +344,7 @@
     }
 
     mCbLooper = new ALooper;
-    mCbLooper->setName(consumerName.string());
+    mCbLooper->setName(consumerName.c_str());
     res = mCbLooper->start(
             /*runOnCallingThread*/false,
             /*canCallJava*/       true,
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 0df7636..28a0233 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -478,7 +478,7 @@
         *keyRequest = mObj->mKeyRequest.array();
         *keyRequestSize = mObj->mKeyRequest.size();
         if (defaultUrl != NULL)
-            *defaultUrl = mObj->mDefaultUrl.string();
+            *defaultUrl = mObj->mDefaultUrl.c_str();
         switch(requestType) {
             case DrmPlugin::kKeyRequestType_Initial:
                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_INITIAL;
@@ -606,8 +606,8 @@
     }
 
     for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
-        keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
-        keyValuePairs[i].mValue = mObj->mQueryResults.valueAt(i).string();
+        keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).c_str();
+        keyValuePairs[i].mValue = mObj->mQueryResults.valueAt(i).c_str();
     }
     *numPairs = mObj->mQueryResults.size();
     return AMEDIA_OK;
@@ -630,7 +630,7 @@
     } else {
         *provisionRequest = mObj->mProvisionRequest.array();
         *provisionRequestSize = mObj->mProvisionRequest.size();
-        *serverUrl = mObj->mProvisionUrl.string();
+        *serverUrl = mObj->mProvisionUrl.c_str();
     }
     return AMEDIA_OK;
 }
@@ -714,7 +714,7 @@
             mObj->mPropertyString);
 
     if (status == OK) {
-        *propertyValue = mObj->mPropertyString.string();
+        *propertyValue = mObj->mPropertyString.c_str();
     } else {
         *propertyValue = NULL;
     }
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 66b5dec..161b5e3 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -142,7 +142,7 @@
     }
     ret.append("}");
     mData->mDebug = ret;
-    return mData->mDebug.string();
+    return mData->mDebug.c_str();
 }
 
 EXPORT
@@ -238,7 +238,7 @@
         return false;
     }
     for (size_t i = 0; i < mData->mStringCache.size(); i++) {
-        if (strcmp(mData->mStringCache.keyAt(i).string(), name) == 0) {
+        if (strcmp(mData->mStringCache.keyAt(i).c_str(), name) == 0) {
             mData->mStringCache.removeItemsAt(i, 1);
             break;
         }
@@ -251,7 +251,7 @@
         if (i < 0) {
             return false;
         }
-        *out = mData->mStringCache.valueAt(i).string();
+        *out = mData->mStringCache.valueAt(i).c_str();
         return true;
     }
     return false;
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 83b84e3..eef460f 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -403,7 +403,7 @@
     PermissionController{}.getPackagesForUid(uid, str16PackageNames);
     std::vector<std::string> packageNames;
     for (const auto& str16PackageName : str16PackageNames) {
-        packageNames.emplace_back(String8(str16PackageName).string());
+        packageNames.emplace_back(String8(str16PackageName).c_str());
     }
     if (packageNames.empty()) {
         ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 60717b5..18ab3a7 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -818,7 +818,7 @@
         result.appendFormat("  %7d %4d %7d %6u  %s\n", r->mSessionid, r->mCnt, r->mPid,
                 r->mUid, info.package.c_str());
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 
@@ -834,7 +834,7 @@
                             hardwareStatus,
                             (uint32_t)(mStandbyTimeInNsecs / 1000000));
     result.append(buffer);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     dprintf(fd, "Vibrator infos(size=%zu):\n", mAudioVibratorInfos.size());
     for (const auto& vibratorInfo : mAudioVibratorInfos) {
@@ -854,7 +854,7 @@
             IPCThreadState::self()->getCallingPid(),
             IPCThreadState::self()->getCallingUid());
     result.append(buffer);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 bool AudioFlinger::dumpTryLock(Mutex& mutex)
@@ -873,7 +873,7 @@
         bool hardwareLocked = dumpTryLock(mHardwareLock);
         if (!hardwareLocked) {
             String8 result(kHardwareLockedString);
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         } else {
             mHardwareLock.unlock();
         }
@@ -883,20 +883,20 @@
         // failed to lock - AudioFlinger is probably deadlocked
         if (!locked) {
             String8 result(kDeadlockedString);
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         }
 
         bool clientLocked = dumpTryLock(mClientLock);
         if (!clientLocked) {
             String8 result(kClientLockedString);
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         }
 
         if (mEffectsFactoryHal != 0) {
             mEffectsFactoryHal->dumpEffects(fd);
         } else {
             String8 result(kNoEffectsFactory);
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         }
 
         dumpClients(fd, args);
@@ -1907,7 +1907,7 @@
 status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
 {
     ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d calling uid %d",
-            ioHandle, keyValuePairs.string(),
+            ioHandle, keyValuePairs.c_str(),
             IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
 
     // check calling permissions
@@ -1918,7 +1918,7 @@
     String8 filteredKeyValuePairs = keyValuePairs;
     filterReservedParameters(filteredKeyValuePairs, IPCThreadState::self()->getCallingUid());
 
-    ALOGV("%s: filtered keyvalue %s", __func__, filteredKeyValuePairs.string());
+    ALOGV("%s: filtered keyvalue %s", __func__, filteredKeyValuePairs.c_str());
 
     // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
@@ -1993,7 +1993,7 @@
 String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
 {
     ALOGVV("getParameters() io %d, keys %s, calling pid %d",
-            ioHandle, keys.string(), IPCThreadState::self()->getCallingPid());
+            ioHandle, keys.c_str(), IPCThreadState::self()->getCallingPid());
 
     Mutex::Autolock _l(mLock);
 
@@ -3030,7 +3030,7 @@
             deviceType,
             flags,
             halConfig,
-            address.string());
+            address.c_str());
 
     mHardwareStatus = AUDIO_HW_IDLE;
 
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 4fb6138..f996157 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -155,16 +155,16 @@
     const bool locked = dumpTryLock(mLock);
     if (!locked) {
         String8 result("DeviceEffectManager may be deadlocked\n");
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
 
     String8 heading("\nDevice Effects:\n");
-    write(fd, heading.string(), heading.size());
+    write(fd, heading.c_str(), heading.size());
     for (const auto& iter : mDeviceEffects) {
         String8 outStr;
         outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
                 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
-        write(fd, outStr.string(), outStr.size());
+        write(fd, outStr.c_str(), outStr.size());
         iter.second->dump(fd, 4);
     }
 
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 822ea93..d1bd276 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -526,7 +526,7 @@
     result.appendFormat("\t\t- apiVersion: %08X\n\t\t- flags: %08X (%s)\n",
             mDescriptor.apiVersion,
             mDescriptor.flags,
-            effectFlagsToString(mDescriptor.flags).string());
+            effectFlagsToString(mDescriptor.flags).c_str());
     result.appendFormat("\t\t- name: %s\n",
             mDescriptor.name);
 
@@ -547,7 +547,7 @@
         mLock.unlock();
     }
 
-    write(fd, result.string(), result.length());
+    write(fd, result.c_str(), result.length());
 }
 
 // ----------------------------------------------------------------------------
@@ -1655,7 +1655,7 @@
             dumpInOutBuffer(false /* isInput */, mOutBuffer).c_str(),
             dumpInOutBuffer(false /* isInput */, mOutConversionBuffer).c_str());
 
-    write(fd, result.string(), result.length());
+    write(fd, result.c_str(), result.length());
 
     if (mEffectInterface != 0) {
         dprintf(fd, "\tEffect ID %d HAL dump:\n", mId);
@@ -2644,7 +2644,7 @@
                 (int)outBufferStr.size(), "Out buffer      ");
         result.appendFormat("\t%s   %s   %d\n",
                 inBufferStr.c_str(), outBufferStr.c_str(), mActiveTrackCnt);
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
 
         for (size_t i = 0; i < numEffects; ++i) {
             sp<EffectModule> effect = mEffects[i];
@@ -2657,7 +2657,7 @@
             mLock.unlock();
         }
     } else {
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
 }
 
@@ -3457,7 +3457,7 @@
     const bool locked = dumpTryLock(mProxyLock);
     if (!locked) {
         String8 result("DeviceEffectProxy may be deadlocked\n");
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
 
     String8 outStr;
@@ -3466,16 +3466,16 @@
     } else {
         outStr.appendFormat("%*sNO HAL Effect\n", spaces, "");
     }
-    write(fd, outStr.string(), outStr.size());
+    write(fd, outStr.c_str(), outStr.size());
     outStr.clear();
 
     outStr.appendFormat("%*sSub Effects:\n", spaces, "");
-    write(fd, outStr.string(), outStr.size());
+    write(fd, outStr.c_str(), outStr.size());
     outStr.clear();
 
     for (const auto& iter : mEffectHandles) {
         outStr.appendFormat("%*sEffect for patch handle %d:\n", spaces + 2, "", iter.first);
-        write(fd, outStr.string(), outStr.size());
+        write(fd, outStr.c_str(), outStr.size());
         outStr.clear();
         sp<EffectBase> effect = iter.second->effect().promote();
         if (effect != nullptr) {
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d0feba5..567d12a 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -920,7 +920,7 @@
             patchPanelDump += "\nPatches:\n";
             headerPrinted = true;
         }
-        patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).string());
+        patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).c_str());
     }
 
     headerPrinted = false;
@@ -938,12 +938,12 @@
             for (const auto& patch : module.second.sw_patches) {
                 moduleDump.appendFormat("%d ", patch);
             }
-            patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.string());
+            patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.c_str());
         }
     }
 
     if (!patchPanelDump.isEmpty()) {
-        write(fd, patchPanelDump.string(), patchPanelDump.size());
+        write(fd, patchPanelDump.c_str(), patchPanelDump.size());
     }
 }
 
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 51bb93b..464940e 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -20,21 +20,25 @@
 #endif
 
 #include <math.h>
+#include <sys/types.h>
 
 // Checks and monitors OP_PLAY_AUDIO
 class OpPlayAudioMonitor : public RefBase {
+    friend class sp<OpPlayAudioMonitor>;
 public:
     ~OpPlayAudioMonitor() override;
     bool hasOpPlayAudio() const;
 
     static sp<OpPlayAudioMonitor> createIfNeeded(
+            AudioFlinger::ThreadBase* thread,
             const AttributionSourceState& attributionSource,
             const audio_attributes_t& attr, int id,
             audio_stream_type_t streamType);
 
 private:
-    OpPlayAudioMonitor(const AttributionSourceState& attributionSource,
-        audio_usage_t usage, int id);
+    OpPlayAudioMonitor(AudioFlinger::ThreadBase* thread,
+                       const AttributionSourceState& attributionSource,
+                       audio_usage_t usage, int id, uid_t uid);
     void onFirstRef() override;
     static void getPackagesForUid(uid_t uid, Vector<String16>& packages);
 
@@ -51,12 +55,15 @@
 
     sp<PlayAudioOpCallback> mOpCallback;
     // called by PlayAudioOpCallback when OP_PLAY_AUDIO is updated in AppOp callback
-    void checkPlayAudioForUsage();
+    void checkPlayAudioForUsage(bool doBroadcast);
 
+    wp<AudioFlinger::ThreadBase> mThread;
     std::atomic_bool mHasOpPlayAudio;
     const AttributionSourceState mAttributionSource;
     const int32_t mUsage; // on purpose not audio_usage_t because always checked in appOps as int32_t
     const int mId; // for logging purposes only
+    const uid_t mUid;
+    const String16 mPackageName;
 };
 
 // playback track
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 95883d9..1f01117 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -490,7 +490,7 @@
                 "  us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n"
                 "  %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f\n"
                 "  MHz: mean=%.1f, stddev=%.1f, min=%.1f max=%.1f",
-                    title.string(),
+                    title.c_str(),
                     elapsed * .000000001, n, perLoop * .000001,
                     mean * .001,
                     stddev * .001,
@@ -616,7 +616,7 @@
 
 status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
 {
-    ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
+    ALOGV("ThreadBase::setParameters() %s", keyValuePairs.c_str());
     Mutex::Autolock _l(mLock);
 
     return sendSetParameterConfigEvent_l(keyValuePairs);
@@ -801,7 +801,7 @@
             if (checkForNewParameter_l(data->mKeyValuePairs, event->mStatus)) {
                 configChanged = true;
                 mLocalLog.log("CFG_EVENT_SET_PARAMETER: (%s) configuration changed",
-                        data->mKeyValuePairs.string());
+                        data->mKeyValuePairs.c_str());
             }
         } break;
         case CFG_EVENT_CREATE_AUDIO_PATCH: {
@@ -988,7 +988,7 @@
     dprintf(fd, "  HAL buffer size: %zu bytes\n", mBufferSize);
     dprintf(fd, "  Channel count: %u\n", mChannelCount);
     dprintf(fd, "  Channel mask: 0x%08x (%s)\n", mChannelMask,
-            channelMaskToString(mChannelMask, mType != RECORD).string());
+            channelMaskToString(mChannelMask, mType != RECORD).c_str());
     dprintf(fd, "  Processing format: 0x%x (%s)\n", mFormat, formatToString(mFormat).c_str());
     dprintf(fd, "  Processing frame size: %zu bytes\n", mFrameSize);
     dprintf(fd, "  Pending config events:");
@@ -1944,7 +1944,7 @@
     if (mLocalLog != nullptr) {
         String8 result;
         track->appendDump(result, false /* active */);
-        mLocalLog->log("AT::%-10s(%p) %s", funcName, track.get(), result.string());
+        mLocalLog->log("AT::%-10s(%p) %s", funcName, track.get(), result.c_str());
     }
 }
 
@@ -2211,7 +2211,7 @@
         }
     }
     result.append("\n");
-    write(fd, result.string(), result.length());
+    write(fd, result.c_str(), result.length());
     result.clear();
 
     // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
@@ -2257,7 +2257,7 @@
         }
     }
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 void AudioFlinger::PlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
@@ -2903,7 +2903,7 @@
 
     String8 result;
     track->appendDump(result, false /* active */);
-    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
+    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.c_str());
 
     mTracks.remove(track);
     {
@@ -4010,9 +4010,9 @@
 
                     releaseWakeLock_l();
                     // wait until we have something to do...
-                    ALOGV("%s going to sleep", myName.string());
+                    ALOGV("%s going to sleep", myName.c_str());
                     mWaitWorkCV.wait(mLock);
-                    ALOGV("%s waking up", myName.string());
+                    ALOGV("%s waking up", myName.c_str());
                     acquireWakeLock_l();
 
                     mMixerStatus = MIXER_IDLE;
@@ -9063,7 +9063,7 @@
 {
     String8 result;
     track->appendDump(result, false /* active */);
-    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
+    mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.c_str());
 
     mTracks.remove(track);
     // need anything related to effects here?
@@ -9142,7 +9142,7 @@
         }
 
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 void AudioFlinger::RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
@@ -10204,9 +10204,9 @@
                 }
 
                 // wait until we have something to do...
-                ALOGV("%s going to sleep", myName.string());
+                ALOGV("%s going to sleep", myName.c_str());
                 mWaitWorkCV.wait(mLock);
-                ALOGV("%s waking up", myName.string());
+                ALOGV("%s waking up", myName.c_str());
 
                 checkSilentMode_l();
 
@@ -10580,7 +10580,7 @@
     } else {
         dprintf(fd, "\n");
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 AudioFlinger::MmapPlaybackThread::MmapPlaybackThread(
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index b2700db..6795a13 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -168,7 +168,7 @@
             mKeyValuePairs(keyValuePairs) {}
 
         virtual  void dump(char *buffer, size_t size) {
-            snprintf(buffer, size, "- KeyValue: %s\n", mKeyValuePairs.string());
+            snprintf(buffer, size, "- KeyValue: %s\n", mKeyValuePairs.c_str());
         }
 
         const String8 mKeyValuePairs;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 00c88bc..30c8240 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -512,11 +512,12 @@
 // static
 sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor>
 AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded(
+            AudioFlinger::ThreadBase* thread,
             const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id,
             audio_stream_type_t streamType)
 {
-    Vector <String16> packages;
-    uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
+    Vector<String16> packages;
+    const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
     getPackagesForUid(uid, packages);
     if (isServiceUid(uid)) {
         if (packages.isEmpty()) {
@@ -538,15 +539,21 @@
             id, attr.flags);
         return nullptr;
     }
-    return new OpPlayAudioMonitor(attributionSource, attr.usage, id);
+    return sp<OpPlayAudioMonitor>::make(thread, attributionSource, attr.usage, id, uid);
 }
 
 AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
-        const AttributionSourceState& attributionSource, audio_usage_t usage, int id)
-        : mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t) usage),
-        mId(id)
-{
-}
+        AudioFlinger::ThreadBase* thread,
+        const AttributionSourceState& attributionSource,
+        audio_usage_t usage, int id, uid_t uid)
+    : mThread(wp<AudioFlinger::ThreadBase>::fromExisting(thread)),
+      mHasOpPlayAudio(true),
+      mAttributionSource(attributionSource),
+      mUsage((int32_t)usage),
+      mId(id),
+      mUid(uid),
+      mPackageName(VALUE_OR_FATAL(aidl2legacy_string_view_String16(
+                  attributionSource.packageName.value_or("")))) {}
 
 AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
 {
@@ -558,13 +565,13 @@
 
 void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef()
 {
-    checkPlayAudioForUsage();
+    // make sure not to broadcast the initial state since it is not needed and could
+    // cause a deadlock since this method can be called with the mThread->mLock held
+    checkPlayAudioForUsage(/*doBroadcast=*/false);
     if (mAttributionSource.packageName.has_value()) {
         mOpCallback = new PlayAudioOpCallback(this);
         mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO,
-            VALUE_OR_FATAL(aidl2legacy_string_view_String16(
-            mAttributionSource.packageName.value_or("")))
-            , mOpCallback);
+                mPackageName, mOpCallback);
     }
 }
 
@@ -575,18 +582,24 @@
 // Note this method is never called (and never to be) for audio server / patch record track
 // - not called from constructor due to check on UID,
 // - not called from PlayAudioOpCallback because the callback is not installed in this case
-void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage()
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage(bool doBroadcast)
 {
-    if (!mAttributionSource.packageName.has_value()) {
-        mHasOpPlayAudio.store(false);
-    } else {
-        uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAttributionSource.uid));
-        String16 packageName = VALUE_OR_FATAL(
-            aidl2legacy_string_view_String16(mAttributionSource.packageName.value_or("")));
-        bool hasIt = mAppOpsManager.checkAudioOpNoThrow(AppOpsManager::OP_PLAY_AUDIO,
-                    mUsage, uid, packageName) == AppOpsManager::MODE_ALLOWED;
-        ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasIt ? "not " : "");
-        mHasOpPlayAudio.store(hasIt);
+    const bool hasAppOps = mAttributionSource.packageName.has_value()
+        && mAppOpsManager.checkAudioOpNoThrow(
+                AppOpsManager::OP_PLAY_AUDIO, mUsage, mUid, mPackageName) ==
+                        AppOpsManager::MODE_ALLOWED;
+
+    bool shouldChange = !hasAppOps;  // check if we need to update.
+    if (mHasOpPlayAudio.compare_exchange_strong(shouldChange, hasAppOps)) {
+        ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasAppOps ? "not " : "");
+        if (doBroadcast) {
+            auto thread = mThread.promote();
+            if (thread != nullptr && thread->type() == AudioFlinger::ThreadBase::OFFLOAD) {
+                // Wake up Thread if offloaded, otherwise it may be several seconds for update.
+                Mutex::Autolock _l(thread->mLock);
+                thread->broadcast_l();
+            }
+        }
     }
 }
 
@@ -603,7 +616,7 @@
     }
     sp<OpPlayAudioMonitor> monitor = mMonitor.promote();
     if (monitor != NULL) {
-        monitor->checkPlayAudioForUsage();
+        monitor->checkPlayAudioForUsage(/*doBroadcast=*/true);
     }
 }
 
@@ -664,7 +677,7 @@
     mAuxEffectId(0), mHasVolumeController(false),
     mFrameMap(16 /* sink-frame-to-track-frame map memory */),
     mVolumeHandler(new media::VolumeHandler(sampleRate)),
-    mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(attributionSource, attr, id(),
+    mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(thread, attributionSource, attr, id(),
         streamType)),
     // mSinkTimestamp
     mFastIndex(-1),
@@ -2292,7 +2305,8 @@
               buffer, bufferSize, nullptr /* sharedBuffer */,
               AUDIO_SESSION_NONE, getpid(), audioServerAttributionSource(getpid()), flags,
               TYPE_PATCH, AUDIO_PORT_HANDLE_NONE, frameCountToBeReady),
-        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true),
+        PatchTrackBase(mCblk ? new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)
+                        : nullptr,
                        *playbackThread, timeout)
 {
     ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
@@ -2872,7 +2886,8 @@
                 sampleRate, format, channelMask, frameCount,
                 buffer, bufferSize, AUDIO_SESSION_NONE, getpid(),
                 audioServerAttributionSource(getpid()), flags, TYPE_PATCH),
-        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true),
+        PatchTrackBase(mCblk ? new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true)
+                        : nullptr,
                        *recordThread, timeout)
 {
     ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
diff --git a/services/audioflinger/timing/tests/mediasyncevent_tests.cpp b/services/audioflinger/timing/tests/mediasyncevent_tests.cpp
index 2922d90..8a6cf68 100644
--- a/services/audioflinger/timing/tests/mediasyncevent_tests.cpp
+++ b/services/audioflinger/timing/tests/mediasyncevent_tests.cpp
@@ -25,7 +25,8 @@
 using namespace android::audioflinger;
 
 namespace {
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
 TEST(MediaSyncEventTests, Basic) {
     struct Cookie : public RefBase {};
 
@@ -66,5 +67,5 @@
     syncEvent->cancel();
     ASSERT_TRUE(syncEvent->isCancelled());
 }
-
+#pragma clang diagnostic pop
 } // namespace
diff --git a/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp b/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp
index ee5d269..e9e1edf 100644
--- a/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp
+++ b/services/audioflinger/timing/tests/synchronizedrecordstate_tests.cpp
@@ -26,6 +26,8 @@
 
 namespace {
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
 TEST(SynchronizedRecordStateTests, Basic) {
     struct Cookie : public RefBase {};
 
@@ -73,5 +75,5 @@
     ASSERT_FALSE(triggered);
     ASSERT_TRUE(syncEvent->isCancelled());
 }
-
+#pragma clang diagnostic pop
 }
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index e994758..cf20260 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -43,7 +43,7 @@
     HwModule(const char *name, uint32_t halVersion = 0);
     ~HwModule();
 
-    const char *getName() const { return mName.string(); }
+    const char *getName() const { return mName.c_str(); }
 
     const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; }
     void setDeclaredDevices(const DeviceVector &devices);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
index e214ae9..8c7a7de 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -89,7 +89,12 @@
         if (aidlPort.ext.getTag() == AudioPortExt::mix) {
             auto mixPort = sp<IOProfile>::make("", AUDIO_PORT_ROLE_NONE);
             RETURN_STATUS_IF_ERROR(mixPort->readFromParcelable(fwPort));
-            sortAudioProfiles(mixPort->getAudioProfiles());
+            auto& profiles = mixPort->getAudioProfiles();
+            if (profiles.empty()) {
+                profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
+            } else {
+                sortAudioProfiles(mixPort->getAudioProfiles());
+            }
             mixPorts.add(mixPort);
             ports.emplace(aidlPort.id, mixPort);
         } else if (aidlPort.ext.getTag() == AudioPortExt::device) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 6b9757d..b41f86d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -138,7 +138,7 @@
 
     dst->appendFormat("%*s- device type: %s\n", spaces, "", toString(mDeviceType).c_str());
 
-    dst->appendFormat("%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
+    dst->appendFormat("%*s- device address: %s\n", spaces, "", mDeviceAddress.c_str());
 
     dst->appendFormat("%*s- output: %d\n", spaces, "",
             mOutput == nullptr ? 0 : mOutput->mIoHandle);
@@ -186,7 +186,7 @@
                 && mix.mDeviceAddress.compare(registeredMix->mDeviceAddress) == 0
                 && is_mix_loopback(mix.mRouteFlags)) {
             ALOGE("registerMix(): mix already registered for dev=0x%x addr=%s",
-                    mix.mDeviceType, mix.mDeviceAddress.string());
+                    mix.mDeviceType, mix.mDeviceAddress.c_str());
             return BAD_VALUE;
         }
     }
@@ -198,7 +198,7 @@
     sp<AudioPolicyMix> policyMix = sp<AudioPolicyMix>::make(mix);
     add(policyMix);
     ALOGD("registerMix(): adding mix for dev=0x%x addr=%s",
-            policyMix->mDeviceType, policyMix->mDeviceAddress.string());
+            policyMix->mDeviceType, policyMix->mDeviceAddress.c_str());
 
     if (desc != nullptr) {
         desc->mPolicyMix = policyMix;
@@ -214,14 +214,14 @@
         if (mix.mDeviceType == registeredMix->mDeviceType
                 && mix.mDeviceAddress.compare(registeredMix->mDeviceAddress) == 0) {
             ALOGD("unregisterMix(): removing mix for dev=0x%x addr=%s",
-                    mix.mDeviceType, mix.mDeviceAddress.string());
+                    mix.mDeviceType, mix.mDeviceAddress.c_str());
             removeAt(i);
             return NO_ERROR;
         }
     }
 
     ALOGE("unregisterMix(): mix not registered for dev=0x%x addr=%s",
-            mix.mDeviceType, mix.mDeviceAddress.string());
+            mix.mDeviceType, mix.mDeviceAddress.c_str());
     return BAD_VALUE;
 }
 
@@ -229,20 +229,20 @@
         const String8& address, sp<AudioPolicyMix> &policyMix) const
 {
 
-    ALOGV("getAudioPolicyMix() for dev=0x%x addr=%s", deviceType, address.string());
+    ALOGV("getAudioPolicyMix() for dev=0x%x addr=%s", deviceType, address.c_str());
     for (ssize_t i = 0; i < size(); i++) {
         // Workaround: when an in audio policy is registered, it opens an output
         // that tries to find the audio policy, thus the device must be ignored.
         if (itemAt(i)->mDeviceAddress.compare(address) == 0) {
             policyMix = itemAt(i);
             ALOGV("getAudioPolicyMix: found mix %zu match (devType=0x%x addr=%s)",
-                    i, deviceType, address.string());
+                    i, deviceType, address.c_str());
             return NO_ERROR;
         }
     }
 
     ALOGE("getAudioPolicyMix(): mix not registered for dev=0x%x addr=%s",
-            deviceType, address.string());
+            deviceType, address.c_str());
     return BAD_VALUE;
 }
 
@@ -449,7 +449,7 @@
             address->c_str(), attr.source);
     for (size_t i = 0; i < size(); i++) {
         const sp<AudioPolicyMix> audioPolicyMix = itemAt(i);
-        ALOGV("\tmix %zu address=%s", i, audioPolicyMix->mDeviceAddress.string());
+        ALOGV("\tmix %zu address=%s", i, audioPolicyMix->mDeviceAddress.c_str());
     }
 #endif
 
@@ -458,7 +458,7 @@
         const sp<AudioPolicyMix>& registeredMix = itemAt(index);
         if (address->compare(registeredMix->mDeviceAddress.c_str()) == 0) {
             ALOGD("getInputMixForAttr found addr=%s dev=0x%x",
-                    registeredMix->mDeviceAddress.string(), registeredMix->mDeviceType);
+                    registeredMix->mDeviceAddress.c_str(), registeredMix->mDeviceType);
             break;
         }
     }
@@ -507,7 +507,7 @@
         }
         // check if this mix goes to a device in the list of devices
         bool deviceMatch = false;
-        const AudioDeviceTypeAddr mixDevice(mix->mDeviceType, mix->mDeviceAddress.string());
+        const AudioDeviceTypeAddr mixDevice(mix->mDeviceType, mix->mDeviceAddress.c_str());
         for (size_t j = 0; j < devices.size(); j++) {
             if (mixDevice.equals(devices[j])) {
                 deviceMatch = true;
@@ -563,7 +563,7 @@
             }
         }
         if (ruleAllowsUid) {
-            devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.string()));
+            devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.c_str()));
         }
     }
     return NO_ERROR;
@@ -598,7 +598,7 @@
         }
         // check if this mix goes to a device in the list of devices
         bool deviceMatch = false;
-        const AudioDeviceTypeAddr mixDevice(mix->mDeviceType, mix->mDeviceAddress.string());
+        const AudioDeviceTypeAddr mixDevice(mix->mDeviceType, mix->mDeviceAddress.c_str());
         for (size_t j = 0; j < devices.size(); j++) {
             if (mixDevice.equals(devices[j])) {
                 deviceMatch = true;
@@ -660,7 +660,7 @@
             }
         }
         if (ruleAllowsUserId) {
-            devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.string()));
+            devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.c_str()));
         }
     }
     return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index a909331..62e5bd4 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -185,7 +185,7 @@
     }
 
     std::string descBaseDumpStr;
-    DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, extraInfo.string(), verbose);
+    DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, extraInfo.c_str(), verbose);
     dst->append(descBaseDumpStr.c_str());
 }
 
@@ -325,7 +325,7 @@
         }
     }
     ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
-            __func__, type, address.string(), device.get(), format);
+            __func__, type, address.c_str(), device.get(), format);
     return device;
 }
 
@@ -448,7 +448,7 @@
     if (isEmpty()) {
         return;
     }
-    dst->appendFormat("%*s%s devices (%zu):\n", spaces, "", tag.string(), size());
+    dst->appendFormat("%*s%s devices (%zu):\n", spaces, "", tag.c_str(), size());
     for (size_t i = 0; i < size(); i++) {
         const std::string prefix = base::StringPrintf("%*s %zu. ", spaces, "", i + 1);
         dst->appendFormat("%s", prefix.c_str());
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 5f14ee4..2c8e50b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -67,7 +67,7 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc =
-            new DeviceDescriptor(device, getTagForDevice(device), address.string());
+            new DeviceDescriptor(device, getTagForDevice(device), address.c_str());
     addDynamicDevice(devDesc);
     // Reciprocally attach the device to the module
     devDesc->attach(this);
@@ -135,7 +135,7 @@
                                               config->sample_rate));
 
     sp<DeviceDescriptor> devDesc =
-            new DeviceDescriptor(device, getTagForDevice(device), address.string());
+            new DeviceDescriptor(device, getTagForDevice(device), address.c_str());
     addDynamicDevice(devDesc);
     // Reciprocally attach the device to the module
     devDesc->attach(this);
@@ -375,7 +375,7 @@
             if (allowToCreate) {
                 moduleDevice->attach(hwModule);
                 // Name may be overwritten, restored on detach.
-                moduleDevice->setAddress(devAddress.string());
+                moduleDevice->setAddress(devAddress.c_str());
                 // Name may be overwritten, restored on detach.
                 moduleDevice->setName(name);
             }
@@ -383,8 +383,8 @@
         }
     }
     if (!allowToCreate) {
-        ALOGV("%s: could not find HW module for device %s %04x address %s", __FUNCTION__,
-              name, deviceType, address);
+        ALOGW("%s: could not find HW module for device %s (%s, %08x) address %s", __FUNCTION__,
+                name, audio_device_to_string(deviceType), deviceType, address);
         return nullptr;
     }
     return createDevice(deviceType, address, name, encodedFormat);
@@ -398,8 +398,14 @@
     std::string tagName = {};
     sp<HwModule> hwModule = getModuleForDeviceType(type, encodedFormat, &tagName);
     if (hwModule == 0) {
-        ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
-              address);
+        if (encodedFormat == AUDIO_FORMAT_DEFAULT) {
+            ALOGE("%s: could not find HW module for device type '%s' (%08x)",
+                    __FUNCTION__, audio_device_to_string(type), type);
+        } else {
+            ALOGE("%s: could not find HW module for device type '%s' (%08x), "
+                    "encoded format '%s'", __FUNCTION__, audio_device_to_string(type), type,
+                    audio_format_to_string(encodedFormat));
+        }
         return nullptr;
     }
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp
index bc72484..7d2d293 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp
@@ -55,6 +55,7 @@
 //
 prebuilt_etc {
     name: "parameter-framework.policy",
+    enabled: false, // TODO: This module depends on domaingeneratorpolicyrule_gen, which fails to build
     filename_from_src: true,
     vendor: true,
     src: ":domaingeneratorpolicyrule_gen",
@@ -68,6 +69,7 @@
 }
 genrule {
     name: "domaingeneratorpolicyrule_gen",
+    enabled: false, // TODO: This module fails to build
     defaults: ["domaingeneratorpolicyrule"],
     srcs: [
         ":audio_policy_pfw_toplevel",
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp
index 11da8c7..f825e5f 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp
@@ -56,6 +56,7 @@
 //
 prebuilt_etc {
     name: "parameter-framework.policy",
+    enabled: false, // TODO: This module depends on domaingeneratorpolicyrule_gen, which fails to build
     filename_from_src: true,
     vendor: true,
     src: ":domaingeneratorpolicyrule_gen",
@@ -69,6 +70,7 @@
 }
 genrule {
     name: "domaingeneratorpolicyrule_gen",
+    enabled: false, // TODO: This module fails to build
     defaults: ["domaingeneratorpolicyrule"],
     srcs: [
         ":audio_policy_pfw_toplevel",
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp
index 91ffeb5..4a83cbc 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp
@@ -55,6 +55,7 @@
 //
 prebuilt_etc {
     name: "parameter-framework.policy",
+    enabled: false, // TODO: This module depends on domaingeneratorpolicyrule_gen, which fails to build
     filename_from_src: true,
     vendor: true,
     src: ":domaingeneratorpolicyrule_gen",
@@ -68,6 +69,7 @@
 }
 genrule {
     name: "domaingeneratorpolicyrule_gen",
+    enabled: false, // TODO: This module fails to build
     defaults: ["domaingeneratorpolicyrule"],
     srcs: [
         ":audio_policy_pfw_toplevel",
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp
index cac63fc..89ab892 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp
@@ -34,6 +34,7 @@
 
 prebuilt_etc {
     name: "parameter-framework.policy",
+    enabled: false, // TODO: This module depends on domaingeneratorpolicyrule_gen, which fails to build
     filename_from_src: true,
     vendor: true,
     src: ":domaingeneratorpolicyrule_gen",
@@ -47,6 +48,7 @@
 
 genrule {
     name: "domaingeneratorpolicyrule_gen",
+    enabled: false, // TODO: This module fails to build
     defaults: ["domaingeneratorpolicyrule"],
     srcs: [
         ":audio_policy_pfw_toplevel",
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp
index 337f358..4880547 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp
@@ -34,6 +34,7 @@
 
 prebuilt_etc {
     name: "parameter-framework.policy",
+    enabled: false, // TODO: This module depends on domaingeneratorpolicyrule_gen, which fails to build
     filename_from_src: true,
     vendor: true,
     src: ":domaingeneratorpolicyrule_gen",
@@ -46,6 +47,7 @@
 }
 genrule {
     name: "domaingeneratorpolicyrule_gen",
+    enabled: false, // TODO: This module fails to build
     defaults: ["domaingeneratorpolicyrule"],
     srcs: [
         ":audio_policy_pfw_toplevel",
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a0ec9aa..1658f40 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -277,7 +277,7 @@
                 sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
                 if (policyMix != nullptr
                         && policyMix->mMixType == MIX_TYPE_RECORDERS
-                        && device->address() == policyMix->mDeviceAddress.string()) {
+                        && device->address() == policyMix->mDeviceAddress.c_str()) {
                     doCheckForDeviceAndOutputChanges = false;
                     break;
                 }
@@ -2216,7 +2216,7 @@
     const char *address = NULL;
     if (policyMix != nullptr) {
         audio_devices_t newDeviceType;
-        address = policyMix->mDeviceAddress.string();
+        address = policyMix->mDeviceAddress.c_str();
         if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
             newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
         } else {
@@ -3605,7 +3605,7 @@
             }
 
             if (mPolicyMixes.registerMix(mix, 0 /*output desc*/) != NO_ERROR) {
-                ALOGE("Error registering mix %zu for address %s", i, address.string());
+                ALOGE("Error registering mix %zu for address %s", i, address.c_str());
                 res = INVALID_OPERATION;
                 break;
             }
@@ -3622,16 +3622,16 @@
 
             if ((res = setDeviceConnectionStateInt(deviceTypeToMakeAvailable,
                     AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                    address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT)) != NO_ERROR) {
+                    address.c_str(), "remote-submix", AUDIO_FORMAT_DEFAULT)) != NO_ERROR) {
                 ALOGE("Failed to set remote submix device available, type %u, address %s",
-                        mix.mDeviceType, address.string());
+                        mix.mDeviceType, address.c_str());
                 break;
             }
         } else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
             String8 address = mix.mDeviceAddress;
             audio_devices_t type = mix.mDeviceType;
             ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
-                    i, mixes.size(), type, address.string());
+                    i, mixes.size(), type, address.c_str());
 
             sp<DeviceDescriptor> device = mHwModules.getDeviceDescriptor(
                     mix.mDeviceType, mix.mDeviceAddress,
@@ -3649,7 +3649,7 @@
                 if (!desc->isDuplicated() && desc->supportedDevices().contains(device)) {
                     if (mPolicyMixes.registerMix(mix, desc) != NO_ERROR) {
                         ALOGE("Could not register mix RENDER,  dev=0x%X addr=%s", type,
-                              address.string());
+                              address.c_str());
                         res = INVALID_OPERATION;
                     } else {
                         foundOutput = true;
@@ -3666,7 +3666,7 @@
                     if (profile->isDirectOutput() && profile->supportsDevice(device)) {
                         if (mPolicyMixes.registerMix(mix, nullptr) != NO_ERROR) {
                             ALOGE("Could not register mix RENDER,  dev=0x%X addr=%s", type,
-                                  address.string());
+                                  address.c_str());
                             res = INVALID_OPERATION;
                         } else {
                             foundOutput = true;
@@ -3676,12 +3676,12 @@
             }
             if (res != NO_ERROR) {
                 ALOGE(" Error registering mix %zu for device 0x%X addr %s",
-                        i, type, address.string());
+                        i, type, address.c_str());
                 res = INVALID_OPERATION;
                 break;
             } else if (!foundOutput) {
                 ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
-                        i, type, address.string());
+                        i, type, address.c_str());
                 res = INVALID_OPERATION;
                 break;
             } else {
@@ -3725,14 +3725,14 @@
             }
 
             for (auto device : {AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX}) {
-                if (getDeviceConnectionState(device, address.string()) ==
+                if (getDeviceConnectionState(device, address.c_str()) ==
                         AUDIO_POLICY_DEVICE_STATE_AVAILABLE)  {
                     res = setDeviceConnectionStateInt(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                                      address.string(), "remote-submix",
+                                                      address.c_str(), "remote-submix",
                                                       AUDIO_FORMAT_DEFAULT);
                     if (res != OK) {
                         ALOGE("Error making RemoteSubmix device unavailable for mix "
-                              "with type %d, address %s", device, address.string());
+                              "with type %d, address %s", device, address.c_str());
                     }
                 }
             }
@@ -4148,7 +4148,7 @@
 {
     String8 result;
     dump(&result);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
@@ -6359,7 +6359,7 @@
             }
 
             ALOGV("opening output for device %08x with params %s profile %p name %s",
-                  deviceType, address.string(), profile.get(), profile->getName().c_str());
+                  deviceType, address.c_str(), profile.get(), profile->getName().c_str());
             desc = openOutputWithProfileAndDevice(profile, DeviceVector(device));
             audio_io_handle_t output = desc == nullptr ? AUDIO_IO_HANDLE_NONE : desc->mIoHandle;
             if (output == AUDIO_IO_HANDLE_NONE) {
@@ -7741,6 +7741,9 @@
     }
     if (deviceTypes.empty()) {
         deviceTypes = outputDesc->devices().types();
+        index = curves.getVolumeIndex(deviceTypes);
+        ALOGD("%s if deviceTypes is change from none to device %s, need get index %d",
+                __func__, dumpDeviceTypes(deviceTypes).c_str(), index);
     }
 
     if (curves.getVolumeIndexMin() < 0 || curves.getVolumeIndexMax() < 0) {
@@ -8055,12 +8058,12 @@
     if (profiles.hasDynamicFormat()) {
         reply = mpClientInterface->getParameters(
                 ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
-        ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.string());
+        ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.c_str());
         AudioParameter repliedParameters(reply);
         FormatVector formats;
         if (repliedParameters.get(
                 String8(AudioParameter::keyStreamSupportedFormats), reply) == NO_ERROR) {
-            formats = formatsFromString(reply.string());
+            formats = formatsFromString(reply.c_str());
         } else if (devDesc->hasValidAudioProfile()) {
             ALOGD("%s: using the device profiles", __func__);
             formats = devDesc->getAudioProfiles().getSupportedFormats();
@@ -8087,11 +8090,11 @@
                     ioHandle,
                     requestedParameters.toString() + ";" +
                     AudioParameter::keyStreamSupportedSamplingRates);
-            ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.string());
+            ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.c_str());
             AudioParameter repliedParameters(reply);
             if (repliedParameters.get(
                     String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
-                samplingRates = samplingRatesFromString(reply.string());
+                samplingRates = samplingRatesFromString(reply.c_str());
             } else {
                 samplingRates = devDesc->getAudioProfiles().getSampleRatesFor(format);
             }
@@ -8100,11 +8103,11 @@
             reply = mpClientInterface->getParameters(ioHandle,
                                                      requestedParameters.toString() + ";" +
                                                      AudioParameter::keyStreamSupportedChannels);
-            ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.string());
+            ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.c_str());
             AudioParameter repliedParameters(reply);
             if (repliedParameters.get(
                     String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
-                channelMasks = channelMasksFromString(reply.string());
+                channelMasks = channelMasksFromString(reply.c_str());
             } else {
                 channelMasks = devDesc->getAudioProfiles().getChannelMasksFor(format);
             }
@@ -8278,7 +8281,7 @@
             desc->mPolicyMix = policyMix;
         } else {
             ALOGW("checkOutputsForDevice() cannot find policy for address %s",
-                    address.string());
+                    address.c_str());
         }
 
     } else if (hasPrimaryOutput() && speaker != nullptr
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 13e682b..2874824 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -190,7 +190,7 @@
                    const String8& keyValuePairs,
                    int delay_ms)
 {
-    mAudioPolicyService->setParameters(io_handle, keyValuePairs.string(), delay_ms);
+    mAudioPolicyService->setParameters(io_handle, keyValuePairs.c_str(), delay_ms);
 }
 
 String8 AudioPolicyService::AudioPolicyClient::getParameters(audio_io_handle_t io_handle,
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 234104d..68092d7 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -463,7 +463,7 @@
 void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
 {
     ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
-            regId.string(), state);
+            regId.c_str(), state);
     mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
 }
 
@@ -807,7 +807,7 @@
     msg << std::endl;
     result.append(msg.str().c_str());
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     mUidPolicy->dumpInternals(fd);
     return NO_ERROR;
@@ -1215,19 +1215,19 @@
         const bool locked = dumpTryLock(mLock);
         if (!locked) {
             String8 result(kDeadlockedString);
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         }
 
         dumpInternals(fd);
 
         String8 actPtr = String8::format("AudioCommandThread: %p\n", mAudioCommandThread.get());
-        write(fd, actPtr.string(), actPtr.size());
+        write(fd, actPtr.c_str(), actPtr.size());
         if (mAudioCommandThread != 0) {
             mAudioCommandThread->dump(fd);
         }
 
         String8 octPtr = String8::format("OutputCommandThread: %p\n", mOutputCommandThread.get());
-        write(fd, octPtr.string(), octPtr.size());
+        write(fd, octPtr.c_str(), octPtr.size());
         if (mOutputCommandThread != 0) {
             mOutputCommandThread->dump(fd);
         }
@@ -1236,7 +1236,7 @@
             mAudioPolicyManager->dump(fd);
         } else {
             String8 apmPtr = String8::format("AudioPolicyManager: %p\n", mAudioPolicyManager);
-            write(fd, apmPtr.string(), apmPtr.size());
+            write(fd, apmPtr.c_str(), apmPtr.size());
         }
 
         mPackageManager.dump(fd);
@@ -1270,7 +1270,7 @@
             IPCThreadState::self()->getCallingPid(),
             IPCThreadState::self()->getCallingUid());
     result.append(buffer);
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
@@ -1449,8 +1449,8 @@
     PermissionController pc;
     uid = pc.getPackageUid(packageName, 0);
     if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(packageName).string());
-        dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
+        ALOGE("Unknown package: '%s'", String8(packageName).c_str());
+        dprintf(err, "Unknown package: '%s'\n", String8(packageName).c_str());
         return BAD_VALUE;
     }
 
@@ -1469,7 +1469,7 @@
     if (args[2] == String16("active")) {
         active = true;
     } else if ((args[2] != String16("idle"))) {
-        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
+        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).c_str());
         return BAD_VALUE;
     }
 
@@ -1849,7 +1849,7 @@
     snprintf(buffer, SIZE, "\tIs RTT Enabled: %s\n", (mRttEnabled ? "True":"False"));
     result.append(buffer);
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 }
 
 // -----------  AudioPolicyService::SensorPrivacyService implementation ----------
@@ -1994,14 +1994,14 @@
 AudioPolicyService::AudioCommandThread::~AudioCommandThread()
 {
     if (!mAudioCommands.isEmpty()) {
-        release_wake_lock(mName.string());
+        release_wake_lock(mName.c_str());
     }
     mAudioCommands.clear();
 }
 
 void AudioPolicyService::AudioCommandThread::onFirstRef()
 {
-    run(mName.string(), ANDROID_PRIORITY_AUDIO);
+    run(mName.c_str(), ANDROID_PRIORITY_AUDIO);
 }
 
 bool AudioPolicyService::AudioCommandThread::threadLoop()
@@ -2038,7 +2038,7 @@
                 case SET_PARAMETERS: {
                     ParametersData *data = (ParametersData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
-                            data->mKeyValuePairs.string(), data->mIO);
+                            data->mKeyValuePairs.c_str(), data->mIO);
                     mLock.unlock();
                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
                     mLock.lock();
@@ -2147,7 +2147,7 @@
                     DynPolicyMixStateUpdateData *data =
                             (DynPolicyMixStateUpdateData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
-                            data->mRegId.string(), data->mState);
+                            data->mRegId.c_str(), data->mState);
                     svc = mService.promote();
                     if (svc == 0) {
                         break;
@@ -2272,7 +2272,7 @@
         // release delayed commands wake lock as many times as we made the  queue is
         // empty during popping.
         while (numTimesBecameEmpty--) {
-            release_wake_lock(mName.string());
+            release_wake_lock(mName.c_str());
         }
 
         // At this stage we have either an empty command queue or the first command in the queue
@@ -2288,7 +2288,7 @@
     }
     // release delayed commands wake lock before quitting
     if (!mAudioCommands.isEmpty()) {
-        release_wake_lock(mName.string());
+        release_wake_lock(mName.c_str());
     }
     mLock.unlock();
     return false;
@@ -2303,7 +2303,7 @@
     const bool locked = dumpTryLock(mLock);
     if (!locked) {
         String8 result2(kCmdDeadlockedString);
-        write(fd, result2.string(), result2.size());
+        write(fd, result2.c_str(), result2.size());
     }
 
     snprintf(buffer, SIZE, "- Commands:\n");
@@ -2321,7 +2321,7 @@
         result.append("     none\n");
     }
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     dumpReleaseLock(mLock, locked);
 
@@ -2508,7 +2508,7 @@
     data->mState = state;
     command->mParam = data;
     ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
-            regId.string(), state);
+            regId.c_str(), state);
     sendCommand(command);
 }
 
@@ -2605,7 +2605,7 @@
 
     // acquire wake lock to make sure delayed commands are processed
     if (mAudioCommands.isEmpty()) {
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.c_str());
     }
 
     // check same pending commands with later time stamps and eliminate them
@@ -2630,7 +2630,7 @@
             ParametersData *data2 = (ParametersData *)command2->mParam.get();
             if (data->mIO != data2->mIO) break;
             ALOGV("Comparing parameter command %s to new command %s",
-                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
+                    data2->mKeyValuePairs.c_str(), data->mKeyValuePairs.c_str());
             AudioParameter param = AudioParameter(data->mKeyValuePairs);
             AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
             for (size_t j = 0; j < param.size(); j++) {
@@ -2643,7 +2643,7 @@
                     param2.getAt(k, key2, value2);
                     if (key2 == key) {
                         param2.remove(key2);
-                        ALOGV("Filtering out parameter %s", key2.string());
+                        ALOGV("Filtering out parameter %s", key2.c_str());
                         break;
                     }
                 }
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index ffd38be..d9d8a3d 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -47,14 +47,14 @@
 CameraFlashlight::~CameraFlashlight() {
 }
 
-status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
+status_t CameraFlashlight::createFlashlightControl(const std::string& cameraId) {
     ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
-            cameraId.string());
+            cameraId.c_str());
     if (mFlashControl != NULL) {
         return INVALID_OPERATION;
     }
 
-    if (mProviderManager->supportSetTorchMode(cameraId.string())) {
+    if (mProviderManager->supportSetTorchMode(cameraId)) {
         mFlashControl = new ProviderFlashControl(mProviderManager);
     } else {
         ALOGE("Flashlight control not supported by this device!");
@@ -64,7 +64,7 @@
     return OK;
 }
 
-status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
+status_t CameraFlashlight::setTorchMode(const std::string& cameraId, bool enabled) {
     if (!mFlashlightMapInitialized) {
         ALOGE("%s: findFlashUnits() must be called before this method.",
                __FUNCTION__);
@@ -72,7 +72,7 @@
     }
 
     ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__,
-            cameraId.string(), enabled);
+            cameraId.c_str(), enabled);
 
     status_t res = OK;
     Mutex::Autolock l(mLock);
@@ -87,7 +87,7 @@
         // TODO: Move torch status checks and state updates behind this CameraFlashlight lock
         // to avoid other similar race conditions.
         ALOGE("%s: Camera device %s is in use, cannot set torch mode.",
-                __FUNCTION__, cameraId.string());
+                __FUNCTION__, cameraId.c_str());
         return -EBUSY;
     }
 
@@ -117,7 +117,7 @@
     return res;
 }
 
-status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const String8& cameraId,
+status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const std::string& cameraId,
             int32_t torchStrength) {
     if (!mFlashlightMapInitialized) {
         ALOGE("%s: findFlashUnits() must be called before this method.",
@@ -126,13 +126,13 @@
     }
 
     ALOGV("%s: set torch strength of camera %s to %d", __FUNCTION__,
-            cameraId.string(), torchStrength);
+            cameraId.c_str(), torchStrength);
     status_t res = OK;
     Mutex::Autolock l(mLock);
 
     if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
         ALOGE("%s: Camera device %s is in use, cannot be turned ON.",
-                __FUNCTION__, cameraId.string());
+                __FUNCTION__, cameraId.c_str());
         return -EBUSY;
     }
 
@@ -148,7 +148,7 @@
 }
 
 
-status_t CameraFlashlight::getTorchStrengthLevel(const String8& cameraId,
+status_t CameraFlashlight::getTorchStrengthLevel(const std::string& cameraId,
             int32_t* torchStrength) {
     status_t res = OK;
     if (!mFlashlightMapInitialized) {
@@ -174,13 +174,13 @@
     Mutex::Autolock l(mLock);
     status_t res;
 
-    std::vector<String8> cameraIds;
+    std::vector<std::string> cameraIds;
     std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
     int numberOfCameras = static_cast<int>(ids.size());
     cameraIds.resize(numberOfCameras);
     // No module, must be provider
     for (size_t i = 0; i < cameraIds.size(); i++) {
-        cameraIds[i] = String8(ids[i].c_str());
+        cameraIds[i] = ids[i];
     }
 
     mFlashControl.clear();
@@ -195,17 +195,17 @@
         res = createFlashlightControl(id);
         if (res) {
             ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
-                    id.string());
+                    id.c_str());
         } else {
             res = mFlashControl->hasFlashUnit(id, &hasFlash);
             if (res == -EUSERS || res == -EBUSY) {
                 ALOGE("%s: failed to check if camera %s has a flash unit. Some "
                         "camera devices may be opened", __FUNCTION__,
-                        id.string());
+                        id.c_str());
                 return res;
             } else if (res) {
                 ALOGE("%s: failed to check if camera %s has a flash unit. %s"
-                        " (%d)", __FUNCTION__, id.string(), strerror(-res),
+                        " (%d)", __FUNCTION__, id.c_str(), strerror(-res),
                         res);
             }
 
@@ -218,12 +218,12 @@
     return OK;
 }
 
-bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
+bool CameraFlashlight::hasFlashUnit(const std::string& cameraId) {
     Mutex::Autolock l(mLock);
     return hasFlashUnitLocked(cameraId);
 }
 
-bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
+bool CameraFlashlight::hasFlashUnitLocked(const std::string& cameraId) {
     if (!mFlashlightMapInitialized) {
         ALOGE("%s: findFlashUnits() must be called before this method.",
                __FUNCTION__);
@@ -234,23 +234,23 @@
     if (index == NAME_NOT_FOUND) {
         // Might be external camera
         ALOGW("%s: camera %s not present when findFlashUnits() was called",
-                __FUNCTION__, cameraId.string());
+                __FUNCTION__, cameraId.c_str());
         return false;
     }
 
     return mHasFlashlightMap.valueAt(index);
 }
 
-bool CameraFlashlight::isBackwardCompatibleMode(const String8& cameraId) {
+bool CameraFlashlight::isBackwardCompatibleMode(const std::string& cameraId) {
     bool backwardCompatibleMode = false;
     if (mProviderManager != nullptr &&
-            !mProviderManager->supportSetTorchMode(cameraId.string())) {
+            !mProviderManager->supportSetTorchMode(cameraId)) {
         backwardCompatibleMode = true;
     }
     return backwardCompatibleMode;
 }
 
-status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
+status_t CameraFlashlight::prepareDeviceOpen(const std::string& cameraId) {
     ALOGV("%s: prepare for device open", __FUNCTION__);
 
     Mutex::Autolock l(mLock);
@@ -270,10 +270,9 @@
             std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
             int numCameras = static_cast<int>(ids.size());
             for (int i = 0; i < numCameras; i++) {
-                String8 id8(ids[i].c_str());
-                if (hasFlashUnitLocked(id8)) {
+                if (hasFlashUnitLocked(ids[i])) {
                     mCallbacks->onTorchStatusChanged(
-                            id8, TorchModeStatus::NOT_AVAILABLE);
+                            ids[i], TorchModeStatus::NOT_AVAILABLE);
                 }
             }
         }
@@ -289,8 +288,8 @@
     return OK;
 }
 
-status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
-    ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
+status_t CameraFlashlight::deviceClosed(const std::string& cameraId) {
+    ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.c_str());
 
     Mutex::Autolock l(mLock);
     if (!mFlashlightMapInitialized) {
@@ -302,7 +301,7 @@
     ssize_t index = mOpenedCameraIds.indexOf(cameraId);
     if (index == NAME_NOT_FOUND) {
         ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
     } else {
         mOpenedCameraIds.removeAt(index);
     }
@@ -316,10 +315,9 @@
         std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
         int numCameras = static_cast<int>(ids.size());
         for (int i = 0; i < numCameras; i++) {
-            String8 id8(ids[i].c_str());
-            if (hasFlashUnitLocked(id8)) {
+            if (hasFlashUnitLocked(ids[i])) {
                 mCallbacks->onTorchStatusChanged(
-                        id8, TorchModeStatus::AVAILABLE_OFF);
+                        ids[i], TorchModeStatus::AVAILABLE_OFF);
             }
         }
     }
@@ -343,35 +341,35 @@
 ProviderFlashControl::~ProviderFlashControl() {
 }
 
-status_t ProviderFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) {
+status_t ProviderFlashControl::hasFlashUnit(const std::string& cameraId, bool *hasFlash) {
     if (!hasFlash) {
         return BAD_VALUE;
     }
-    *hasFlash = mProviderManager->hasFlashUnit(cameraId.string());
+    *hasFlash = mProviderManager->hasFlashUnit(cameraId);
     return OK;
 }
 
-status_t ProviderFlashControl::setTorchMode(const String8& cameraId, bool enabled) {
+status_t ProviderFlashControl::setTorchMode(const std::string& cameraId, bool enabled) {
     ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
-            cameraId.string(), enabled);
+            cameraId.c_str(), enabled);
 
-    return mProviderManager->setTorchMode(cameraId.string(), enabled);
+    return mProviderManager->setTorchMode(cameraId, enabled);
 }
 
-status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const String8& cameraId,
+status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const std::string& cameraId,
             int32_t torchStrength) {
     ALOGV("%s: change torch strength level of camera %s to %d", __FUNCTION__,
-            cameraId.string(), torchStrength);
+            cameraId.c_str(), torchStrength);
 
-    return mProviderManager->turnOnTorchWithStrengthLevel(cameraId.string(), torchStrength);
+    return mProviderManager->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
 }
 
-status_t ProviderFlashControl::getTorchStrengthLevel(const String8& cameraId,
+status_t ProviderFlashControl::getTorchStrengthLevel(const std::string& cameraId,
             int32_t* torchStrength) {
     ALOGV("%s: get torch strength level of camera %s", __FUNCTION__,
-            cameraId.string());
+            cameraId.c_str());
 
-    return mProviderManager->getTorchStrengthLevel(cameraId.string(), torchStrength);
+    return mProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
 }
 // ProviderFlashControl implementation ends
 
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 1703ddc..733c928 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H
 #define ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H
 
+#include <string>
 #include <gui/GLConsumer.h>
 #include <gui/Surface.h>
 #include <utils/KeyedVector.h>
@@ -38,20 +39,21 @@
         // cause the torch mode to be turned off in HAL v1 devices. If
         // previously-on torch mode is turned off,
         // callbacks.torch_mode_status_change() should be invoked.
-        virtual status_t hasFlashUnit(const String8& cameraId,
+        virtual status_t hasFlashUnit(const std::string& cameraId,
                     bool *hasFlash) = 0;
 
         // set the torch mode to on or off.
-        virtual status_t setTorchMode(const String8& cameraId,
+        virtual status_t setTorchMode(const std::string& cameraId,
                     bool enabled) = 0;
 
         // Change the brightness level of the torch. If the torch is OFF and
         // torchStrength >= 1, then the torch will also be turned ON.
-        virtual status_t turnOnTorchWithStrengthLevel(const String8& cameraId,
+        virtual status_t turnOnTorchWithStrengthLevel(const std::string& cameraId,
                     int32_t torchStrength) = 0;
 
         // Returns the torch strength level.
-        virtual status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength) = 0;
+        virtual status_t getTorchStrengthLevel(const std::string& cameraId,
+                int32_t* torchStrength) = 0;
 };
 
 /**
@@ -70,49 +72,49 @@
 
         // Whether a camera device has a flash unit. Before findFlashUnits() is
         // called, this function always returns false.
-        bool hasFlashUnit(const String8& cameraId);
+        bool hasFlashUnit(const std::string& cameraId);
 
         // set the torch mode to on or off.
-        status_t setTorchMode(const String8& cameraId, bool enabled);
+        status_t setTorchMode(const std::string& cameraId, bool enabled);
 
         // Change the torch strength level of the flash unit in torch mode.
-        status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
+        status_t turnOnTorchWithStrengthLevel(const std::string& cameraId, int32_t torchStrength);
 
         // Get the torch strength level
-        status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
+        status_t getTorchStrengthLevel(const std::string& cameraId, int32_t* torchStrength);
 
         // Notify CameraFlashlight that camera service is going to open a camera
         // device. CameraFlashlight will free the resources that may cause the
         // camera open to fail. Camera service must call this function before
         // opening a camera device.
-        status_t prepareDeviceOpen(const String8& cameraId);
+        status_t prepareDeviceOpen(const std::string& cameraId);
 
         // Notify CameraFlashlight that camera service has closed a camera
         // device. CameraFlashlight may invoke callbacks for torch mode
         // available depending on the implementation.
-        status_t deviceClosed(const String8& cameraId);
+        status_t deviceClosed(const std::string& cameraId);
 
     private:
         // create flashlight control based on camera module API and camera
         // device API versions.
-        status_t createFlashlightControl(const String8& cameraId);
+        status_t createFlashlightControl(const std::string& cameraId);
 
         // mLock should be locked.
-        bool hasFlashUnitLocked(const String8& cameraId);
+        bool hasFlashUnitLocked(const std::string& cameraId);
 
         // Check if flash control is in backward compatible mode (simulated torch API by
         // opening cameras)
-        bool isBackwardCompatibleMode(const String8& cameraId);
+        bool isBackwardCompatibleMode(const std::string& cameraId);
 
         sp<FlashControlBase> mFlashControl;
 
         sp<CameraProviderManager> mProviderManager;
 
         CameraProviderManager::StatusListener* mCallbacks;
-        SortedVector<String8> mOpenedCameraIds;
+        SortedVector<std::string> mOpenedCameraIds;
 
         // camera id -> if it has a flash unit
-        KeyedVector<String8, bool> mHasFlashlightMap;
+        KeyedVector<std::string, bool> mHasFlashlightMap;
         bool mFlashlightMapInitialized;
 
         Mutex mLock; // protect CameraFlashlight API
@@ -127,10 +129,10 @@
         virtual ~ProviderFlashControl();
 
         // FlashControlBase
-        status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
-        status_t setTorchMode(const String8& cameraId, bool enabled);
-        status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
-        status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
+        status_t hasFlashUnit(const std::string& cameraId, bool *hasFlash);
+        status_t setTorchMode(const std::string& cameraId, bool enabled);
+        status_t turnOnTorchWithStrengthLevel(const std::string& cameraId, int32_t torchStrength);
+        status_t getTorchStrengthLevel(const std::string& cameraId, int32_t* torchStrength);
 
     private:
         sp<CameraProviderManager> mProviderManager;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 668a51a..3e7af3d 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -24,6 +24,8 @@
 #include <cstdlib>
 #include <cstring>
 #include <ctime>
+#include <iostream>
+#include <sstream>
 #include <string>
 #include <sys/types.h>
 #include <inttypes.h>
@@ -36,7 +38,6 @@
 #include <aidl/AidlCameraService.h>
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
 #include <android/permission/PermissionChecker.h>
 #include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
@@ -71,6 +72,7 @@
 #include <system/camera_metadata.h>
 #include <binder/IServiceManager.h>
 #include <binder/IActivityManager.h>
+#include <camera/StringUtils.h>
 
 #include <system/camera.h>
 
@@ -91,7 +93,6 @@
 
 namespace android {
 
-using base::StringPrintf;
 using binder::Status;
 using namespace camera3;
 using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
@@ -116,28 +117,17 @@
     android_atomic_write(level, &gLogLevel);
 }
 
-// Convenience methods for constructing binder::Status objects for error returns
-
-#define STATUS_ERROR(errorCode, errorString) \
-    binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
-
-#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
-    binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
-                    __VA_ARGS__))
-
 // ----------------------------------------------------------------------------
 
-static const String16 sDumpPermission("android.permission.DUMP");
-static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
-static const String16 sCameraPermission("android.permission.CAMERA");
-static const String16 sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
-static const String16
+static const std::string sDumpPermission("android.permission.DUMP");
+static const std::string sManageCameraPermission("android.permission.MANAGE_CAMERA");
+static const std::string sCameraPermission("android.permission.CAMERA");
+static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
+static const std::string
         sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
-static const String16 sCameraOpenCloseListenerPermission(
+static const std::string sCameraOpenCloseListenerPermission(
         "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
-static const String16
+static const std::string
         sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
 // Constant integer for FGS Logging, used to denote the API type for logger
 static const int LOG_FGS_CAMERA_API = 1;
@@ -145,12 +135,13 @@
 static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
 static constexpr int32_t kSystemNativeClientState =
         ActivityManager::PROCESS_STATE_PERSISTENT_UI;
+static const std::string kServiceName("cameraserver");
 
-const String8 CameraService::kOfflineDevice("offline-");
-const String16 CameraService::kWatchAllClientsFlag("all");
+const std::string CameraService::kOfflineDevice("offline-");
+const std::string CameraService::kWatchAllClientsFlag("all");
 
 // Set to keep track of logged service error events.
-static std::set<String8> sServiceErrorEventSet;
+static std::set<std::string> sServiceErrorEventSet;
 
 CameraService::CameraService(
         std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
@@ -181,7 +172,7 @@
 }
 
 void CameraService::onServiceRegistration(const String16& name, const sp<IBinder>&) {
-    if (name != String16(kAppopsServiceName)) {
+    if (name != toString16(kAppopsServiceName)) {
         return;
     }
 
@@ -219,9 +210,9 @@
     // boot availability for cameraservice, use checkService which is
     // non blocking and register for notifications
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->checkService(String16(kAppopsServiceName));
+    sp<IBinder> binder = sm->checkService(toString16(kAppopsServiceName));
     if (!binder) {
-        sm->registerForNotifications(String16(kAppopsServiceName), this);
+        sm->registerForNotifications(toString16(kAppopsServiceName), this);
     } else {
         mAppOps.setCameraAudioRestriction(mAudioRestriction);
     }
@@ -257,8 +248,8 @@
             if (res != OK) {
                 ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
                         __FUNCTION__, strerror(-res), res);
-                logServiceError(String8::format("Unable to initialize camera provider manager"),
-                ERROR_DISCONNECTED);
+                logServiceError("Unable to initialize camera provider manager",
+                        ERROR_DISCONNECTED);
                 return res;
             }
         }
@@ -283,14 +274,12 @@
 
 
     for (auto& cameraId : deviceIds) {
-        String8 id8 = String8(cameraId.c_str());
-        if (getCameraState(id8) == nullptr) {
-            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+        if (getCameraState(cameraId) == nullptr) {
+            onDeviceStatusChanged(cameraId, CameraDeviceStatus::PRESENT);
         }
         if (unavailPhysicalIds.count(cameraId) > 0) {
             for (const auto& physicalId : unavailPhysicalIds[cameraId]) {
-                String8 physicalId8 = String8(physicalId.c_str());
-                onDeviceStatusChanged(id8, physicalId8, CameraDeviceStatus::NOT_PRESENT);
+                onDeviceStatusChanged(cameraId, physicalId, CameraDeviceStatus::NOT_PRESENT);
             }
         }
     }
@@ -310,7 +299,7 @@
     return OK;
 }
 
-void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status,
+void CameraService::broadcastTorchModeStatus(const std::string& cameraId, TorchModeStatus status,
         SystemCameraKind systemCameraKind) {
     Mutex::Autolock lock(mStatusListenerLock);
     for (auto& i : mListenerList) {
@@ -321,7 +310,7 @@
             continue;
         }
         auto ret = i->getListener()->onTorchStatusChanged(mapToInterface(status),
-                String16{cameraId});
+                cameraId);
         i->handleBinderStatus(ret, "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d",
                 __FUNCTION__, i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
     }
@@ -343,7 +332,7 @@
     mNormalDeviceIdsWithoutSystemCamera.clear();
     for (auto &deviceId : normalDeviceIds) {
         SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
-        if (getSystemCameraKind(String8(deviceId.c_str()), &deviceKind) != OK) {
+        if (getSystemCameraKind(deviceId, &deviceKind) != OK) {
             ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, deviceId.c_str());
             continue;
         }
@@ -358,14 +347,15 @@
               mNormalDeviceIdsWithoutSystemCamera.size());
 }
 
-status_t CameraService::getSystemCameraKind(const String8& cameraId, SystemCameraKind *kind) const {
+status_t CameraService::getSystemCameraKind(const std::string& cameraId,
+        SystemCameraKind *kind) const {
     auto state = getCameraState(cameraId);
     if (state != nullptr) {
         *kind = state->getSystemCameraKind();
         return OK;
     }
     // Hidden physical camera ids won't have CameraState
-    return mCameraProviderManager->getSystemCameraKind(cameraId.c_str(), kind);
+    return mCameraProviderManager->getSystemCameraKind(cameraId, kind);
 }
 
 void CameraService::updateCameraNumAndIds() {
@@ -388,9 +378,8 @@
     for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) {
         int facing = -1;
         int orientation = 0;
-        String8 cameraId8(cameraId.c_str());
         int portraitRotation;
-        getDeviceVersion(cameraId8, /*overrideToPortrait*/false, /*out*/&portraitRotation,
+        getDeviceVersion(cameraId, /*overrideToPortrait*/false, /*out*/&portraitRotation,
                 /*out*/&facing, /*out*/&orientation);
         if (facing == -1) {
             ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
@@ -422,8 +411,7 @@
     }
 }
 
-void CameraService::addStates(const String8 id) {
-    std::string cameraId(id.c_str());
+void CameraService::addStates(const std::string& cameraId) {
     CameraResourceCost cost;
     status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
     if (res != OK) {
@@ -438,61 +426,61 @@
     }
     std::vector<std::string> physicalCameraIds;
     mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds);
-    std::set<String8> conflicting;
+    std::set<std::string> conflicting;
     for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
-        conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
+        conflicting.emplace(cost.conflictingDevices[i]);
     }
 
     {
         Mutex::Autolock lock(mCameraStatesLock);
-        mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
+        mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost.resourceCost,
                 conflicting, deviceKind, physicalCameraIds));
     }
 
-    if (mFlashlight->hasFlashUnit(id)) {
+    if (mFlashlight->hasFlashUnit(cameraId)) {
         Mutex::Autolock al(mTorchStatusMutex);
-        mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+        mTorchStatusMap.add(cameraId, TorchModeStatus::AVAILABLE_OFF);
 
-        broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF, deviceKind);
+        broadcastTorchModeStatus(cameraId, TorchModeStatus::AVAILABLE_OFF, deviceKind);
     }
 
     updateCameraNumAndIds();
-    logDeviceAdded(id, "Device added");
+    logDeviceAdded(cameraId, "Device added");
 }
 
-void CameraService::removeStates(const String8 id) {
+void CameraService::removeStates(const std::string& cameraId) {
     updateCameraNumAndIds();
-    if (mFlashlight->hasFlashUnit(id)) {
+    if (mFlashlight->hasFlashUnit(cameraId)) {
         Mutex::Autolock al(mTorchStatusMutex);
-        mTorchStatusMap.removeItem(id);
+        mTorchStatusMap.removeItem(cameraId);
     }
 
     {
         Mutex::Autolock lock(mCameraStatesLock);
-        mCameraStates.erase(id);
+        mCameraStates.erase(cameraId);
     }
 }
 
-void CameraService::onDeviceStatusChanged(const String8& id,
+void CameraService::onDeviceStatusChanged(const std::string& cameraId,
         CameraDeviceStatus newHalStatus) {
     ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
-            id.string(), newHalStatus);
+            cameraId.c_str(), newHalStatus);
 
     StatusInternal newStatus = mapToInternal(newHalStatus);
 
-    std::shared_ptr<CameraState> state = getCameraState(id);
+    std::shared_ptr<CameraState> state = getCameraState(cameraId);
 
     if (state == nullptr) {
         if (newStatus == StatusInternal::PRESENT) {
             ALOGI("%s: Unknown camera ID %s, a new camera is added",
-                    __FUNCTION__, id.string());
+                    __FUNCTION__, cameraId.c_str());
 
             // First add as absent to make sure clients are notified below
-            addStates(id);
+            addStates(cameraId);
 
-            updateStatus(newStatus, id);
+            updateStatus(newStatus, cameraId);
         } else {
-            ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
+            ALOGE("%s: Bad camera ID %s", __FUNCTION__, cameraId.c_str());
         }
         return;
     }
@@ -505,12 +493,12 @@
     }
 
     if (newStatus == StatusInternal::NOT_PRESENT) {
-        logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
+        logDeviceRemoved(cameraId, fmt::sprintf("Device status changed from %d to %d", oldStatus,
                 newStatus));
 
         // Set the device status to NOT_PRESENT, clients will no longer be able to connect
         // to this device until the status changes
-        updateStatus(StatusInternal::NOT_PRESENT, id);
+        updateStatus(StatusInternal::NOT_PRESENT, cameraId);
 
         sp<BasicClient> clientToDisconnectOnline, clientToDisconnectOffline;
         {
@@ -522,28 +510,28 @@
 
             // Remove online as well as offline client from the list of active clients,
             // if they are present
-            clientToDisconnectOnline = removeClientLocked(id);
-            clientToDisconnectOffline = removeClientLocked(kOfflineDevice + id);
+            clientToDisconnectOnline = removeClientLocked(cameraId);
+            clientToDisconnectOffline = removeClientLocked(kOfflineDevice + cameraId);
         }
 
-        disconnectClient(id, clientToDisconnectOnline);
-        disconnectClient(kOfflineDevice + id, clientToDisconnectOffline);
+        disconnectClient(cameraId, clientToDisconnectOnline);
+        disconnectClient(kOfflineDevice + cameraId, clientToDisconnectOffline);
 
-        removeStates(id);
+        removeStates(cameraId);
     } else {
         if (oldStatus == StatusInternal::NOT_PRESENT) {
-            logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
+            logDeviceAdded(cameraId, fmt::sprintf("Device status changed from %d to %d", oldStatus,
                     newStatus));
         }
-        updateStatus(newStatus, id);
+        updateStatus(newStatus, cameraId);
     }
 }
 
-void CameraService::onDeviceStatusChanged(const String8& id,
-        const String8& physicalId,
+void CameraService::onDeviceStatusChanged(const std::string& id,
+        const std::string& physicalId,
         CameraDeviceStatus newHalStatus) {
     ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
-            __FUNCTION__, id.string(), physicalId.string(), newHalStatus);
+            __FUNCTION__, id.c_str(), physicalId.c_str(), newHalStatus);
 
     StatusInternal newStatus = mapToInternal(newHalStatus);
 
@@ -551,7 +539,7 @@
 
     if (state == nullptr) {
         ALOGE("%s: Physical camera id %s status change on a non-present ID %s",
-                __FUNCTION__, physicalId.string(), id.string());
+                __FUNCTION__, physicalId.c_str(), id.c_str());
         return;
     }
 
@@ -559,7 +547,7 @@
     if (logicalCameraStatus != StatusInternal::PRESENT &&
             logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
         ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
-                __FUNCTION__, physicalId.string(), newHalStatus, logicalCameraStatus);
+                __FUNCTION__, physicalId.c_str(), newHalStatus, logicalCameraStatus);
         return;
     }
 
@@ -571,21 +559,18 @@
     }
 
     if (updated) {
-        String8 idCombo = id + " : " + physicalId;
+        std::string idCombo = id + " : " + physicalId;
         if (newStatus == StatusInternal::PRESENT) {
-            logDeviceAdded(idCombo,
-                    String8::format("Device status changed to %d", newStatus));
+            logDeviceAdded(idCombo, fmt::sprintf("Device status changed to %d", newStatus));
         } else {
-            logDeviceRemoved(idCombo,
-                    String8::format("Device status changed to %d", newStatus));
+            logDeviceRemoved(idCombo, fmt::sprintf("Device status changed to %d", newStatus));
         }
         // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
         SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
         if (getSystemCameraKind(id, &deviceKind) != OK) {
-            ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.string());
+            ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.c_str());
             return;
         }
-        String16 id16(id), physicalId16(physicalId);
         Mutex::Autolock lock(mStatusListenerLock);
         for (auto& listener : mListenerList) {
             if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
@@ -595,7 +580,7 @@
                 continue;
             }
             auto ret = listener->getListener()->onPhysicalCameraStatusChanged(
-                    mapToInterface(newStatus), id16, physicalId16);
+                    mapToInterface(newStatus), id, physicalId);
             listener->handleBinderStatus(ret,
                     "%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d",
                     __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
@@ -604,10 +589,10 @@
     }
 }
 
-void CameraService::disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect) {
+void CameraService::disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect) {
     if (clientToDisconnect.get() != nullptr) {
         ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
-                __FUNCTION__, id.string());
+                __FUNCTION__, id.c_str());
         // Notify the client of disconnection
         clientToDisconnect->notifyError(
                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
@@ -616,13 +601,13 @@
     }
 }
 
-void CameraService::onTorchStatusChanged(const String8& cameraId,
+void CameraService::onTorchStatusChanged(const std::string& cameraId,
         TorchModeStatus newStatus) {
     SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
     status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
     if (res != OK) {
         ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
         return;
     }
     Mutex::Autolock al(mTorchStatusMutex);
@@ -630,34 +615,33 @@
 }
 
 
-void CameraService::onTorchStatusChanged(const String8& cameraId,
+void CameraService::onTorchStatusChanged(const std::string& cameraId,
         TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
     Mutex::Autolock al(mTorchStatusMutex);
     onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
 }
 
-void CameraService::broadcastTorchStrengthLevel(const String8& cameraId,
+void CameraService::broadcastTorchStrengthLevel(const std::string& cameraId,
         int32_t newStrengthLevel) {
     Mutex::Autolock lock(mStatusListenerLock);
     for (auto& i : mListenerList) {
-        auto ret = i->getListener()->onTorchStrengthLevelChanged(String16{cameraId},
-                newStrengthLevel);
+        auto ret = i->getListener()->onTorchStrengthLevelChanged(cameraId, newStrengthLevel);
         i->handleBinderStatus(ret,
                 "%s: Failed to trigger onTorchStrengthLevelChanged for %d:%d: %d", __FUNCTION__,
                 i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
     }
 }
 
-void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
+void CameraService::onTorchStatusChangedLocked(const std::string& cameraId,
         TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
     ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
-            __FUNCTION__, cameraId.string(), newStatus);
+            __FUNCTION__, cameraId.c_str(), newStatus);
 
     TorchModeStatus status;
     status_t res = getTorchStatusLocked(cameraId, &status);
     if (res) {
         ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
-                __FUNCTION__, cameraId.string(), strerror(-res), res);
+                __FUNCTION__, cameraId.c_str(), strerror(-res), res);
         return;
     }
     if (status == newStatus) {
@@ -682,18 +666,18 @@
             if (oldUid != newUid) {
                 // If the UID has changed, log the status and update current UID in mTorchUidMap
                 if (status == TorchModeStatus::AVAILABLE_ON) {
-                    notifier.noteFlashlightOff(cameraId, oldUid);
+                    notifier.noteFlashlightOff(toString8(cameraId), oldUid);
                 }
                 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
-                    notifier.noteFlashlightOn(cameraId, newUid);
+                    notifier.noteFlashlightOn(toString8(cameraId), newUid);
                 }
                 iter->second.second = newUid;
             } else {
                 // If the UID has not changed, log the status
                 if (newStatus == TorchModeStatus::AVAILABLE_ON) {
-                    notifier.noteFlashlightOn(cameraId, oldUid);
+                    notifier.noteFlashlightOn(toString8(cameraId), oldUid);
                 } else {
-                    notifier.noteFlashlightOff(cameraId, oldUid);
+                    notifier.noteFlashlightOff(toString8(cameraId), oldUid);
                 }
             }
         }
@@ -707,11 +691,11 @@
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
     bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
-            sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+            toString16(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;
+            toString16(sCameraPermission), attributionSource, String16(),
+            AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
     return checkPermissionForSystemCamera && checkPermissionForCamera;
 }
 
@@ -750,13 +734,13 @@
     ATRACE_CALL();
     Mutex::Autolock l(mServiceLock);
     std::string cameraIdStr = cameraIdIntToStrLocked(cameraId);
-    if (shouldRejectSystemCameraConnection(String8(cameraIdStr.c_str()))) {
+    if (shouldRejectSystemCameraConnection(cameraIdStr)) {
         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
                 "characteristics for system only device %s: ", cameraIdStr.c_str());
     }
 
     if (!mInitialized) {
-        logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+        logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
         return STATUS_ERROR(ERROR_DISCONNECTED,
                 "Camera subsystem is not available");
     }
@@ -775,13 +759,13 @@
     Status ret = Status::ok();
     int portraitRotation;
     status_t err = mCameraProviderManager->getCameraInfo(
-            cameraIdStr.c_str(), overrideToPortrait, &portraitRotation, cameraInfo);
+            cameraIdStr, overrideToPortrait, &portraitRotation, cameraInfo);
     if (err != OK) {
         ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                 "Error retrieving camera info from device %d: %s (%d)", cameraId,
                 strerror(-err), err);
-        logServiceError(String8::format("Error retrieving camera info from device %d",cameraId),
-            ERROR_INVALID_OPERATION);
+        logServiceError(std::string("Error retrieving camera info from device ")
+                + std::to_string(cameraId), ERROR_INVALID_OPERATION);
     }
 
     return ret;
@@ -796,8 +780,8 @@
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
     bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
-                sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+                toString16(sSystemCameraPermission), attributionSource, String16(),
+                AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
     if (checkPermissionForSystemCamera || getpid() == callingPid) {
         deviceIds = &mNormalDeviceIds;
     }
@@ -810,12 +794,12 @@
     return (*deviceIds)[cameraIdInt];
 }
 
-String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
+std::string CameraService::cameraIdIntToStr(int cameraIdInt) {
     Mutex::Autolock lock(mServiceLock);
-    return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
+    return cameraIdIntToStrLocked(cameraIdInt);
 }
 
-Status CameraService::getCameraCharacteristics(const String16& cameraId,
+Status CameraService::getCameraCharacteristics(const std::string& cameraId,
         int targetSdkVersion, bool overrideToPortrait, CameraMetadata* cameraInfo) {
     ATRACE_CALL();
     if (!cameraInfo) {
@@ -825,43 +809,41 @@
 
     if (!mInitialized) {
         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
-        logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+        logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
         return STATUS_ERROR(ERROR_DISCONNECTED,
                 "Camera subsystem is not available");;
     }
 
-    if (shouldRejectSystemCameraConnection(String8(cameraId))) {
+    if (shouldRejectSystemCameraConnection(cameraId)) {
         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
-                "characteristics for system only device %s: ", String8(cameraId).string());
+                "characteristics for system only device %s: ", cameraId.c_str());
     }
 
     Status ret{};
 
-
-    std::string cameraIdStr = String8(cameraId).string();
     bool overrideForPerfClass =
             SessionConfigurationUtils::targetPerfClassPrimaryCamera(mPerfClassPrimaryCameraIds,
-                    cameraIdStr, targetSdkVersion);
+                    cameraId, targetSdkVersion);
     status_t res = mCameraProviderManager->getCameraCharacteristics(
-            cameraIdStr, overrideForPerfClass, cameraInfo, overrideToPortrait);
+            cameraId, overrideForPerfClass, cameraInfo, overrideToPortrait);
     if (res != OK) {
         if (res == NAME_NOT_FOUND) {
             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to retrieve camera "
-                    "characteristics for unknown device %s: %s (%d)", String8(cameraId).string(),
+                    "characteristics for unknown device %s: %s (%d)", cameraId.c_str(),
                     strerror(-res), res);
         } else {
-            logServiceError(String8::format("Unable to retrieve camera characteristics for "
-            "device %s.", String8(cameraId).string()),ERROR_INVALID_OPERATION);
+            logServiceError(fmt::sprintf("Unable to retrieve camera characteristics for device %s.",
+                    cameraId.c_str()), ERROR_INVALID_OPERATION);
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
-                    "characteristics for device %s: %s (%d)", String8(cameraId).string(),
+                    "characteristics for device %s: %s (%d)", cameraId.c_str(),
                     strerror(-res), res);
         }
     }
     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
-    if (getSystemCameraKind(String8(cameraId), &deviceKind) != OK) {
-        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, String8(cameraId).string());
+    if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
+        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera kind "
-                "for device %s", String8(cameraId).string());
+                "for device %s", cameraId.c_str());
     }
     int callingPid = CameraThreadState::getCallingPid();
     int callingUid = CameraThreadState::getCallingUid();
@@ -874,19 +856,19 @@
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
     bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+                toString16(sCameraPermission), attributionSource, String16(),
+                AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
     if ((callingPid != getpid()) &&
             (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
             !checkPermissionForCamera) {
         res = cameraInfo->removePermissionEntries(
-                mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
+                mCameraProviderManager->getProviderTagIdLocked(cameraId),
                 &tagsRemoved);
         if (res != OK) {
             cameraInfo->clear();
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to remove camera"
                     " characteristics needing camera permission for device %s: %s (%d)",
-                    String8(cameraId).string(), strerror(-res), res);
+                    cameraId.c_str(), strerror(-res), res);
         }
     }
 
@@ -896,7 +878,7 @@
         if (res != OK) {
             cameraInfo->clear();
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to insert camera "
-                    "keys needing permission for device %s: %s (%d)", String8(cameraId).string(),
+                    "keys needing permission for device %s: %s (%d)", cameraId.c_str(),
                     strerror(-res), res);
         }
     }
@@ -904,7 +886,7 @@
     return ret;
 }
 
-Status CameraService::getTorchStrengthLevel(const String16& cameraId,
+Status CameraService::getTorchStrengthLevel(const std::string& cameraId,
         int32_t* torchStrength) {
     ATRACE_CALL();
     Mutex::Autolock l(mServiceLock);
@@ -918,22 +900,21 @@
         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Strength level should not be null.");
     }
 
-    status_t res = mCameraProviderManager->getTorchStrengthLevel(String8(cameraId).string(),
-        torchStrength);
+    status_t res = mCameraProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
     if (res != OK) {
         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve torch "
-            "strength level for device %s: %s (%d)", String8(cameraId).string(),
+            "strength level for device %s: %s (%d)", cameraId.c_str(),
             strerror(-res), res);
     }
     ALOGI("%s: Torch strength level is: %d", __FUNCTION__, *torchStrength);
     return Status::ok();
 }
 
-String8 CameraService::getFormattedCurrentTime() {
+std::string CameraService::getFormattedCurrentTime() {
     time_t now = time(nullptr);
     char formattedTime[64];
     strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
-    return String8(formattedTime);
+    return std::string(formattedTime);
 }
 
 Status CameraService::getCameraVendorTagDescriptor(
@@ -971,7 +952,7 @@
     BasicClient::BasicClient::sCameraService = nullptr;
 }
 
-std::pair<int, IPCTransport> CameraService::getDeviceVersion(const String8& cameraId,
+std::pair<int, IPCTransport> CameraService::getDeviceVersion(const std::string& cameraId,
         bool overrideToPortrait, int* portraitRotation, int* facing, int* orientation) {
     ATRACE_CALL();
 
@@ -980,18 +961,17 @@
     status_t res;
     hardware::hidl_version maxVersion{0,0};
     IPCTransport transport = IPCTransport::INVALID;
-    res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
-            &maxVersion, &transport);
+    res = mCameraProviderManager->getHighestSupportedVersion(cameraId, &maxVersion, &transport);
     if (res != OK || transport == IPCTransport::INVALID) {
         ALOGE("%s: Unable to get highest supported version for camera id %s", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
         return std::make_pair(-1, IPCTransport::INVALID) ;
     }
     deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
 
     hardware::CameraInfo info;
     if (facing) {
-        res = mCameraProviderManager->getCameraInfo(cameraId.string(), overrideToPortrait,
+        res = mCameraProviderManager->getCameraInfo(cameraId, overrideToPortrait,
                 portraitRotation, &info);
         if (res != OK) {
             return std::make_pair(-1, IPCTransport::INVALID);
@@ -1023,8 +1003,8 @@
 }
 
 Status CameraService::makeClient(const sp<CameraService>& cameraService,
-        const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
-        const std::optional<String16>& featureId,  const String8& cameraId,
+        const sp<IInterface>& cameraCb, const std::string& packageName, bool systemNativeClient,
+        const std::optional<std::string>& featureId,  const std::string& cameraId,
         int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
         int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
         apiLevel effectiveApiLevel, bool overrideForPerfClass, bool overrideToPortrait,
@@ -1038,7 +1018,7 @@
                 ALOGE("Camera using old HAL version: %d", deviceVersion);
                 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                         "Camera device \"%s\" HAL version %d no longer supported",
-                        cameraId.string(), deviceVersion);
+                        cameraId.c_str(), deviceVersion);
                 break;
             case CAMERA_DEVICE_API_VERSION_3_0:
             case CAMERA_DEVICE_API_VERSION_3_1:
@@ -1054,13 +1034,14 @@
                 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
                 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                         "Camera device \"%s\" has unknown HAL version %d",
-                        cameraId.string(), deviceVersion);
+                        cameraId.c_str(), deviceVersion);
         }
     }
     if (effectiveApiLevel == API_1) { // Camera1 API route
         sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
         *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
-                packageName, featureId, cameraId, api1CameraId, facing, sensorOrientation,
+                packageName, featureId, cameraId,
+                api1CameraId, facing, sensorOrientation,
                 clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
                 forceSlowJpegMode);
         ALOGI("%s: Camera1 API (legacy), override to portrait %d, forceSlowJpegMode %d",
@@ -1077,18 +1058,18 @@
     return Status::ok();
 }
 
-String8 CameraService::toString(std::set<userid_t> intSet) {
-    String8 s("");
+std::string CameraService::toString(std::set<userid_t> intSet) {
+    std::ostringstream s;
     bool first = true;
     for (userid_t i : intSet) {
         if (first) {
-            s.appendFormat("%d", i);
+            s << std::to_string(i);
             first = false;
         } else {
-            s.appendFormat(", %d", i);
+            s << ", " << std::to_string(i);
         }
     }
-    return s;
+    return std::move(s.str());
 }
 
 int32_t CameraService::mapToInterface(TorchModeStatus status) {
@@ -1154,18 +1135,17 @@
 Status CameraService::initializeShimMetadata(int cameraId) {
     int uid = CameraThreadState::getCallingUid();
 
-    String16 internalPackageName("cameraserver");
-    String8 id = String8::format("%d", cameraId);
+    std::string cameraIdStr = std::to_string(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,
+            sp<ICameraClient>{nullptr}, cameraIdStr, cameraId,
+            kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
             API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
             /*targetSdkVersion*/ __ANDROID_API_FUTURE__, /*overrideToPortrait*/ true,
             /*forceSlowJpegMode*/false, /*out*/ tmp)
             ).isOk()) {
-        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
+        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
     }
     return ret;
 }
@@ -1183,17 +1163,17 @@
         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
     }
 
-    String8 id = String8::format("%d", cameraId);
+    std::string cameraIdStr = std::to_string(cameraId);
 
     // Check if we already have parameters
     {
         // Scope for service lock
         Mutex::Autolock lock(mServiceLock);
-        auto cameraState = getCameraState(id);
+        auto cameraState = getCameraState(cameraIdStr);
         if (cameraState == nullptr) {
-            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
+            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                    "Invalid camera ID: %s", id.string());
+                    "Invalid camera ID: %s", cameraIdStr.c_str());
         }
         CameraParameters p = cameraState->getShimParams();
         if (!p.isEmpty()) {
@@ -1214,11 +1194,11 @@
     {
         // Scope for service lock
         Mutex::Autolock lock(mServiceLock);
-        auto cameraState = getCameraState(id);
+        auto cameraState = getCameraState(cameraIdStr);
         if (cameraState == nullptr) {
-            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
+            ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                    "Invalid camera ID: %s", id.string());
+                    "Invalid camera ID: %s", cameraIdStr.c_str());
         }
         CameraParameters p = cameraState->getShimParams();
         if (!p.isEmpty()) {
@@ -1244,12 +1224,13 @@
     }
 }
 
-static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
+static status_t getUidForPackage(const std::string &packageName, int userId, /*inout*/uid_t& uid,
+        int err) {
     PermissionController pc;
-    uid = pc.getPackageUid(packageName, 0);
+    uid = pc.getPackageUid(toString16(packageName), 0);
     if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(packageName).string());
-        dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
+        ALOGE("Unknown package: '%s'", packageName.c_str());
+        dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
         return BAD_VALUE;
     }
 
@@ -1263,8 +1244,8 @@
     return NO_ERROR;
 }
 
-Status CameraService::validateConnectLocked(const String8& cameraId,
-        const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
+Status CameraService::validateConnectLocked(const std::string& cameraId,
+        const std::string& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
         /*out*/int& originalClientPid) const {
 
 #ifdef __BRILLO__
@@ -1286,14 +1267,14 @@
         ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
                 callingPid);
         return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
-                "No camera HAL module available to open camera device \"%s\"", cameraId.string());
+                "No camera HAL module available to open camera device \"%s\"", cameraId.c_str());
     }
 
     if (getCameraState(cameraId) == nullptr) {
         ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
-                cameraId.string());
+                cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
-                "No camera device with ID \"%s\" available", cameraId.string());
+                "No camera device with ID \"%s\" available", cameraId.c_str());
     }
 
     status_t err = checkIfDeviceIsUsable(cameraId);
@@ -1302,17 +1283,17 @@
             case -ENODEV:
             case -EBUSY:
                 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
-                        "No camera device with ID \"%s\" currently available", cameraId.string());
+                        "No camera device with ID \"%s\" currently available", cameraId.c_str());
             default:
                 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
-                        "Unknown error connecting to ID \"%s\"", cameraId.string());
+                        "Unknown error connecting to ID \"%s\"", cameraId.c_str());
         }
     }
     return Status::ok();
 }
 
-Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
-        const String8& clientName8, int& clientUid, int& clientPid,
+Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
+        const std::string& clientName, int& clientUid, int& clientPid,
         /*out*/int& originalClientPid) const {
     permission::PermissionChecker permissionChecker;
     AttributionSourceState attributionSource{};
@@ -1329,8 +1310,8 @@
         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                 "Untrusted caller (calling PID %d, UID %d) trying to "
                 "forward camera access to camera %s for client %s (PID %d, UID %d)",
-                callingPid, callingUid, cameraId.string(),
-                clientName8.string(), clientUid, clientPid);
+                callingPid, callingUid, cameraId.c_str(),
+                clientName.c_str(), clientUid, clientPid);
     }
 
     // Check if we can trust clientPid
@@ -1342,21 +1323,21 @@
         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                 "Untrusted caller (calling PID %d, UID %d) trying to "
                 "forward camera access to camera %s for client %s (PID %d, UID %d)",
-                callingPid, callingUid, cameraId.string(),
-                clientName8.string(), clientUid, clientPid);
+                callingPid, callingUid, cameraId.c_str(),
+                clientName.c_str(), clientUid, clientPid);
     }
 
     if (shouldRejectSystemCameraConnection(cameraId)) {
         ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
                 cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" is"
-                                "available", cameraId.string());
+                                "available", cameraId.c_str());
     }
     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
     if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
-        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.string());
+        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "No camera device with ID \"%s\""
-                "found while trying to query device kind", cameraId.string());
+                "found while trying to query device kind", cameraId.c_str());
 
     }
 
@@ -1365,27 +1346,27 @@
     // android.permission.SYSTEM_CAMERA for system only camera devices).
     attributionSource.pid = clientPid;
     attributionSource.uid = clientUid;
-    attributionSource.packageName = clientName8;
+    attributionSource.packageName = clientName;
     bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+            toString16(sCameraPermission), attributionSource, String16(),
+            AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
     if (callingPid != getpid() &&
                 (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
         ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
-                clientName8.string(), clientUid, clientPid, cameraId.string());
+                clientName.c_str(), clientUid, clientPid, cameraId.c_str());
     }
 
     // Make sure the UID is in an active state to use the camera
-    if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
+    if (!mUidPolicy->isUidActive(callingUid, clientName)) {
         int32_t procState = mUidPolicy->getProcState(callingUid);
         ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
             clientPid, clientUid);
         return STATUS_ERROR_FMT(ERROR_DISABLED,
                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background ("
                 "calling UID %d proc state %" PRId32 ")",
-                clientName8.string(), clientUid, clientPid, cameraId.string(),
+                clientName.c_str(), clientUid, clientPid, cameraId.c_str(),
                 callingUid, procState);
     }
 
@@ -1394,7 +1375,7 @@
         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 "
-                "is enabled", clientName8.string(), clientUid, clientPid, cameraId.string());
+                "is enabled", clientName.c_str(), clientUid, clientPid, cameraId.c_str());
     }
 
     // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
@@ -1410,32 +1391,32 @@
             (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
         ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
                 "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
-                toString(mAllowedUsers).string());
+                toString(mAllowedUsers).c_str());
         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                 "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
-                clientUserId, cameraId.string());
+                clientUserId, cameraId.c_str());
     }
 
     return Status::ok();
 }
 
-status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
+status_t CameraService::checkIfDeviceIsUsable(const std::string& cameraId) const {
     auto cameraState = getCameraState(cameraId);
     int callingPid = CameraThreadState::getCallingPid();
     if (cameraState == nullptr) {
         ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
-                cameraId.string());
+                cameraId.c_str());
         return -ENODEV;
     }
 
     StatusInternal currentStatus = cameraState->getStatus();
     if (currentStatus == StatusInternal::NOT_PRESENT) {
         ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
-                callingPid, cameraId.string());
+                callingPid, cameraId.c_str());
         return -ENODEV;
     } else if (currentStatus == StatusInternal::ENUMERATING) {
         ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
-                callingPid, cameraId.string());
+                callingPid, cameraId.c_str());
         return -EBUSY;
     }
 
@@ -1452,13 +1433,13 @@
     auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
 
     logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
-            String8(client->getPackageName()));
+            client->getPackageName());
 
     if (evicted.size() > 0) {
         // This should never happen - clients should already have been removed in disconnect
         for (auto& i : evicted) {
             ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
-                    __FUNCTION__, i->getKey().string());
+                    __FUNCTION__, i->getKey().c_str());
         }
 
         LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
@@ -1476,12 +1457,12 @@
     }
 }
 
-status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
-        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
-        int oomScoreOffset, bool systemNativeClient,
+status_t CameraService::handleEvictionsLocked(const std::string& cameraId, int clientPid,
+        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback,
+        const std::string& packageName, int oomScoreOffset, bool systemNativeClient,
         /*out*/
         sp<BasicClient>* client,
-        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
+        std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial) {
     ATRACE_CALL();
     status_t ret = NO_ERROR;
     std::vector<DescriptorPtr> evictedClients;
@@ -1539,7 +1520,7 @@
         auto state = getCameraState(cameraId);
         if (state == nullptr) {
             ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
-                clientPid, cameraId.string());
+                clientPid, cameraId.c_str());
             // Should never get here because validateConnectLocked should have errored out
             return BAD_VALUE;
         }
@@ -1567,25 +1548,25 @@
                     " priority).", clientPid);
 
             sp<BasicClient> clientSp = clientDescriptor->getValue();
-            String8 curTime = getFormattedCurrentTime();
+            std::string curTime = getFormattedCurrentTime();
             auto incompatibleClients =
                     mActiveClientManager.getIncompatibleClients(clientDescriptor);
 
-            String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
-                    "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
-                    cameraId.string(), packageName.string(), clientPid,
+            std::string msg = fmt::sprintf("%s : DENIED connect device %s client for package %s "
+                    "(PID %d, score %d state %d) due to eviction policy", curTime.c_str(),
+                    cameraId.c_str(), packageName.c_str(), clientPid,
                     clientPriority.getScore(), clientPriority.getState());
 
             for (auto& i : incompatibleClients) {
-                msg.appendFormat("\n   - Blocked by existing device %s client for package %s"
+                msg += fmt::sprintf("\n   - Blocked by existing device %s client for package %s"
                         "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
-                        i->getKey().string(),
-                        String8{i->getValue()->getPackageName()}.string(),
+                        i->getKey().c_str(),
+                        i->getValue()->getPackageName().c_str(),
                         i->getOwnerId(), i->getPriority().getScore(),
                         i->getPriority().getState());
                 ALOGE("   Conflicts with: Device %s, client package %s (PID %"
-                        PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
-                        String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
+                        PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().c_str(),
+                        i->getValue()->getPackageName().c_str(), i->getOwnerId(),
                         i->getPriority().getScore(), i->getPriority().getState());
             }
 
@@ -1614,17 +1595,17 @@
             }
 
             ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
-                    i->getKey().string());
+                    i->getKey().c_str());
             evictedClients.push_back(i);
 
             // Log the clients evicted
-            logEvent(String8::format("EVICT device %s client held by package %s (PID"
+            logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID"
                     " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
                     " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
-                    i->getKey().string(), String8{clientSp->getPackageName()}.string(),
+                    i->getKey().c_str(), clientSp->getPackageName().c_str(),
                     i->getOwnerId(), i->getPriority().getScore(),
-                    i->getPriority().getState(), cameraId.string(),
-                    packageName.string(), clientPid, clientPriority.getScore(),
+                    i->getPriority().getState(), cameraId.c_str(),
+                    packageName.c_str(), clientPid, clientPriority.getScore(),
                     clientPriority.getState()));
 
             // Notify the client of disconnection
@@ -1650,18 +1631,18 @@
 
     for (const auto& i : evictedClients) {
         ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
-                __FUNCTION__, i->getKey().string(), i->getOwnerId());
+                __FUNCTION__, i->getKey().c_str(), i->getOwnerId());
         ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
         if (ret == TIMED_OUT) {
             ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
-                    "current clients:\n%s", __FUNCTION__, i->getKey().string(),
-                    mActiveClientManager.toString().string());
+                    "current clients:\n%s", __FUNCTION__, i->getKey().c_str(),
+                    mActiveClientManager.toString().c_str());
             return -EBUSY;
         }
         if (ret != NO_ERROR) {
             ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
-                    "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
-                    ret, mActiveClientManager.toString().string());
+                    "current clients:\n%s", __FUNCTION__, i->getKey().c_str(), strerror(-ret),
+                    ret, mActiveClientManager.toString().c_str());
             return ret;
         }
     }
@@ -1683,7 +1664,7 @@
 Status CameraService::connect(
         const sp<ICameraClient>& cameraClient,
         int api1CameraId,
-        const String16& clientPackageName,
+        const std::string& clientPackageName,
         int clientUid,
         int clientPid,
         int targetSdkVersion,
@@ -1695,16 +1676,16 @@
     ATRACE_CALL();
     Status ret = Status::ok();
 
-    String8 id = cameraIdIntToStr(api1CameraId);
+    std::string cameraIdStr = cameraIdIntToStr(api1CameraId);
     sp<Client> client = nullptr;
-    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
-            clientPackageName,/*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
+    ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
+            clientPackageName, /*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
             /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
             overrideToPortrait, forceSlowJpegMode, /*out*/client);
 
     if(!ret.isOk()) {
-        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
-                ret.toString8());
+        logRejected(cameraIdStr, CameraThreadState::getCallingPid(), clientPackageName,
+                toStdString(ret.toString8()));
         return ret;
     }
 
@@ -1735,7 +1716,7 @@
     return false;
 }
 
-bool CameraService::shouldRejectSystemCameraConnection(const String8& cameraId) const {
+bool CameraService::shouldRejectSystemCameraConnection(const std::string& cameraId) const {
     // Rules for rejection:
     // 1) If cameraserver tries to access this camera device, accept the
     //    connection.
@@ -1780,9 +1761,9 @@
 
 Status CameraService::connectDevice(
         const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
-        const String16& cameraId,
-        const String16& clientPackageName,
-        const std::optional<String16>& clientFeatureId,
+        const std::string& cameraId,
+        const std::string& clientPackageName,
+        const std::optional<std::string>& clientFeatureId,
         int clientUid, int oomScoreOffset, int targetSdkVersion,
         bool overrideToPortrait,
         /*out*/
@@ -1790,25 +1771,24 @@
 
     ATRACE_CALL();
     Status ret = Status::ok();
-    String8 id = String8(cameraId);
     sp<CameraDeviceClient> client = nullptr;
-    String16 clientPackageNameAdj = clientPackageName;
+    std::string clientPackageNameAdj = clientPackageName;
     int callingPid = CameraThreadState::getCallingPid();
     bool systemNativeClient = false;
     if (doesClientHaveSystemUid() && (clientPackageNameAdj.size() == 0)) {
         std::string systemClient =
-                StringPrintf("client.pid<%d>", CameraThreadState::getCallingPid());
-        clientPackageNameAdj = String16(systemClient.c_str());
+                fmt::sprintf("client.pid<%d>", CameraThreadState::getCallingPid());
+        clientPackageNameAdj = systemClient;
         systemNativeClient = true;
     }
 
     if (oomScoreOffset < 0) {
-        String8 msg =
-                String8::format("Cannot increase the priority of a client %s pid %d for "
-                        "camera id %s", String8(clientPackageNameAdj).string(), callingPid,
-                        id.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg =
+                fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
+                        "camera id %s", clientPackageNameAdj.c_str(), callingPid,
+                        cameraId.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     userid_t clientUserId = multiuser_get_user_id(clientUid);
@@ -1818,32 +1798,30 @@
     }
 
     if (mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
-        String8 msg =
-                String8::format("Camera disabled by device policy");
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(ERROR_DISABLED, msg.string());
+        std::string msg = "Camera disabled by device policy";
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(ERROR_DISABLED, msg.c_str());
     }
 
     // enforce system camera permissions
     if (oomScoreOffset > 0 &&
             !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid()) &&
             !isTrustedCallingUid(CameraThreadState::getCallingUid())) {
-        String8 msg =
-                String8::format("Cannot change the priority of a client %s pid %d for "
+        std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
                         "camera id %s without SYSTEM_CAMERA permissions",
-                        String8(clientPackageNameAdj).string(), callingPid, id.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.string());
+                        clientPackageNameAdj.c_str(), callingPid, cameraId.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
     }
 
-    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
-            /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient,clientFeatureId,
+    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb,
+            cameraId, /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient, clientFeatureId,
             clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
             targetSdkVersion, overrideToPortrait, /*forceSlowJpegMode*/false,
             /*out*/client);
 
     if(!ret.isOk()) {
-        logRejected(id, callingPid, String8(clientPackageNameAdj), ret.toString8());
+        logRejected(cameraId, callingPid, clientPackageNameAdj, toStdString(ret.toString8()));
         return ret;
     }
 
@@ -1874,11 +1852,11 @@
     return ret;
 }
 
-String16 CameraService::getPackageNameFromUid(int clientUid) {
-    String16 packageName("");
+std::string CameraService::getPackageNameFromUid(int clientUid) {
+    std::string packageName("");
 
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
+    sp<IBinder> binder = sm->getService(toString16(kPermissionServiceName));
     if (binder == 0) {
         ALOGE("Cannot get permission service");
         // Return empty package name and the further interaction
@@ -1899,22 +1877,22 @@
     }
 
     // Arbitrarily pick the first name in the list
-    packageName = packages[0];
+    packageName = toStdString(packages[0]);
 
     return packageName;
 }
 
 template<class CALLBACK, class CLIENT>
-Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
-        int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
-        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
+Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
+        int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
+        const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
         apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
         bool overrideToPortrait, bool forceSlowJpegMode,
         /*out*/sp<CLIENT>& device) {
     binder::Status ret = binder::Status::ok();
 
     bool isNonSystemNdk = false;
-    String16 clientPackageName;
+    std::string clientPackageName;
     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
@@ -1929,14 +1907,12 @@
         clientPackageName = clientPackageNameMaybe;
     }
 
-    String8 clientName8(clientPackageName);
-
     int originalClientPid = 0;
 
     int packagePid = (clientPid == USE_CALLING_PID) ?
         CameraThreadState::getCallingPid() : clientPid;
     ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
-            "Camera API version %d", packagePid, clientName8.string(), cameraId.string(),
+            "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
             static_cast<int>(effectiveApiLevel));
 
     nsecs_t openTimeNs = systemTime();
@@ -1955,11 +1931,11 @@
                     , clientPid);
             return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                     "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
-                    cameraId.string(), clientName8.string(), clientPid);
+                    cameraId.c_str(), clientPackageName.c_str(), clientPid);
         }
 
         // Enforce client permissions and do basic validity checks
-        if(!(ret = validateConnectLocked(cameraId, clientName8,
+        if(!(ret = validateConnectLocked(cameraId, clientPackageName,
                 /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
             return ret;
         }
@@ -1976,27 +1952,27 @@
         status_t err;
 
         sp<BasicClient> clientTmp = nullptr;
-        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
+        std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>> partial;
         if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
-                IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, systemNativeClient,
-                /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
+                IInterface::asBinder(cameraCb), clientPackageName, oomScoreOffset,
+                systemNativeClient, /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
             switch (err) {
                 case -ENODEV:
                     return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                             "No camera device with ID \"%s\" currently available",
-                            cameraId.string());
+                            cameraId.c_str());
                 case -EBUSY:
                     return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                             "Higher-priority client using camera, ID \"%s\" currently unavailable",
-                            cameraId.string());
+                            cameraId.c_str());
                 case -EUSERS:
                     return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                             "Too many cameras already open, cannot open camera \"%s\"",
-                            cameraId.string());
+                            cameraId.c_str());
                 default:
                     return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                             "Unexpected error %s (%d) opening camera \"%s\"",
-                            strerror(-err), err, cameraId.string());
+                            strerror(-err), err, cameraId.c_str());
             }
         }
 
@@ -2014,17 +1990,17 @@
                 getDeviceVersion(cameraId, overrideToPortrait, /*out*/&portraitRotation,
                         /*out*/&facing, /*out*/&orientation);
         if (facing == -1) {
-            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
+            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.c_str());
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
-                    "Unable to get camera device \"%s\" facing", cameraId.string());
+                    "Unable to get camera device \"%s\" facing", cameraId.c_str());
         }
 
         sp<BasicClient> tmp = nullptr;
         bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
-                mPerfClassPrimaryCameraIds, cameraId.string(), targetSdkVersion);
+                mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion);
         if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
-                clientFeatureId, cameraId, api1CameraId, facing, orientation,
-                clientPid, clientUid, getpid(),
+                clientFeatureId, cameraId, api1CameraId, facing,
+                orientation, clientPid, clientUid, getpid(),
                 deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                 overrideToPortrait, forceSlowJpegMode,
                 /*out*/&tmp)).isOk()) {
@@ -2035,7 +2011,7 @@
         LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                 __FUNCTION__);
 
-        String8 monitorTags = isClientWatched(client.get()) ? mMonitorTags : String8("");
+        std::string monitorTags = isClientWatched(client.get()) ? mMonitorTags : std::string();
         err = client->initialize(mCameraProviderManager, monitorTags);
         if (err != OK) {
             ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
@@ -2043,24 +2019,24 @@
             switch(err) {
                 case BAD_VALUE:
                     return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
+                            "Illegal argument to HAL module for camera \"%s\"", cameraId.c_str());
                 case -EBUSY:
                     return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
-                            "Camera \"%s\" is already open", cameraId.string());
+                            "Camera \"%s\" is already open", cameraId.c_str());
                 case -EUSERS:
                     return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                             "Too many cameras already open, cannot open camera \"%s\"",
-                            cameraId.string());
+                            cameraId.c_str());
                 case PERMISSION_DENIED:
                     return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
-                            "No permission to open camera \"%s\"", cameraId.string());
+                            "No permission to open camera \"%s\"", cameraId.c_str());
                 case -EACCES:
                     return STATUS_ERROR_FMT(ERROR_DISABLED,
-                            "Camera \"%s\" disabled by policy", cameraId.string());
+                            "Camera \"%s\" disabled by policy", cameraId.c_str());
                 case -ENODEV:
                 default:
                     return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
-                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
+                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.c_str(),
                             strerror(-err), err);
             }
         }
@@ -2077,7 +2053,7 @@
                 cameraState->setShimParams(params);
             } else {
                 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
-                        __FUNCTION__, cameraId.string());
+                        __FUNCTION__, cameraId.c_str());
             }
         }
 
@@ -2128,7 +2104,7 @@
         } 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());
+                    client->getPackageName().c_str(), cameraId.c_str());
             // Do not hold mServiceLock while disconnecting clients, but
             // retain the condition blocking other clients from connecting
             // in mServiceLockWrapper if held.
@@ -2144,7 +2120,7 @@
             mServiceLock.lock();
 
             return STATUS_ERROR_FMT(ERROR_DISABLED,
-                    "Camera \"%s\" disabled due to camera mute", cameraId.string());
+                    "Camera \"%s\" disabled due to camera mute", cameraId.c_str());
         }
 
         if (shimUpdateOnly) {
@@ -2182,7 +2158,7 @@
                 if(res != OK) {
                     return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                             "No camera device with ID \"%s\" currently available",
-                            mInjectionExternalCamId.string());
+                            mInjectionExternalCamId.c_str());
                 }
                 res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
                 if (res != OK) {
@@ -2190,7 +2166,7 @@
                 }
             } else {
                 ALOGE("%s: Internal camera ID = %s 's client does not exist!",
-                        __FUNCTION__, mInjectionInternalCamId.string());
+                        __FUNCTION__, mInjectionInternalCamId.c_str());
                 res = NO_INIT;
                 mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res);
             }
@@ -2200,7 +2176,8 @@
     return ret;
 }
 
-status_t CameraService::addOfflineClient(String8 cameraId, sp<BasicClient> offlineClient) {
+status_t CameraService::addOfflineClient(const std::string &cameraId,
+        sp<BasicClient> offlineClient) {
     if (offlineClient.get() == nullptr) {
         return BAD_VALUE;
     }
@@ -2229,7 +2206,7 @@
         const auto& onlinePriority = onlineClientDesc->getPriority();
         auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
                 kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
-                /*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
+                /*conflictingKeys*/ std::set<std::string>(), onlinePriority.getScore(),
                 onlineClientDesc->getOwnerId(), onlinePriority.getState(),
                 // native clients don't have offline processing support.
                 /*ommScoreOffset*/ 0, /*systemNativeClient*/false);
@@ -2245,7 +2222,8 @@
             return BAD_VALUE;
         }
 
-        String8 monitorTags = isClientWatched(offlineClient.get()) ? mMonitorTags : String8("");
+        std::string monitorTags = isClientWatched(offlineClient.get())
+                ? mMonitorTags : std::string();
         auto err = offlineClient->initialize(mCameraProviderManager, monitorTags);
         if (err != OK) {
             ALOGE("%s: Could not initialize offline client.", __FUNCTION__);
@@ -2256,7 +2234,7 @@
         if (evicted.size() > 0) {
             for (auto& i : evicted) {
                 ALOGE("%s: Invalid state: Offline client for camera %s was not removed ",
-                        __FUNCTION__, i->getKey().string());
+                        __FUNCTION__, i->getKey().c_str());
             }
 
             LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, offline clients not evicted "
@@ -2267,7 +2245,7 @@
 
         logConnectedOffline(offlineClientDesc->getKey(),
                 static_cast<int>(offlineClientDesc->getOwnerId()),
-                String8(offlineClient->getPackageName()));
+                offlineClient->getPackageName());
 
         sp<IBinder> remoteCallback = offlineClient->getRemote();
         if (remoteCallback != nullptr) {
@@ -2278,8 +2256,8 @@
     return OK;
 }
 
-Status CameraService::turnOnTorchWithStrengthLevel(const String16& cameraId, int32_t torchStrength,
-        const sp<IBinder>& clientBinder) {
+Status CameraService::turnOnTorchWithStrengthLevel(const std::string& cameraId,
+        int32_t torchStrength, const sp<IBinder>& clientBinder) {
     Mutex::Autolock lock(mServiceLock);
 
     ATRACE_CALL();
@@ -2289,60 +2267,59 @@
                 "Torch client binder in null.");
     }
 
-    String8 id = String8(cameraId.string());
     int uid = CameraThreadState::getCallingUid();
 
-    if (shouldRejectSystemCameraConnection(id)) {
+    if (shouldRejectSystemCameraConnection(cameraId)) {
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to change the strength level"
-                "for system only device %s: ", id.string());
+                "for system only device %s: ", cameraId.c_str());
     }
 
     // verify id is valid
-    auto state = getCameraState(id);
+    auto state = getCameraState(cameraId);
     if (state == nullptr) {
-        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
+        ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-            "Camera ID \"%s\" is a not valid camera ID", id.string());
+            "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
     }
 
     StatusInternal cameraStatus = state->getStatus();
     if (cameraStatus != StatusInternal::NOT_AVAILABLE &&
             cameraStatus != StatusInternal::PRESENT) {
-        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(),
+        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
             (int)cameraStatus);
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                "Camera ID \"%s\" is a not valid camera ID", id.string());
+                "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
     }
 
     {
         Mutex::Autolock al(mTorchStatusMutex);
         TorchModeStatus status;
-        status_t err = getTorchStatusLocked(id, &status);
+        status_t err = getTorchStatusLocked(cameraId, &status);
         if (err != OK) {
             if (err == NAME_NOT_FOUND) {
              return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                    "Camera \"%s\" does not have a flash unit", id.string());
+                    "Camera \"%s\" does not have a flash unit", cameraId.c_str());
             }
             ALOGE("%s: getting current torch status failed for camera %s",
-                    __FUNCTION__, id.string());
+                    __FUNCTION__, cameraId.c_str());
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                     "Error changing torch strength level for camera \"%s\": %s (%d)",
-                    id.string(), strerror(-err), err);
+                    cameraId.c_str(), strerror(-err), err);
         }
 
         if (status == TorchModeStatus::NOT_AVAILABLE) {
             if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
                 ALOGE("%s: torch mode of camera %s is not available because "
-                        "camera is in use.", __FUNCTION__, id.string());
+                        "camera is in use.", __FUNCTION__, cameraId.c_str());
                 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                         "Torch for camera \"%s\" is not available due to an existing camera user",
-                        id.string());
+                        cameraId.c_str());
             } else {
                 ALOGE("%s: torch mode of camera %s is not available due to "
-                       "insufficient resources", __FUNCTION__, id.string());
+                       "insufficient resources", __FUNCTION__, cameraId.c_str());
                 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                         "Torch for camera \"%s\" is not available due to insufficient resources",
-                        id.string());
+                        cameraId.c_str());
             }
         }
     }
@@ -2353,44 +2330,44 @@
     }
     // Check if the current torch strength level is same as the new one.
     bool shouldSkipTorchStrengthUpdates = mCameraProviderManager->shouldSkipTorchStrengthUpdate(
-            id.string(), torchStrength);
+            cameraId, torchStrength);
 
-    status_t err = mFlashlight->turnOnTorchWithStrengthLevel(id, torchStrength);
+    status_t err = mFlashlight->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
 
     if (err != OK) {
         int32_t errorCode;
-        String8 msg;
+        std::string msg;
         switch (err) {
             case -ENOSYS:
-                msg = String8::format("Camera \"%s\" has no flashlight.",
-                    id.string());
+                msg = fmt::sprintf("Camera \"%s\" has no flashlight.",
+                    cameraId.c_str());
                 errorCode = ERROR_ILLEGAL_ARGUMENT;
                 break;
             case -EBUSY:
-                msg = String8::format("Camera \"%s\" is in use",
-                    id.string());
+                msg = fmt::sprintf("Camera \"%s\" is in use",
+                    cameraId.c_str());
                 errorCode = ERROR_CAMERA_IN_USE;
                 break;
             case -EINVAL:
-                msg = String8::format("Torch strength level %d is not within the "
+                msg = fmt::sprintf("Torch strength level %d is not within the "
                         "valid range.", torchStrength);
                 errorCode = ERROR_ILLEGAL_ARGUMENT;
                 break;
             default:
-                msg = String8::format("Changing torch strength level failed.");
+                msg = "Changing torch strength level failed.";
                 errorCode = ERROR_INVALID_OPERATION;
         }
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(errorCode, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(errorCode, msg.c_str());
     }
 
     {
         // update the link to client's death
         // Store the last client that turns on each camera's torch mode.
         Mutex::Autolock al(mTorchClientMapMutex);
-        ssize_t index = mTorchClientMap.indexOfKey(id);
+        ssize_t index = mTorchClientMap.indexOfKey(cameraId);
         if (index == NAME_NOT_FOUND) {
-            mTorchClientMap.add(id, clientBinder);
+            mTorchClientMap.add(cameraId, clientBinder);
         } else {
             mTorchClientMap.valueAt(index)->unlinkToDeath(this);
             mTorchClientMap.replaceValueAt(index, clientBinder);
@@ -2399,16 +2376,15 @@
     }
 
     int clientPid = CameraThreadState::getCallingPid();
-    const char *id_cstr = id.c_str();
     ALOGI("%s: Torch strength for camera id %s changed to %d for client PID %d",
-            __FUNCTION__, id_cstr, torchStrength, clientPid);
+            __FUNCTION__, cameraId.c_str(), torchStrength, clientPid);
     if (!shouldSkipTorchStrengthUpdates) {
-        broadcastTorchStrengthLevel(id, torchStrength);
+        broadcastTorchStrengthLevel(cameraId, torchStrength);
     }
     return Status::ok();
 }
 
-Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
+Status CameraService::setTorchMode(const std::string& cameraId, bool enabled,
         const sp<IBinder>& clientBinder) {
     Mutex::Autolock lock(mServiceLock);
 
@@ -2419,58 +2395,58 @@
                 "Torch client Binder is null");
     }
 
-    String8 id = String8(cameraId.string());
     int uid = CameraThreadState::getCallingUid();
 
-    if (shouldRejectSystemCameraConnection(id)) {
+    if (shouldRejectSystemCameraConnection(cameraId)) {
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode"
-                " for system only device %s: ", id.string());
+                " for system only device %s: ", cameraId.c_str());
     }
     // verify id is valid.
-    auto state = getCameraState(id);
+    auto state = getCameraState(cameraId);
     if (state == nullptr) {
-        ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
+        ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                "Camera ID \"%s\" is a not valid camera ID", id.string());
+                "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
     }
 
     StatusInternal cameraStatus = state->getStatus();
     if (cameraStatus != StatusInternal::PRESENT &&
             cameraStatus != StatusInternal::NOT_AVAILABLE) {
-        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
+        ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
+                (int)cameraStatus);
         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                "Camera ID \"%s\" is a not valid camera ID", id.string());
+                "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
     }
 
     {
         Mutex::Autolock al(mTorchStatusMutex);
         TorchModeStatus status;
-        status_t err = getTorchStatusLocked(id, &status);
+        status_t err = getTorchStatusLocked(cameraId, &status);
         if (err != OK) {
             if (err == NAME_NOT_FOUND) {
                 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
-                        "Camera \"%s\" does not have a flash unit", id.string());
+                        "Camera \"%s\" does not have a flash unit", cameraId.c_str());
             }
             ALOGE("%s: getting current torch status failed for camera %s",
-                    __FUNCTION__, id.string());
+                    __FUNCTION__, cameraId.c_str());
             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
-                    "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
+                    "Error updating torch status for camera \"%s\": %s (%d)", cameraId.c_str(),
                     strerror(-err), err);
         }
 
         if (status == TorchModeStatus::NOT_AVAILABLE) {
             if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
                 ALOGE("%s: torch mode of camera %s is not available because "
-                        "camera is in use", __FUNCTION__, id.string());
+                        "camera is in use", __FUNCTION__, cameraId.c_str());
                 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                         "Torch for camera \"%s\" is not available due to an existing camera user",
-                        id.string());
+                        cameraId.c_str());
             } else {
                 ALOGE("%s: torch mode of camera %s is not available due to "
-                        "insufficient resources", __FUNCTION__, id.string());
+                        "insufficient resources", __FUNCTION__, cameraId.c_str());
                 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                         "Torch for camera \"%s\" is not available due to insufficient resources",
-                        id.string());
+                        cameraId.c_str());
             }
         }
     }
@@ -2482,40 +2458,40 @@
         updateTorchUidMapLocked(cameraId, uid);
     }
 
-    status_t err = mFlashlight->setTorchMode(id, enabled);
+    status_t err = mFlashlight->setTorchMode(cameraId, enabled);
 
     if (err != OK) {
         int32_t errorCode;
-        String8 msg;
+        std::string msg;
         switch (err) {
             case -ENOSYS:
-                msg = String8::format("Camera \"%s\" has no flashlight",
-                    id.string());
+                msg = fmt::sprintf("Camera \"%s\" has no flashlight",
+                    cameraId.c_str());
                 errorCode = ERROR_ILLEGAL_ARGUMENT;
                 break;
             case -EBUSY:
-                msg = String8::format("Camera \"%s\" is in use",
-                    id.string());
+                msg = fmt::sprintf("Camera \"%s\" is in use",
+                    cameraId.c_str());
                 errorCode = ERROR_CAMERA_IN_USE;
                 break;
             default:
-                msg = String8::format(
+                msg = fmt::sprintf(
                     "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
-                    id.string(), enabled, strerror(-err), err);
+                    cameraId.c_str(), enabled, strerror(-err), err);
                 errorCode = ERROR_INVALID_OPERATION;
         }
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        logServiceError(msg,errorCode);
-        return STATUS_ERROR(errorCode, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        logServiceError(msg, errorCode);
+        return STATUS_ERROR(errorCode, msg.c_str());
     }
 
     {
         // update the link to client's death
         Mutex::Autolock al(mTorchClientMapMutex);
-        ssize_t index = mTorchClientMap.indexOfKey(id);
+        ssize_t index = mTorchClientMap.indexOfKey(cameraId);
         if (enabled) {
             if (index == NAME_NOT_FOUND) {
-                mTorchClientMap.add(id, clientBinder);
+                mTorchClientMap.add(cameraId, clientBinder);
             } else {
                 mTorchClientMap.valueAt(index)->unlinkToDeath(this);
                 mTorchClientMap.replaceValueAt(index, clientBinder);
@@ -2527,21 +2503,20 @@
     }
 
     int clientPid = CameraThreadState::getCallingPid();
-    const char *id_cstr = id.c_str();
-    const char *torchState = enabled ? "on" : "off";
-    ALOGI("Torch for camera id %s turned %s for client PID %d", id_cstr, torchState, clientPid);
-    logTorchEvent(id_cstr, torchState , clientPid);
+    std::string torchState = enabled ? "on" : "off";
+    ALOGI("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
+            torchState.c_str(), clientPid);
+    logTorchEvent(cameraId, torchState, clientPid);
     return Status::ok();
 }
 
-void CameraService::updateTorchUidMapLocked(const String16& cameraId, int uid) {
-    String8 id = String8(cameraId.string());
-    if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
-        mTorchUidMap[id].first = uid;
-        mTorchUidMap[id].second = uid;
+void CameraService::updateTorchUidMapLocked(const std::string& cameraId, int uid) {
+    if (mTorchUidMap.find(cameraId) == mTorchUidMap.end()) {
+        mTorchUidMap[cameraId].first = uid;
+        mTorchUidMap[cameraId].second = uid;
     } else {
         // Set the pending UID
-        mTorchUidMap[id].first = uid;
+        mTorchUidMap[cameraId].first = uid;
     }
 }
 
@@ -2554,7 +2529,7 @@
     if (pid != selfPid) {
         // Ensure we're being called by system_server, or similar process with
         // permissions to notify the camera service about system events
-        if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+        if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
             const int uid = CameraThreadState::getCallingUid();
             ALOGE("Permission Denial: cannot send updates to camera service about system"
                     " events from pid=%d, uid=%d", pid, uid);
@@ -2577,6 +2552,11 @@
         }
         case ICameraService::EVENT_USB_DEVICE_ATTACHED:
         case ICameraService::EVENT_USB_DEVICE_DETACHED: {
+            if (args.size() != 1) {
+                return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT,
+                    "USB Device Event requires 1 argument");
+            }
+
             // Notify CameraProviderManager for lazy HALs
             mCameraProviderManager->notifyUsbDeviceEvent(eventId,
                                                         std::to_string(args[0]));
@@ -2623,7 +2603,7 @@
     if (pid != selfPid) {
         // Ensure we're being called by system_server, or similar process with
         // permissions to notify the camera service about system events
-        if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+        if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
             const int uid = CameraThreadState::getCallingUid();
             ALOGE("Permission Denial: cannot send updates to camera service about device"
                     " state changes from pid=%d, uid=%d", pid, uid);
@@ -2654,7 +2634,7 @@
     if (callingPid != selfPid) {
         // Ensure we're being called by system_server, or similar process with
         // permissions to notify the camera service about system events
-        if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+        if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
             const int uid = CameraThreadState::getCallingUid();
             ALOGE("Permission Denial: cannot send updates to camera service about orientation"
                     " changes from pid=%d, uid=%d", callingPid, uid);
@@ -2696,7 +2676,7 @@
 
     if (!mInitialized) {
         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
-        logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+        logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
         return STATUS_ERROR(ERROR_DISCONNECTED,
                 "Camera subsystem is not available");
     }
@@ -2708,8 +2688,7 @@
         std::vector<std::string> validCombination;
         for (auto &cameraId : combination) {
             // if the camera state is not present, skip
-            String8 cameraIdStr(cameraId.c_str());
-            auto state = getCameraState(cameraIdStr);
+            auto state = getCameraState(cameraId);
             if (state == nullptr) {
                 ALOGW("%s: camera id %s does not exist", __FUNCTION__, cameraId.c_str());
                 continue;
@@ -2718,7 +2697,7 @@
             if (status == StatusInternal::NOT_PRESENT || status == StatusInternal::ENUMERATING) {
                 continue;
             }
-            if (shouldRejectSystemCameraConnection(cameraIdStr)) {
+            if (shouldRejectSystemCameraConnection(cameraId)) {
                 continue;
             }
             validCombination.push_back(cameraId);
@@ -2752,8 +2731,8 @@
     attributionSource.pid = callingPid;
     attributionSource.uid = callingUid;
     bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
-                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
-                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+                toString16(sCameraPermission), attributionSource, String16(),
+                AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
     if ((callingPid != getpid()) && !checkPermissionForCamera) {
         ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
         return STATUS_ERROR(ERROR_PERMISSION_DENIED,
@@ -2766,7 +2745,7 @@
                     cameraIdsAndSessionConfigurations, mPerfClassPrimaryCameraIds,
                     targetSdkVersion, isSupported);
     if (res != OK) {
-        logServiceError(String8::format("Unable to query session configuration support"),
+        logServiceError("Unable to query session configuration support",
             ERROR_INVALID_OPERATION);
         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query session configuration "
                 "support %s (%d)", strerror(-res), res);
@@ -2806,7 +2785,7 @@
     attributionSource.uid = clientUid;
     attributionSource.pid = clientPid;
     bool openCloseCallbackAllowed = permissionChecker.checkPermissionForPreflight(
-            sCameraOpenCloseListenerPermission, attributionSource, String16(),
+            toString16(sCameraOpenCloseListenerPermission), attributionSource, String16(),
             AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
 
     Mutex::Autolock lock(mServiceLock);
@@ -2826,11 +2805,11 @@
                         openCloseCallbackAllowed);
         auto ret = serviceListener->initialize(isProcessLocalTest);
         if (ret != NO_ERROR) {
-            String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
+            std::string msg = fmt::sprintf("Failed to initialize service listener: %s (%d)",
                     strerror(-ret), ret);
-            logServiceError(msg,ERROR_ILLEGAL_ARGUMENT);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+            logServiceError(msg, ERROR_ILLEGAL_ARGUMENT);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
         // The listener still needs to be added to the list of listeners, regardless of what
         // permissions the listener process has / whether it is a vendor listener. Since it might be
@@ -2845,7 +2824,7 @@
         for (auto& i : mCameraStates) {
             cameraStatuses->emplace_back(i.first,
                     mapToInterface(i.second->getStatus()), i.second->getUnavailablePhysicalIds(),
-                    openCloseCallbackAllowed ? i.second->getClientPackage() : String8::empty());
+                    openCloseCallbackAllowed ? i.second->getClientPackage() : std::string());
         }
     }
     // Remove the camera statuses that should be hidden from the client, we do
@@ -2864,9 +2843,9 @@
                             clientUid);}), cameraStatuses->end());
 
     //cameraStatuses will have non-eligible camera ids removed.
-    std::set<String16> idsChosenForCallback;
+    std::set<std::string> idsChosenForCallback;
     for (const auto &s : *cameraStatuses) {
-        idsChosenForCallback.insert(String16(s.cameraId));
+        idsChosenForCallback.insert(s.cameraId);
     }
 
     /*
@@ -2876,7 +2855,7 @@
     {
         Mutex::Autolock al(mTorchStatusMutex);
         for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
-            String16 id = String16(mTorchStatusMap.keyAt(i).string());
+            const std::string &id = mTorchStatusMap.keyAt(i);
             // The camera id is visible to the client. Fine to send torch
             // callback.
             if (idsChosenForCallback.find(id) != idsChosenForCallback.end()) {
@@ -2918,7 +2897,7 @@
     return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
 }
 
-Status CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
+Status CameraService::getLegacyParameters(int cameraId, /*out*/std::string* parameters) {
 
     ATRACE_CALL();
     ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
@@ -2937,37 +2916,34 @@
     }
 
     String8 shimParamsString8 = shimParams.flatten();
-    String16 shimParamsString16 = String16(shimParamsString8);
 
-    *parameters = shimParamsString16;
+    *parameters = toStdString(shimParamsString8);
 
     return ret;
 }
 
-Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
+Status CameraService::supportsCameraApi(const std::string& cameraId, int apiVersion,
         /*out*/ bool *isSupported) {
     ATRACE_CALL();
 
-    const String8 id = String8(cameraId);
-
-    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
+    ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
 
     switch (apiVersion) {
         case API_VERSION_1:
         case API_VERSION_2:
             break;
         default:
-            String8 msg = String8::format("Unknown API version %d", apiVersion);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+            std::string msg = fmt::sprintf("Unknown API version %d", apiVersion);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     int portraitRotation;
-    auto deviceVersionAndTransport = getDeviceVersion(id, false, &portraitRotation);
+    auto deviceVersionAndTransport = getDeviceVersion(cameraId, false, &portraitRotation);
     if (deviceVersionAndTransport.first == -1) {
-        String8 msg = String8::format("Unknown camera ID %s", id.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Unknown camera ID %s", cameraId.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
         int deviceVersion = deviceVersionAndTransport.first;
@@ -2977,11 +2953,11 @@
             case CAMERA_DEVICE_API_VERSION_3_1:
                 if (apiVersion == API_VERSION_2) {
                     ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without "
-                            "shim", __FUNCTION__, id.string(), deviceVersion);
+                            "shim", __FUNCTION__, cameraId.c_str(), deviceVersion);
                     *isSupported = false;
                 } else { // if (apiVersion == API_VERSION_1) {
                     ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always "
-                            "supported", __FUNCTION__, id.string());
+                            "supported", __FUNCTION__, cameraId.c_str());
                     *isSupported = true;
                 }
                 break;
@@ -2992,14 +2968,14 @@
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_7:
                 ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
-                        __FUNCTION__, id.string());
+                        __FUNCTION__, cameraId.c_str());
                 *isSupported = true;
                 break;
             default: {
-                String8 msg = String8::format("Unknown device version %x for device %s",
-                        deviceVersion, id.string());
-                ALOGE("%s: %s", __FUNCTION__, msg.string());
-                return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
+                std::string msg = fmt::sprintf("Unknown device version %x for device %s",
+                        deviceVersion, cameraId.c_str());
+                ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+                return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.c_str());
             }
         }
     } else {
@@ -3008,27 +2984,25 @@
     return Status::ok();
 }
 
-Status CameraService::isHiddenPhysicalCamera(const String16& cameraId,
+Status CameraService::isHiddenPhysicalCamera(const std::string& cameraId,
         /*out*/ bool *isSupported) {
     ATRACE_CALL();
 
-    const String8 id = String8(cameraId);
-
-    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
-    *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(id.string());
+    ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
+    *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(cameraId);
 
     return Status::ok();
 }
 
 Status CameraService::injectCamera(
-        const String16& packageName, const String16& internalCamId,
-        const String16& externalCamId,
+        const std::string& packageName, const std::string& internalCamId,
+        const std::string& externalCamId,
         const sp<ICameraInjectionCallback>& callback,
         /*out*/
         sp<ICameraInjectionSession>* cameraInjectionSession) {
     ATRACE_CALL();
 
-    if (!checkCallingPermission(sCameraInjectExternalCameraPermission)) {
+    if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) {
         const int pid = CameraThreadState::getCallingPid();
         const int uid = CameraThreadState::getCallingUid();
         ALOGE("Permission Denial: can't inject camera pid=%d, uid=%d", pid, uid);
@@ -3039,13 +3013,13 @@
     ALOGV(
         "%s: Package name = %s, Internal camera ID = %s, External camera ID = "
         "%s",
-        __FUNCTION__, String8(packageName).string(),
-        String8(internalCamId).string(), String8(externalCamId).string());
+        __FUNCTION__, packageName.c_str(),
+        internalCamId.c_str(), externalCamId.c_str());
 
     {
         Mutex::Autolock lock(mInjectionParametersLock);
-        mInjectionInternalCamId = String8(internalCamId);
-        mInjectionExternalCamId = String8(externalCamId);
+        mInjectionInternalCamId = internalCamId;
+        mInjectionExternalCamId = externalCamId;
         mInjectionStatusListener->addListener(callback);
         *cameraInjectionSession = new CameraInjectionSession(this);
         status_t res = NO_ERROR;
@@ -3060,7 +3034,7 @@
             if(res != OK) {
                 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                         "No camera device with ID \"%s\" currently available",
-                        mInjectionExternalCamId.string());
+                        mInjectionExternalCamId.c_str());
             }
             res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
             if(res != OK) {
@@ -3075,7 +3049,7 @@
 }
 
 Status CameraService::reportExtensionSessionStats(
-        const hardware::CameraExtensionSessionStats& stats, String16* sessionKey /*out*/) {
+        const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/) {
     ALOGV("%s: reported %s", __FUNCTION__, stats.toString().c_str());
     *sessionKey = mCameraServiceProxyWrapper->updateExtensionStats(stats);
     return Status::ok();
@@ -3142,7 +3116,7 @@
 }
 
 std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
-        const String8& cameraId) const {
+        const std::string& cameraId) const {
     std::shared_ptr<CameraState> state;
     {
         Mutex::Autolock lock(mCameraStatesLock);
@@ -3154,12 +3128,12 @@
     return state;
 }
 
-sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
+sp<CameraService::BasicClient> CameraService::removeClientLocked(const std::string& cameraId) {
     // Remove from active clients list
     auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
     if (clientDescriptorPtr == nullptr) {
         ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
         return sp<BasicClient>{nullptr};
     }
 
@@ -3214,16 +3188,14 @@
 
         evicted.push_back(clientSp);
 
-        String8 curTime = getFormattedCurrentTime();
-
         ALOGE("Evicting conflicting client for camera ID %s due to user change",
-                i->getKey().string());
+                i->getKey().c_str());
 
         // Log the clients evicted
-        logEvent(String8::format("EVICT device %s client held by package %s (PID %"
+        logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID %"
                 PRId32 ", score %" PRId32 ", state %" PRId32 ")\n   - Evicted due"
-                " to user switch.", i->getKey().string(),
-                String8{clientSp->getPackageName()}.string(),
+                " to user switch.", i->getKey().c_str(),
+                clientSp->getPackageName().c_str(),
                 i->getOwnerId(), i->getPriority().getScore(),
                 i->getPriority().getState()));
 
@@ -3246,12 +3218,12 @@
     mServiceLock.lock();
 }
 
-void CameraService::logEvent(const char* event) {
-    String8 curTime = getFormattedCurrentTime();
+void CameraService::logEvent(const std::string &event) {
+    std::string curTime = getFormattedCurrentTime();
     Mutex::Autolock l(mLogLock);
-    String8 msg = String8::format("%s : %s", curTime.string(), event);
+    std::string msg = curTime + " : " + event;
     // For service error events, print the msg only once.
-    if(!msg.contains("SERVICE ERROR")) {
+    if (msg.find("SERVICE ERROR") != std::string::npos) {
         mEventLog.add(msg);
     } else if(sServiceErrorEventSet.find(msg) == sServiceErrorEventSet.end()) {
         // Error event not added to the dumpsys log before
@@ -3260,77 +3232,78 @@
     }
 }
 
-void CameraService::logDisconnected(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+void CameraService::logDisconnected(const std::string &cameraId, int clientPid,
+        const std::string &clientPackage) {
     // Log the clients evicted
-    logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
-            clientPackage, clientPid));
+    logEvent(fmt::sprintf("DISCONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
+            clientPackage.c_str(), clientPid));
 }
 
-void CameraService::logDisconnectedOffline(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+void CameraService::logDisconnectedOffline(const std::string &cameraId, int clientPid,
+        const std::string &clientPackage) {
     // Log the clients evicted
-    logEvent(String8::format("DISCONNECT offline device %s client for package %s (PID %d)",
-                cameraId, clientPackage, clientPid));
+    logEvent(fmt::sprintf("DISCONNECT offline device %s client for package %s (PID %d)",
+            cameraId.c_str(), clientPackage.c_str(), clientPid));
 }
 
-void CameraService::logConnected(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+void CameraService::logConnected(const std::string &cameraId, int clientPid,
+        const std::string &clientPackage) {
     // Log the clients evicted
-    logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
-            clientPackage, clientPid));
+    logEvent(fmt::sprintf("CONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
+            clientPackage.c_str(), clientPid));
 }
 
-void CameraService::logConnectedOffline(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+void CameraService::logConnectedOffline(const std::string &cameraId, int clientPid,
+        const std::string &clientPackage) {
     // Log the clients evicted
-    logEvent(String8::format("CONNECT offline device %s client for package %s (PID %d)", cameraId,
-            clientPackage, clientPid));
+    logEvent(fmt::sprintf("CONNECT offline device %s client for package %s (PID %d)",
+            cameraId.c_str(), clientPackage.c_str(), clientPid));
 }
 
-void CameraService::logRejected(const char* cameraId, int clientPid,
-        const char* clientPackage, const char* reason) {
+void CameraService::logRejected(const std::string &cameraId, int clientPid,
+        const std::string &clientPackage, const std::string &reason) {
     // Log the client rejected
-    logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
-            cameraId, clientPackage, clientPid, reason));
+    logEvent(fmt::sprintf("REJECT device %s client for package %s (PID %d), reason: (%s)",
+            cameraId.c_str(), clientPackage.c_str(), clientPid, reason.c_str()));
 }
 
-void CameraService::logTorchEvent(const char* cameraId, const char *torchState, int clientPid) {
+void CameraService::logTorchEvent(const std::string &cameraId, const std::string &torchState,
+        int clientPid) {
     // Log torch event
-    logEvent(String8::format("Torch for camera id %s turned %s for client PID %d", cameraId,
-            torchState, clientPid));
+    logEvent(fmt::sprintf("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
+            torchState.c_str(), clientPid));
 }
 
 void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
         const std::set<userid_t>& newUserIds) {
-    String8 newUsers = toString(newUserIds);
-    String8 oldUsers = toString(oldUserIds);
+    std::string newUsers = toString(newUserIds);
+    std::string oldUsers = toString(oldUserIds);
     if (oldUsers.size() == 0) {
         oldUsers = "<None>";
     }
     // Log the new and old users
-    logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
-            oldUsers.string(), newUsers.string()));
+    logEvent(fmt::sprintf("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
+            oldUsers.c_str(), newUsers.c_str()));
 }
 
-void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
+void CameraService::logDeviceRemoved(const std::string &cameraId, const std::string &reason) {
     // Log the device removal
-    logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
+    logEvent(fmt::sprintf("REMOVE device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
 }
 
-void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
+void CameraService::logDeviceAdded(const std::string &cameraId, const std::string &reason) {
     // Log the device removal
-    logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
+    logEvent(fmt::sprintf("ADD device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
 }
 
-void CameraService::logClientDied(int clientPid, const char* reason) {
+void CameraService::logClientDied(int clientPid, const std::string &reason) {
     // Log the device removal
-    logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
+    logEvent(fmt::sprintf("DIED client(s) with PID %d, reason: (%s)", clientPid, reason.c_str()));
 }
 
-void CameraService::logServiceError(const char* msg, int errorCode) {
-    String8 curTime = getFormattedCurrentTime();
-    logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
+void CameraService::logServiceError(const std::string &msg, int errorCode) {
+    logEvent(fmt::sprintf("SERVICE ERROR: %s : %d (%s)", msg.c_str(), errorCode,
+            strerror(-errorCode)));
 }
 
 status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
@@ -3450,9 +3423,9 @@
 
 CameraService::Client::Client(const sp<CameraService>& cameraService,
         const sp<ICameraClient>& cameraClient,
-        const String16& clientPackageName, bool systemNativeClient,
-        const std::optional<String16>& clientFeatureId,
-        const String8& cameraIdStr,
+        const std::string& clientPackageName, bool systemNativeClient,
+        const std::optional<std::string>& clientFeatureId,
+        const std::string& cameraIdStr,
         int api1CameraId, int cameraFacing, int sensorOrientation,
         int clientPid, uid_t clientUid,
         int servicePid, bool overrideToPortrait) :
@@ -3488,8 +3461,8 @@
 
 CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
         const sp<IBinder>& remoteCallback,
-        const String16& clientPackageName, bool nativeClient,
-        const std::optional<String16>& clientFeatureId, const String8& cameraIdStr,
+        const std::string& clientPackageName, bool nativeClient,
+        const std::optional<std::string>& clientFeatureId, const std::string& cameraIdStr,
         int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
         int servicePid, bool overrideToPortrait):
         mDestructionStarted(false),
@@ -3540,9 +3513,9 @@
     mDisconnected = true;
 
     sCameraService->removeByClient(this);
-    sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
+    sCameraService->logDisconnected(mCameraIdStr, mClientPid, mClientPackageName);
     sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
-            mCameraIdStr.c_str());
+            mCameraIdStr);
 
     sp<IBinder> remote = getRemote();
     if (remote != nullptr) {
@@ -3552,7 +3525,7 @@
     finishCameraOps();
     // Notify flashlight that a camera device is closed.
     sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
-    ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
+    ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.c_str(),
             mClientPid);
 
     // client shouldn't be able to call into us anymore
@@ -3576,7 +3549,7 @@
     return OK;
 }
 
-status_t CameraService::BasicClient::startWatchingTags(const String8&, int) {
+status_t CameraService::BasicClient::startWatchingTags(const std::string&, int) {
     // Can't watch tags directly, must go through CameraService::startWatchingTags
     return OK;
 }
@@ -3591,7 +3564,7 @@
     return OK;
 }
 
-String16 CameraService::BasicClient::getPackageName() const {
+std::string CameraService::BasicClient::getPackageName() const {
     return mClientPackageName;
 }
 
@@ -3648,7 +3621,7 @@
 status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) {
     if (mode == AppOpsManager::MODE_ERRORED) {
         ALOGI("Camera %s: Access for \"%s\" has been revoked",
-                mCameraIdStr.string(), String8(mClientPackageName).string());
+                mCameraIdStr.c_str(), mClientPackageName.c_str());
         return PERMISSION_DENIED;
     } else if (!mUidIsTrusted && mode == AppOpsManager::MODE_IGNORED) {
         // If the calling Uid is trusted (a native service), the AppOpsManager could
@@ -3664,7 +3637,7 @@
         // capabilities are unknown.
         if (!isUidActive || !isCameraPrivacyEnabled) {
             ALOGI("Camera %s: Access for \"%s\" has been restricted",
-                    mCameraIdStr.string(), String8(mClientPackageName).string());
+                    mCameraIdStr.c_str(), mClientPackageName.c_str());
             // Return the same error as for device policy manager rejection
             return -EACCES;
         }
@@ -3677,18 +3650,18 @@
 
     {
         ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
-              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+              __FUNCTION__, mClientPackageName.c_str(), mClientUid);
     }
     if (mAppOpsManager != nullptr) {
         // Notify app ops that the camera is not available
         mOpsCallback = new OpsCallback(this);
         mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
-                mClientPackageName, mOpsCallback);
+                toString16(mClientPackageName), mOpsCallback);
 
         // Just check for camera acccess here on open - delay startOp until
         // camera frames start streaming in startCameraStreamingOps
         int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName);
+                toString16(mClientPackageName));
         status_t res = handleAppOpMode(mode);
         if (res != OK) {
             return res;
@@ -3721,12 +3694,13 @@
     }
 
     ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d",
-            __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+            __FUNCTION__, mClientPackageName.c_str(), mClientUid);
 
     if (mAppOpsManager != nullptr) {
         int32_t mode = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId,
-                String16("start camera ") + String16(mCameraIdStr));
+                toString16(mClientPackageName), /*startIfModeDefault*/ false,
+                toString16(mClientFeatureId),
+                toString16("start camera ") + toString16(mCameraIdStr));
         status_t res = handleAppOpMode(mode);
         if (res != OK) {
             return res;
@@ -3742,14 +3716,14 @@
     ATRACE_CALL();
 
     ALOGV("%s: Start camera noteAppOp, package name = %s, client UID = %d",
-            __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+            __FUNCTION__, mClientPackageName.c_str(), mClientUid);
 
     // noteAppOp is only used for when camera mute is not supported, in order
     // to trigger the sensor privacy "Unblock" dialog
     if (mAppOpsManager != nullptr) {
         int32_t mode = mAppOpsManager->noteOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName, mClientFeatureId,
-                String16("start camera ") + String16(mCameraIdStr));
+                toString16(mClientPackageName), toString16(mClientFeatureId),
+                toString16("start camera ") + toString16(mCameraIdStr));
         status_t res = handleAppOpMode(mode);
         if (res != OK) {
             return res;
@@ -3773,7 +3747,7 @@
 
     if (mAppOpsManager != nullptr) {
         mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName, mClientFeatureId);
+                toString16(mClientPackageName), toString16(mClientFeatureId));
         mOpsStreaming = false;
     }
 
@@ -3829,7 +3803,7 @@
 
     int32_t res;
     res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
-            mClientUid, mClientPackageName);
+            mClientUid, toString16(mClientPackageName));
     ALOGV("checkOp returns: %d, %s ", res,
             res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
             res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
@@ -3837,15 +3811,15 @@
             "UNKNOWN");
 
     if (res == AppOpsManager::MODE_ERRORED) {
-        ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
-              String8(mClientPackageName).string());
+        ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.c_str(),
+              mClientPackageName.c_str());
         block();
     } else if (res == AppOpsManager::MODE_IGNORED) {
         bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName);
         bool isCameraPrivacyEnabled =
                 sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled();
         ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d",
-                mCameraIdStr.string(), String8(mClientPackageName).string(),
+                mCameraIdStr.c_str(), mClientPackageName.c_str(),
                 mUidIsTrusted, isUidActive);
         // If the calling Uid is trusted (a native service), or the client Uid is active (WAR for
         // b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as
@@ -3926,7 +3900,7 @@
             | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE
             | ActivityManager::UID_OBSERVER_PROC_OOM_ADJ,
             ActivityManager::PROCESS_STATE_UNKNOWN,
-            String16("cameraserver"), emptyUidArray, 0, mObserverToken);
+            toString16(kServiceName), emptyUidArray, 0, mObserverToken);
     if (res == OK) {
         mRegistered = true;
         ALOGV("UidPolicy: Registered with ActivityManager");
@@ -3936,7 +3910,7 @@
 }
 
 void CameraService::UidPolicy::onServiceRegistration(const String16& name, const sp<IBinder>&) {
-    if (name != String16(kActivityServiceName)) {
+    if (name != toString16(kActivityServiceName)) {
         return;
     }
 
@@ -3948,9 +3922,9 @@
     // If not available then register for notifications, instead of blocking
     // till the service is ready
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->checkService(String16(kActivityServiceName));
+    sp<IBinder> binder = sm->checkService(toString16(kActivityServiceName));
     if (!binder) {
-        sm->registerForNotifications(String16(kActivityServiceName), this);
+        sm->registerForNotifications(toString16(kActivityServiceName), this);
     } else {
         registerWithActivityManager();
     }
@@ -4069,7 +4043,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, toString16(kServiceName), uid);
         if (res != OK) {
             ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res);
         }
@@ -4090,7 +4064,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, toString16(kServiceName), uid);
             if (res != OK) {
                 ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res);
             }
@@ -4102,7 +4076,7 @@
     }
 }
 
-bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
+bool CameraService::UidPolicy::isUidActive(uid_t uid, const std::string &callingPackage) {
     Mutex::Autolock _l(mUidLock);
     return isUidActiveLocked(uid, callingPackage);
 }
@@ -4110,7 +4084,7 @@
 static const int64_t kPollUidActiveTimeoutTotalMillis = 300;
 static const int64_t kPollUidActiveTimeoutMillis = 50;
 
-bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
+bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, const std::string &callingPackage) {
     // Non-app UIDs are considered always active
     // If activity manager is unreachable, assume everything is active
     if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -4137,7 +4111,7 @@
             // some polling which should happen pretty rarely anyway as the race is hard
             // to hit.
             active = mActiveUids.find(uid) != mActiveUids.end();
-            if (!active) active = am.isUidActive(uid, callingPackage);
+            if (!active) active = am.isUidActive(uid, toString16(callingPackage));
             if (active) {
                 break;
             }
@@ -4177,12 +4151,12 @@
     return procState;
 }
 
-void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
-        String16 callingPackage, bool active) {
+void CameraService::UidPolicy::addOverrideUid(uid_t uid,
+        const std::string &callingPackage, bool active) {
     updateOverrideUid(uid, callingPackage, active, true);
 }
 
-void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
+void CameraService::UidPolicy::removeOverrideUid(uid_t uid, const std::string &callingPackage) {
     updateOverrideUid(uid, callingPackage, false, false);
 }
 
@@ -4193,7 +4167,7 @@
     mActiveUids.clear();
 }
 
-void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
+void CameraService::UidPolicy::updateOverrideUid(uid_t uid, const std::string &callingPackage,
         bool active, bool insert) {
     bool wasActive = false;
     bool isActive = false;
@@ -4236,7 +4210,7 @@
 
 void CameraService::SensorPrivacyPolicy::onServiceRegistration(const String16& name,
                                                                const sp<IBinder>&) {
-    if (name != String16(kSensorPrivacyServiceName)) {
+    if (name != toString16(kSensorPrivacyServiceName)) {
         return;
     }
 
@@ -4247,9 +4221,9 @@
     // Use checkservice to see if the sensor_privacy service is available
     // If service is not available then register for notification
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->checkService(String16(kSensorPrivacyServiceName));
+    sp<IBinder> binder = sm->checkService(toString16(kSensorPrivacyServiceName));
     if (!binder) {
-        sm->registerForNotifications(String16(kSensorPrivacyServiceName),this);
+        sm->registerForNotifications(toString16(kSensorPrivacyServiceName),this);
     } else {
         registerWithSensorPrivacyManager();
     }
@@ -4313,8 +4287,8 @@
 //                  CameraState
 // ----------------------------------------------------------------------------
 
-CameraService::CameraState::CameraState(const String8& id, int cost,
-        const std::set<String8>& conflicting, SystemCameraKind systemCameraKind,
+CameraService::CameraState::CameraState(const std::string& id, int cost,
+        const std::set<std::string>& conflicting, SystemCameraKind systemCameraKind,
         const std::vector<std::string>& physicalCameras) : mId(id),
         mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
         mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {}
@@ -4326,9 +4300,9 @@
     return mStatus;
 }
 
-std::vector<String8> CameraService::CameraState::getUnavailablePhysicalIds() const {
+std::vector<std::string> CameraService::CameraState::getUnavailablePhysicalIds() const {
     Mutex::Autolock lock(mStatusLock);
-    std::vector<String8> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
+    std::vector<std::string> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
     return res;
 }
 
@@ -4344,14 +4318,10 @@
     return mCost;
 }
 
-std::set<String8> CameraService::CameraState::getConflicting() const {
+std::set<std::string> CameraService::CameraState::getConflicting() const {
     return mConflicting;
 }
 
-String8 CameraService::CameraState::getId() const {
-    return mId;
-}
-
 SystemCameraKind CameraService::CameraState::getSystemCameraKind() const {
     return mSystemCameraKind;
 }
@@ -4361,24 +4331,24 @@
             != mPhysicalCameras.end();
 }
 
-bool CameraService::CameraState::addUnavailablePhysicalId(const String8& physicalId) {
+bool CameraService::CameraState::addUnavailablePhysicalId(const std::string& physicalId) {
     Mutex::Autolock lock(mStatusLock);
     auto result = mUnavailablePhysicalIds.insert(physicalId);
     return result.second;
 }
 
-bool CameraService::CameraState::removeUnavailablePhysicalId(const String8& physicalId) {
+bool CameraService::CameraState::removeUnavailablePhysicalId(const std::string& physicalId) {
     Mutex::Autolock lock(mStatusLock);
     auto count = mUnavailablePhysicalIds.erase(physicalId);
     return count > 0;
 }
 
-void CameraService::CameraState::setClientPackage(const String8& clientPackage) {
+void CameraService::CameraState::setClientPackage(const std::string& clientPackage) {
     Mutex::Autolock lock(mStatusLock);
     mClientPackage = clientPackage;
 }
 
-String8 CameraService::CameraState::getClientPackage() const {
+std::string CameraService::CameraState::getClientPackage() const {
     Mutex::Autolock lock(mStatusLock);
     return mClientPackage;
 }
@@ -4388,23 +4358,23 @@
 // ----------------------------------------------------------------------------
 
 void CameraService::ClientEventListener::onClientAdded(
-        const resource_policy::ClientDescriptor<String8,
+        const resource_policy::ClientDescriptor<std::string,
         sp<CameraService::BasicClient>>& descriptor) {
     const auto& basicClient = descriptor.getValue();
     if (basicClient.get() != nullptr) {
         BatteryNotifier& notifier(BatteryNotifier::getInstance());
-        notifier.noteStartCamera(descriptor.getKey(),
+        notifier.noteStartCamera(toString8(descriptor.getKey()),
                 static_cast<int>(basicClient->getClientUid()));
     }
 }
 
 void CameraService::ClientEventListener::onClientRemoved(
-        const resource_policy::ClientDescriptor<String8,
+        const resource_policy::ClientDescriptor<std::string,
         sp<CameraService::BasicClient>>& descriptor) {
     const auto& basicClient = descriptor.getValue();
     if (basicClient.get() != nullptr) {
         BatteryNotifier& notifier(BatteryNotifier::getInstance());
-        notifier.noteStopCamera(descriptor.getKey(),
+        notifier.noteStopCamera(toString8(descriptor.getKey()),
                 static_cast<int>(basicClient->getClientUid()));
     }
 }
@@ -4421,7 +4391,7 @@
 CameraService::CameraClientManager::~CameraClientManager() {}
 
 sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
-        const String8& id) const {
+        const std::string& id) const {
     auto descriptor = get(id);
     if (descriptor == nullptr) {
         return sp<BasicClient>{nullptr};
@@ -4429,56 +4399,57 @@
     return descriptor->getValue();
 }
 
-String8 CameraService::CameraClientManager::toString() const {
+std::string CameraService::CameraClientManager::toString() const {
     auto all = getAll();
-    String8 ret("[");
+    std::ostringstream ret;
+    ret << "[";
     bool hasAny = false;
     for (auto& i : all) {
         hasAny = true;
-        String8 key = i->getKey();
+        std::string key = i->getKey();
         int32_t cost = i->getCost();
         int32_t pid = i->getOwnerId();
         int32_t score = i->getPriority().getScore();
         int32_t state = i->getPriority().getState();
         auto conflicting = i->getConflicting();
         auto clientSp = i->getValue();
-        String8 packageName;
+        std::string packageName;
         userid_t clientUserId = 0;
         if (clientSp.get() != nullptr) {
-            packageName = String8{clientSp->getPackageName()};
+            packageName = clientSp->getPackageName();
             uid_t clientUid = clientSp->getClientUid();
             clientUserId = multiuser_get_user_id(clientUid);
         }
-        ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
-                PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
+        ret << fmt::sprintf("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
+                PRId32 ", State: %" PRId32, key.c_str(), cost, pid, score, state);
 
         if (clientSp.get() != nullptr) {
-            ret.appendFormat("User Id: %d, ", clientUserId);
+            ret << fmt::sprintf("User Id: %d, ", clientUserId);
         }
         if (packageName.size() != 0) {
-            ret.appendFormat("Client Package Name: %s", packageName.string());
+            ret << fmt::sprintf("Client Package Name: %s", packageName.c_str());
         }
 
-        ret.append(", Conflicting Client Devices: {");
+        ret << ", Conflicting Client Devices: {";
         for (auto& j : conflicting) {
-            ret.appendFormat("%s, ", j.string());
+            ret << fmt::sprintf("%s, ", j.c_str());
         }
-        ret.append("})");
+        ret << "})";
     }
-    if (hasAny) ret.append("\n");
-    ret.append("]\n");
-    return ret;
+    if (hasAny) ret << "\n";
+    ret << "]\n";
+    return std::move(ret.str());
 }
 
 CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
-        const String8& key, const sp<BasicClient>& value, int32_t cost,
-        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
+        const std::string& key, const sp<BasicClient>& value, int32_t cost,
+        const std::set<std::string>& conflictingKeys, int32_t score, int32_t ownerId,
         int32_t state, int32_t oomScoreOffset, bool systemNativeClient) {
 
     int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score;
-    int32_t state_adj = systemNativeClient ? kSystemNativeClientState: state;
+    int32_t state_adj = systemNativeClient ? kSystemNativeClientState : state;
 
-    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
+    return std::make_shared<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>(
             key, value, cost, conflictingKeys, score_adj, ownerId, state_adj,
             systemNativeClient, oomScoreOffset);
 }
@@ -4517,7 +4488,7 @@
 }
 
 void CameraService::InjectionStatusListener::notifyInjectionError(
-        String8 injectedCamId, status_t err) {
+        const std::string &injectedCamId, status_t err) {
     if (mCameraInjectionCallback == nullptr) {
         ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr");
         return;
@@ -4528,37 +4499,37 @@
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_SESSION);
             ALOGE("No camera device with ID \"%s\" currently available!",
-                    injectedCamId.string());
+                    injectedCamId.c_str());
             break;
         case -EBUSY:
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_SESSION);
             ALOGE("Higher-priority client using camera, ID \"%s\" currently unavailable!",
-                    injectedCamId.string());
+                    injectedCamId.c_str());
             break;
         case DEAD_OBJECT:
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_SESSION);
             ALOGE("Camera ID \"%s\" object is dead!",
-                    injectedCamId.string());
+                    injectedCamId.c_str());
             break;
         case INVALID_OPERATION:
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_SESSION);
             ALOGE("Camera ID \"%s\" encountered an operating or internal error!",
-                    injectedCamId.string());
+                    injectedCamId.c_str());
             break;
         case UNKNOWN_TRANSACTION:
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED);
             ALOGE("Camera ID \"%s\" method doesn't support!",
-                    injectedCamId.string());
+                    injectedCamId.c_str());
             break;
         default:
             mCameraInjectionCallback->onInjectionError(
                     ICameraInjectionCallback::ERROR_INJECTION_INVALID_ERROR);
             ALOGE("Unexpected error %s (%d) opening camera \"%s\"!",
-                    strerror(-err), err, injectedCamId.string());
+                    strerror(-err), err, injectedCamId.c_str());
     }
 }
 
@@ -4634,10 +4605,10 @@
         Mutex::Autolock l(mCameraStatesLock);
         // Start collecting the info for open sessions and store it in temp file.
         for (const auto& state : mCameraStates) {
-            String8 cameraId = state.first;
+            std::string cameraId = state.first;
             auto clientDescriptor = mActiveClientManager.get(cameraId);
             if (clientDescriptor != nullptr) {
-                dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+                dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
                 // Log the current open session info before device is disconnected.
                 dumpOpenSessionClientLogs(mMemFd, args, cameraId);
             }
@@ -4648,7 +4619,7 @@
 status_t CameraService::dump(int fd, const Vector<String16>& args) {
     ATRACE_CALL();
 
-    if (checkCallingPermission(sDumpPermission) == false) {
+    if (checkCallingPermission(toString16(sDumpPermission)) == false) {
         dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
                 CameraThreadState::getCallingPid(),
                 CameraThreadState::getCallingUid());
@@ -4677,9 +4648,9 @@
     for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
         dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
     }
-    String8 activeClientString = mActiveClientManager.toString();
-    dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
-    dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
+    std::string activeClientString = mActiveClientManager.toString();
+    dprintf(fd, "Active Camera Clients:\n%s", activeClientString.c_str());
+    dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).c_str());
     if (mStreamUseCaseOverrides.size() > 0) {
         dprintf(fd, "Active stream use case overrides:");
         for (int64_t useCaseOverride : mStreamUseCaseOverrides) {
@@ -4697,18 +4668,18 @@
 
     int argSize = args.size();
     for (int i = 0; i < argSize; i++) {
-        if (args[i] == TagMonitor::kMonitorOption) {
+        if (args[i] == toString16(TagMonitor::kMonitorOption)) {
             if (i + 1 < argSize) {
-                mMonitorTags = String8(args[i + 1]);
+                mMonitorTags = toStdString(args[i + 1]);
             }
             break;
         }
     }
 
     for (auto& state : mCameraStates) {
-        String8 cameraId = state.first;
+        const std::string &cameraId = state.first;
 
-        dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+        dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
 
         CameraParameters p = state.second->getShimParams();
         if (!p.isEmpty()) {
@@ -4759,8 +4730,8 @@
         if (args[i] == verboseOption) {
             // change logging level
             if (i + 1 >= n) continue;
-            String8 levelStr(args[i+1]);
-            int level = atoi(levelStr.string());
+            std::string levelStr = toStdString(args[i+1]);
+            int level = atoi(levelStr.c_str());
             dprintf(fd, "\nSetting log level to %d.\n", level);
             setLogLevel(level);
         } else if (args[i] == unreachableOption) {
@@ -4806,11 +4777,11 @@
 }
 
 void CameraService::dumpOpenSessionClientLogs(int fd,
-        const Vector<String16>& args, const String8& cameraId) {
+        const Vector<String16>& args, const std::string& cameraId) {
     auto clientDescriptor = mActiveClientManager.get(cameraId);
     dprintf(fd, "  %s : Device %s is open. Client instance dump:\n",
-            getFormattedCurrentTime().string(),
-            cameraId.string());
+            getFormattedCurrentTime().c_str(),
+            cameraId.c_str());
     dprintf(fd, "    Client priority score: %d state: %d\n",
         clientDescriptor->getPriority().getScore(),
         clientDescriptor->getPriority().getState());
@@ -4818,14 +4789,14 @@
 
     auto client = clientDescriptor->getValue();
     dprintf(fd, "    Client package: %s\n",
-        String8(client->getPackageName()).string());
+        client->getPackageName().c_str());
 
     client->dumpClient(fd, args);
 }
 
-void CameraService::dumpClosedSessionClientLogs(int fd, const String8& cameraId) {
+void CameraService::dumpClosedSessionClientLogs(int fd, const std::string& cameraId) {
     dprintf(fd, "  Device %s is closed, no client instance\n",
-                    cameraId.string());
+                    cameraId.c_str());
 }
 
 void CameraService::dumpEventLog(int fd) {
@@ -4833,7 +4804,7 @@
 
     Mutex::Autolock l(mLogLock);
     for (const auto& msg : mEventLog) {
-        dprintf(fd, "  %s\n", msg.string());
+        dprintf(fd, "  %s\n", msg.c_str());
     }
 
     if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
@@ -4844,7 +4815,7 @@
     dprintf(fd, "\n");
 }
 
-void CameraService::cacheClientTagDumpIfNeeded(const char *cameraId, BasicClient* client) {
+void CameraService::cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient* client) {
     Mutex::Autolock lock(mLogLock);
     if (!isClientWatchedLocked(client)) { return; }
 
@@ -4853,34 +4824,26 @@
 
     if (dumpVector.empty()) { return; }
 
-    std::string dumpString;
+    std::ostringstream dumpString;
 
-    String8 currentTime = getFormattedCurrentTime();
-    dumpString += "Cached @ ";
-    dumpString += currentTime.string();
-    dumpString += "\n"; // First line is the timestamp of when client is cached.
-
-
-    const String16 &packageName = client->getPackageName();
-
-    String8 packageName8 = String8(packageName);
-    const char *printablePackageName = packageName8.lockBuffer(packageName.size());
-
+    std::string currentTime = getFormattedCurrentTime();
+    dumpString << "Cached @ ";
+    dumpString << currentTime;
+    dumpString << "\n"; // First line is the timestamp of when client is cached.
 
     size_t i = dumpVector.size();
 
     // Store the string in reverse order (latest last)
     while (i > 0) {
          i--;
-         dumpString += cameraId;
-         dumpString += ":";
-         dumpString += printablePackageName;
-         dumpString += "  ";
-         dumpString += dumpVector[i]; // implicitly ends with '\n'
+         dumpString << cameraId;
+         dumpString << ":";
+         dumpString << client->getPackageName();
+         dumpString << "  ";
+         dumpString << dumpVector[i]; // implicitly ends with '\n'
     }
 
-    packageName8.unlockBuffer();
-    mWatchedClientsDumpCache[packageName] = dumpString;
+    mWatchedClientsDumpCache[client->getPackageName()] = dumpString.str();
 }
 
 void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
@@ -4888,7 +4851,7 @@
     for (size_t i = 0; i < mTorchClientMap.size(); i++) {
         if (mTorchClientMap[i] == who) {
             // turn off the torch mode that was turned on by dead client
-            String8 cameraId = mTorchClientMap.keyAt(i);
+            std::string cameraId = mTorchClientMap.keyAt(i);
             status_t res = mFlashlight->setTorchMode(cameraId, false);
             if (res) {
                 ALOGE("%s: torch client died but couldn't turn off torch: "
@@ -4908,7 +4871,7 @@
       * binder driver
       */
     // PID here is approximate and can be wrong.
-    logClientDied(CameraThreadState::getCallingPid(), String8("Binder died unexpectedly"));
+    logClientDied(CameraThreadState::getCallingPid(), "Binder died unexpectedly");
 
     // check torch client
     handleTorchClientBinderDied(who);
@@ -4923,11 +4886,11 @@
             __FUNCTION__);
 }
 
-void CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
+void CameraService::updateStatus(StatusInternal status, const std::string& cameraId) {
     updateStatus(status, cameraId, {});
 }
 
-void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
+void CameraService::updateStatus(StatusInternal status, const std::string& cameraId,
         std::initializer_list<StatusInternal> rejectSourceStates) {
     // Do not lock mServiceLock here or can get into a deadlock from
     // connect() -> disconnect -> updateStatus
@@ -4936,14 +4899,14 @@
 
     if (state == nullptr) {
         ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
         return;
     }
 
     // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
     if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
-        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.string());
+        ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
         return;
     }
 
@@ -4954,7 +4917,7 @@
     // of the listeners with both the mStatusLock and mStatusListenerLock held
     state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind,
                         &logicalCameraIds]
-            (const String8& cameraId, StatusInternal status) {
+            (const std::string& cameraId, StatusInternal status) {
 
             if (status != StatusInternal::ENUMERATING) {
                 // Update torch status if it has a flash unit.
@@ -4973,7 +4936,7 @@
             }
 
             Mutex::Autolock lock(mStatusListenerLock);
-            notifyPhysicalCameraStatusLocked(mapToInterface(status), String16(cameraId),
+            notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId,
                     logicalCameraIds, deviceKind);
 
             for (auto& listener : mListenerList) {
@@ -4986,7 +4949,7 @@
                     continue;
                 }
                 auto ret = listener->getListener()->onStatusChanged(mapToInterface(status),
-                        String16(cameraId));
+                        cameraId);
                 listener->handleBinderStatus(ret,
                         "%s: Failed to trigger onStatusChanged callback for %d:%d: %d",
                         __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
@@ -4995,18 +4958,18 @@
         });
 }
 
-void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
-        const String16& clientPackageName) {
+void CameraService::updateOpenCloseStatus(const std::string& cameraId, bool open,
+        const std::string& clientPackageName) {
     auto state = getCameraState(cameraId);
     if (state == nullptr) {
         ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
-                cameraId.string());
+                cameraId.c_str());
         return;
     }
     if (open) {
-        state->setClientPackage(String8(clientPackageName));
+        state->setClientPackage(clientPackageName);
     } else {
-        state->setClientPackage(String8::empty());
+        state->setClientPackage(std::string());
     }
 
     Mutex::Autolock lock(mStatusListenerLock);
@@ -5017,11 +4980,10 @@
         }
 
         binder::Status ret;
-        String16 cameraId64(cameraId);
         if (open) {
-            ret = it->getListener()->onCameraOpened(cameraId64, clientPackageName);
+            ret = it->getListener()->onCameraOpened(cameraId, clientPackageName);
         } else {
-            ret = it->getListener()->onCameraClosed(cameraId64);
+            ret = it->getListener()->onCameraClosed(cameraId);
         }
 
         it->handleBinderStatus(ret,
@@ -5032,7 +4994,7 @@
 
 template<class Func>
 void CameraService::CameraState::updateStatus(StatusInternal status,
-        const String8& cameraId,
+        const std::string& cameraId,
         std::initializer_list<StatusInternal> rejectSourceStates,
         Func onStatusUpdatedLocked) {
     Mutex::Autolock lock(mStatusLock);
@@ -5044,7 +5006,7 @@
     }
 
     ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
-            cameraId.string(), oldStatus, status);
+            cameraId.c_str(), oldStatus, status);
 
     if (oldStatus == StatusInternal::NOT_PRESENT &&
             (status != StatusInternal::PRESENT &&
@@ -5064,7 +5026,7 @@
     for (auto& rejectStatus : rejectSourceStates) {
         if (oldStatus == rejectStatus) {
             ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source "
-                    "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
+                    "state was was in one of the bad states.", __FUNCTION__, cameraId.c_str());
             mStatus = oldStatus;
             return;
         }
@@ -5074,7 +5036,7 @@
 }
 
 status_t CameraService::getTorchStatusLocked(
-        const String8& cameraId,
+        const std::string& cameraId,
         TorchModeStatus *status) const {
     if (!status) {
         return BAD_VALUE;
@@ -5089,7 +5051,7 @@
     return OK;
 }
 
-status_t CameraService::setTorchStatusLocked(const String8& cameraId,
+status_t CameraService::setTorchStatusLocked(const std::string& cameraId,
         TorchModeStatus status) {
     ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
     if (index == NAME_NOT_FOUND) {
@@ -5100,20 +5062,20 @@
     return OK;
 }
 
-std::list<String16> CameraService::getLogicalCameras(
-        const String8& physicalCameraId) {
-    std::list<String16> retList;
+std::list<std::string> CameraService::getLogicalCameras(
+        const std::string& physicalCameraId) {
+    std::list<std::string> retList;
     Mutex::Autolock lock(mCameraStatesLock);
     for (const auto& state : mCameraStates) {
-        if (state.second->containsPhysicalCamera(physicalCameraId.c_str())) {
-            retList.emplace_back(String16(state.first));
+        if (state.second->containsPhysicalCamera(physicalCameraId)) {
+            retList.emplace_back(state.first);
         }
     }
     return retList;
 }
 
 void CameraService::notifyPhysicalCameraStatusLocked(int32_t status,
-        const String16& physicalCameraId, const std::list<String16>& logicalCameraIds,
+        const std::string& physicalCameraId, const std::list<std::string>& logicalCameraIds,
         SystemCameraKind deviceKind) {
     // mStatusListenerLock is expected to be locked
     for (const auto& logicalCameraId : logicalCameraIds) {
@@ -5124,7 +5086,7 @@
             if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
                     listener->getListenerPid(), listener->getListenerUid())) {
                 ALOGV("Skipping discovery callback for system-only camera device %s",
-                        String8(physicalCameraId).c_str());
+                        physicalCameraId.c_str());
                 continue;
             }
             auto ret = listener->getListener()->onPhysicalCameraStatusChanged(status,
@@ -5164,44 +5126,44 @@
 
 // NOTE: This is a remote API - make sure all args are validated
 status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
-    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
+    if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) {
         return PERMISSION_DENIED;
     }
     if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
         return BAD_VALUE;
     }
-    if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
+    if (args.size() >= 3 && args[0] == toString16("set-uid-state")) {
         return handleSetUidState(args, err);
-    } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
+    } else if (args.size() >= 2 && args[0] == toString16("reset-uid-state")) {
         return handleResetUidState(args, err);
-    } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
+    } else if (args.size() >= 2 && args[0] == toString16("get-uid-state")) {
         return handleGetUidState(args, out, err);
-    } else if (args.size() >= 2 && args[0] == String16("set-rotate-and-crop")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-rotate-and-crop")) {
         return handleSetRotateAndCrop(args);
-    } else if (args.size() >= 1 && args[0] == String16("get-rotate-and-crop")) {
+    } else if (args.size() >= 1 && args[0] == toString16("get-rotate-and-crop")) {
         return handleGetRotateAndCrop(out);
-    } else if (args.size() >= 2 && args[0] == String16("set-autoframing")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-autoframing")) {
         return handleSetAutoframing(args);
-    } else if (args.size() >= 1 && args[0] == String16("get-autoframing")) {
+    } else if (args.size() >= 1 && args[0] == toString16("get-autoframing")) {
         return handleGetAutoframing(out);
-    } else if (args.size() >= 2 && args[0] == String16("set-image-dump-mask")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-image-dump-mask")) {
         return handleSetImageDumpMask(args);
-    } else if (args.size() >= 1 && args[0] == String16("get-image-dump-mask")) {
+    } else if (args.size() >= 1 && args[0] == toString16("get-image-dump-mask")) {
         return handleGetImageDumpMask(out);
-    } else if (args.size() >= 2 && args[0] == String16("set-camera-mute")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-camera-mute")) {
         return handleSetCameraMute(args);
-    } else if (args.size() >= 2 && args[0] == String16("set-stream-use-case-override")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-stream-use-case-override")) {
         return handleSetStreamUseCaseOverrides(args);
-    } else if (args.size() >= 1 && args[0] == String16("clear-stream-use-case-override")) {
+    } else if (args.size() >= 1 && args[0] == toString16("clear-stream-use-case-override")) {
         handleClearStreamUseCaseOverrides();
         return OK;
-    } else if (args.size() >= 1 && args[0] == String16("set-zoom-override")) {
+    } else if (args.size() >= 1 && args[0] == toString16("set-zoom-override")) {
         return handleSetZoomOverride(args);
-    } else if (args.size() >= 2 && args[0] == String16("watch")) {
+    } else if (args.size() >= 2 && args[0] == toString16("watch")) {
         return handleWatchCommand(args, in, out);
-    } else if (args.size() >= 2 && args[0] == String16("set-watchdog")) {
+    } else if (args.size() >= 2 && args[0] == toString16("set-watchdog")) {
         return handleSetCameraServiceWatchdog(args);
-    } else if (args.size() == 1 && args[0] == String16("help")) {
+    } else if (args.size() == 1 && args[0] == toString16("help")) {
         printHelp(out);
         return OK;
     }
@@ -5210,19 +5172,19 @@
 }
 
 status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
-    String16 packageName = args[1];
+    std::string packageName = toStdString(args[1]);
 
     bool active = false;
-    if (args[2] == String16("active")) {
+    if (args[2] == toString16("active")) {
         active = true;
-    } else if ((args[2] != String16("idle"))) {
-        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
+    } else if ((args[2] != toString16("idle"))) {
+        ALOGE("Expected active or idle but got: '%s'", toStdString(args[2]).c_str());
         return BAD_VALUE;
     }
 
     int userId = 0;
-    if (args.size() >= 5 && args[3] == String16("--user")) {
-        userId = atoi(String8(args[4]));
+    if (args.size() >= 5 && args[3] == toString16("--user")) {
+        userId = atoi(toStdString(args[4]).c_str());
     }
 
     uid_t uid;
@@ -5235,11 +5197,11 @@
 }
 
 status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
-    String16 packageName = args[1];
+    std::string packageName = toStdString(args[1]);
 
     int userId = 0;
-    if (args.size() >= 4 && args[2] == String16("--user")) {
-        userId = atoi(String8(args[3]));
+    if (args.size() >= 4 && args[2] == toString16("--user")) {
+        userId = atoi(toStdString(args[3]).c_str());
     }
 
     uid_t uid;
@@ -5252,11 +5214,11 @@
 }
 
 status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
-    String16 packageName = args[1];
+    std::string packageName = toStdString(args[1]);
 
     int userId = 0;
-    if (args.size() >= 4 && args[2] == String16("--user")) {
-        userId = atoi(String8(args[3]));
+    if (args.size() >= 4 && args[2] == toString16("--user")) {
+        userId = atoi(toStdString(args[3]).c_str());
     }
 
     uid_t uid;
@@ -5272,7 +5234,7 @@
 }
 
 status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) {
-    int rotateValue = atoi(String8(args[1]));
+    int rotateValue = atoi(toStdString(args[1]).c_str());
     if (rotateValue < ANDROID_SCALER_ROTATE_AND_CROP_NONE ||
             rotateValue > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
     Mutex::Autolock lock(mServiceLock);
@@ -5296,7 +5258,7 @@
 
 status_t CameraService::handleSetAutoframing(const Vector<String16>& args) {
     char* end;
-    int autoframingValue = (int) strtol(String8(args[1]), &end, /*base=*/10);
+    int autoframingValue = (int) strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
     if ((*end != '\0') ||
             (autoframingValue != ANDROID_CONTROL_AUTOFRAMING_OFF &&
              autoframingValue != ANDROID_CONTROL_AUTOFRAMING_ON &&
@@ -5323,7 +5285,7 @@
 }
 
 status_t CameraService::handleSetCameraServiceWatchdog(const Vector<String16>& args) {
-    int enableWatchdog = atoi(String8(args[1]));
+    int enableWatchdog = atoi(toStdString(args[1]).c_str());
 
     if (enableWatchdog < 0 || enableWatchdog > 1) return BAD_VALUE;
 
@@ -5359,11 +5321,11 @@
 status_t CameraService::handleSetImageDumpMask(const Vector<String16>& args) {
     char *endPtr;
     errno = 0;
-    String8 maskString8 = String8(args[1]);
-    long maskValue = strtol(maskString8.c_str(), &endPtr, 10);
+    std::string maskString = toStdString(args[1]);
+    long maskValue = strtol(maskString.c_str(), &endPtr, 10);
 
     if (errno != 0) return BAD_VALUE;
-    if (endPtr != maskString8.c_str() + maskString8.size()) return BAD_VALUE;
+    if (endPtr != maskString.c_str() + maskString.size()) return BAD_VALUE;
     if (maskValue < 0 || maskValue > 1) return BAD_VALUE;
 
     Mutex::Autolock lock(mServiceLock);
@@ -5380,7 +5342,7 @@
 }
 
 status_t CameraService::handleSetCameraMute(const Vector<String16>& args) {
-    int muteValue = strtol(String8(args[1]), nullptr, 10);
+    int muteValue = strtol(toStdString(args[1]).c_str(), nullptr, 10);
     if (errno != 0) return BAD_VALUE;
 
     if (muteValue < 0 || muteValue > 1) return BAD_VALUE;
@@ -5407,23 +5369,23 @@
     std::vector<int64_t> useCasesOverride;
     for (size_t i = 1; i < args.size(); i++) {
         int64_t useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
-        String8 arg8 = String8(args[i]);
-        if (arg8 == "DEFAULT") {
+        std::string arg = toStdString(args[i]);
+        if (arg == "DEFAULT") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
-        } else if (arg8 == "PREVIEW") {
+        } else if (arg == "PREVIEW") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW;
-        } else if (arg8 == "STILL_CAPTURE") {
+        } else if (arg == "STILL_CAPTURE") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE;
-        } else if (arg8 == "VIDEO_RECORD") {
+        } else if (arg == "VIDEO_RECORD") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD;
-        } else if (arg8 == "PREVIEW_VIDEO_STILL") {
+        } else if (arg == "PREVIEW_VIDEO_STILL") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL;
-        } else if (arg8 == "VIDEO_CALL") {
+        } else if (arg == "VIDEO_CALL") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
-        } else if (arg8 == "CROPPED_RAW") {
+        } else if (arg == "CROPPED_RAW") {
             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW;
         } else {
-            ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg8.c_str());
+            ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg.c_str());
             return BAD_VALUE;
         }
         useCasesOverride.push_back(useCase);
@@ -5442,7 +5404,7 @@
 
 status_t CameraService::handleSetZoomOverride(const Vector<String16>& args) {
     char* end;
-    int zoomOverrideValue = strtol(String8(args[1]), &end, /*base=*/10);
+    int zoomOverrideValue = strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
     if ((*end != '\0') ||
             (zoomOverrideValue != -1 &&
              zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF &&
@@ -5469,15 +5431,15 @@
 }
 
 status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
-    if (args.size() >= 3 && args[1] == String16("start")) {
+    if (args.size() >= 3 && args[1] == toString16("start")) {
         return startWatchingTags(args, outFd);
-    } else if (args.size() == 2 && args[1] == String16("stop")) {
+    } else if (args.size() == 2 && args[1] == toString16("stop")) {
         return stopWatchingTags(outFd);
-    } else if (args.size() == 2 && args[1] == String16("dump")) {
+    } else if (args.size() == 2 && args[1] == toString16("dump")) {
         return printWatchedTags(outFd);
-    } else if (args.size() >= 2 && args[1] == String16("live")) {
+    } else if (args.size() >= 2 && args[1] == toString16("live")) {
         return printWatchedTagsUntilInterrupt(args, inFd, outFd);
-    } else if (args.size() == 2 && args[1] == String16("clear")) {
+    } else if (args.size() == 2 && args[1] == toString16("clear")) {
         return clearCachedMonitoredTagDumps(outFd);
     }
     dprintf(outFd, "Camera service watch commands:\n"
@@ -5498,7 +5460,7 @@
     Mutex::Autolock lock(mLogLock);
     size_t tagsIdx; // index of '-m'
     String16 tags("");
-    for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != String16("-m"); tagsIdx++);
+    for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != toString16("-m"); tagsIdx++);
     if (tagsIdx < args.size() - 1) {
         tags = args[tagsIdx + 1];
     } else {
@@ -5507,16 +5469,17 @@
     }
 
     size_t clientsIdx; // index of '-c'
-    String16 clients = kWatchAllClientsFlag; // watch all clients if no clients are provided
-    for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != String16("-c");
+    // watch all clients if no clients are provided
+    String16 clients = toString16(kWatchAllClientsFlag);
+    for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != toString16("-c");
          clientsIdx++);
     if (clientsIdx < args.size() - 1) {
         clients = args[clientsIdx + 1];
     }
-    parseClientsToWatchLocked(String8(clients));
+    parseClientsToWatchLocked(toStdString(clients));
 
     // track tags to initialize future clients with the monitoring information
-    mMonitorTags = String8(tags);
+    mMonitorTags = toStdString(tags);
 
     bool serviceLock = tryLock(mServiceLock);
     int numWatchedClients = 0;
@@ -5540,7 +5503,7 @@
 status_t CameraService::stopWatchingTags(int outFd) {
     // clear mMonitorTags to prevent new clients from monitoring tags at initialization
     Mutex::Autolock lock(mLogLock);
-    mMonitorTags = String8::empty();
+    mMonitorTags = "";
 
     mWatchedClientPackages.clear();
     mWatchedClientsDumpCache.clear();
@@ -5568,7 +5531,7 @@
 
 status_t CameraService::printWatchedTags(int outFd) {
     Mutex::Autolock logLock(mLogLock);
-    std::set<String16> connectedMonitoredClients;
+    std::set<std::string> connectedMonitoredClients;
 
     bool printedSomething = false; // tracks if any monitoring information was printed
                                    // (from either cached or active clients)
@@ -5591,17 +5554,14 @@
         }
 
         // Print tag dumps for active client
-        const String8 &cameraId = clientDescriptor->getKey();
-        String8 packageName8 = String8(client->getPackageName());
-        const char *printablePackageName = packageName8.lockBuffer(packageName8.size());
-        dprintf(outFd, "Client: %s (active)\n", printablePackageName);
+        const std::string &cameraId = clientDescriptor->getKey();
+        dprintf(outFd, "Client: %s (active)\n", client->getPackageName().c_str());
         while(printIdx > 0) {
             printIdx--;
-            dprintf(outFd, "%s:%s  %s", cameraId.string(), printablePackageName,
+            dprintf(outFd, "%s:%s  %s", cameraId.c_str(), client->getPackageName().c_str(),
                     dumpVector[printIdx].c_str());
         }
         dprintf(outFd, "\n");
-        packageName8.unlockBuffer();
         printedSomething = true;
 
         connectedMonitoredClients.emplace(client->getPackageName());
@@ -5610,12 +5570,12 @@
 
     // Print entries in mWatchedClientsDumpCache for clients that are not connected
     for (const auto &kv: mWatchedClientsDumpCache) {
-        const String16 &package = kv.first;
+        const std::string &package = kv.first;
         if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) {
             continue;
         }
 
-        dprintf(outFd, "Client: %s (cached)\n", String8(package).string());
+        dprintf(outFd, "Client: %s (cached)\n", package.c_str());
         dprintf(outFd, "%s\n", kv.second.c_str());
         printedSomething = true;
     }
@@ -5629,8 +5589,8 @@
 
 // Print all events in vector `events' that came after lastPrintedEvent
 void printNewWatchedEvents(int outFd,
-                           const char *cameraId,
-                           const String16 &packageName,
+                           const std::string &cameraId,
+                           const std::string &packageName,
                            const std::vector<std::string> &events,
                            const std::string &lastPrintedEvent) {
     if (events.empty()) { return; }
@@ -5644,17 +5604,13 @@
 
     if (lastPrintedIdx == 0) { return; } // early exit if no new event in `events`
 
-    String8 packageName8(packageName);
-    const char *printablePackageName = packageName8.lockBuffer(packageName8.size());
-
     // print events in chronological order (latest event last)
     size_t idxToPrint = lastPrintedIdx;
     do {
         idxToPrint--;
-        dprintf(outFd, "%s:%s  %s", cameraId, printablePackageName, events[idxToPrint].c_str());
+        dprintf(outFd, "%s:%s  %s", cameraId.c_str(), packageName.c_str(),
+                events[idxToPrint].c_str());
     } while (idxToPrint != 0);
-
-    packageName8.unlockBuffer();
 }
 
 // Returns true if adb shell cmd watch should be interrupted based on data in inFd. The watch
@@ -5731,12 +5687,12 @@
     long refreshTimeoutMs = 1000L; // refresh every 1s by default
     if (args.size() > 2) {
         size_t intervalIdx; // index of '-n'
-        for (intervalIdx = 2; intervalIdx < args.size() && String16("-n") != args[intervalIdx];
+        for (intervalIdx = 2; intervalIdx < args.size() && toString16("-n") != args[intervalIdx];
              intervalIdx++);
 
         size_t intervalValIdx = intervalIdx + 1;
         if (intervalValIdx < args.size()) {
-            refreshTimeoutMs = strtol(String8(args[intervalValIdx].string()), nullptr, 10);
+            refreshTimeoutMs = strtol(toStdString(args[intervalValIdx]).c_str(), nullptr, 10);
             if (errno) { return BAD_VALUE; }
         }
     }
@@ -5745,7 +5701,7 @@
     refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs;
 
     dprintf(outFd, "Press return to exit...\n\n");
-    std::map<String16, std::string> packageNameToLastEvent;
+    std::map<std::string, std::string> packageNameToLastEvent;
 
     while (true) {
         bool serviceLock = tryLock(mServiceLock);
@@ -5760,7 +5716,7 @@
             if (client.get() == nullptr) { continue; }
             if (!isClientWatchedLocked(client.get())) { continue; }
 
-            const String16 &packageName = client->getPackageName();
+            const std::string &packageName = client->getPackageName();
             // This also initializes the map entries with an empty string
             const std::string& lastPrintedEvent = packageNameToLastEvent[packageName];
 
@@ -5768,15 +5724,12 @@
             client->dumpWatchedEventsToVector(latestEvents);
 
             if (!latestEvents.empty()) {
-                String8 cameraId = clientDescriptor->getKey();
-                const char *printableCameraId = cameraId.lockBuffer(cameraId.size());
                 printNewWatchedEvents(outFd,
-                                      printableCameraId,
+                                      clientDescriptor->getKey(),
                                       packageName,
                                       latestEvents,
                                       lastPrintedEvent);
                 packageNameToLastEvent[packageName] = latestEvents[0];
-                cameraId.unlockBuffer();
             }
         }
         if (shouldInterruptWatchCommand(inFd, outFd, refreshTimeoutMs)) {
@@ -5786,17 +5739,14 @@
     return OK;
 }
 
-void CameraService::parseClientsToWatchLocked(String8 clients) {
+void CameraService::parseClientsToWatchLocked(const std::string &clients) {
     mWatchedClientPackages.clear();
 
-    const char *allSentinel = String8(kWatchAllClientsFlag).string();
+    std::istringstream iss(clients);
+    std::string nextClient;
 
-    char *tokenized = clients.lockBuffer(clients.size());
-    char *savePtr;
-    char *nextClient = strtok_r(tokenized, ",", &savePtr);
-
-    while (nextClient != nullptr) {
-        if (strcmp(nextClient, allSentinel) == 0) {
+    while (std::getline(iss, nextClient, ',')) {
+        if (nextClient == kWatchAllClientsFlag) {
             // Don't need to track any other package if 'all' is present
             mWatchedClientPackages.clear();
             mWatchedClientPackages.emplace(kWatchAllClientsFlag);
@@ -5805,9 +5755,7 @@
 
         // track package names
         mWatchedClientPackages.emplace(nextClient);
-        nextClient = strtok_r(nullptr, ",", &savePtr);
     }
-    clients.unlockBuffer();
 }
 
 status_t CameraService::printHelp(int out) {
@@ -5871,13 +5819,13 @@
     return mode;
 }
 
-status_t CameraService::checkIfInjectionCameraIsPresent(const String8& externalCamId,
+status_t CameraService::checkIfInjectionCameraIsPresent(const std::string& externalCamId,
         sp<BasicClient> clientSp) {
     std::unique_ptr<AutoConditionLock> lock =
             AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
     status_t res = NO_ERROR;
     if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) {
-        ALOGW("Device %s is not usable!", externalCamId.string());
+        ALOGW("Device %s is not usable!", externalCamId.c_str());
         mInjectionStatusListener->notifyInjectionError(
                 externalCamId, UNKNOWN_TRANSACTION);
         clientSp->notifyError(
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3214d4c..bc65293 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -119,19 +119,19 @@
     /////////////////////////////////////////////////////////////////////
     // HAL Callbacks - implements CameraProviderManager::StatusListener
 
-    virtual void        onDeviceStatusChanged(const String8 &cameraId,
+    virtual void        onDeviceStatusChanged(const std::string &cameraId,
             CameraDeviceStatus newHalStatus) override;
-    virtual void        onDeviceStatusChanged(const String8 &cameraId,
-            const String8 &physicalCameraId,
+    virtual void        onDeviceStatusChanged(const std::string &cameraId,
+            const std::string &physicalCameraId,
             CameraDeviceStatus newHalStatus) override;
     // This method may hold CameraProviderManager::mInterfaceMutex as a part
     // of calling getSystemCameraKind() internally. Care should be taken not to
     // directly / indirectly call this from callers who also hold
     // mInterfaceMutex.
-    virtual void        onTorchStatusChanged(const String8& cameraId,
+    virtual void        onTorchStatusChanged(const std::string& cameraId,
             TorchModeStatus newStatus) override;
     // Does not hold CameraProviderManager::mInterfaceMutex.
-    virtual void        onTorchStatusChanged(const String8& cameraId,
+    virtual void        onTorchStatusChanged(const std::string& cameraId,
             TorchModeStatus newStatus,
             SystemCameraKind kind) override;
     virtual void        onNewProviderRegistered() override;
@@ -142,7 +142,7 @@
 
     virtual binder::Status     getCameraInfo(int cameraId, bool overrideToPortrait,
             hardware::CameraInfo* cameraInfo) override;
-    virtual binder::Status     getCameraCharacteristics(const String16& cameraId,
+    virtual binder::Status     getCameraCharacteristics(const std::string& cameraId,
             int targetSdkVersion, bool overrideToPortrait, CameraMetadata* cameraInfo) override;
     virtual binder::Status     getCameraVendorTagDescriptor(
             /*out*/
@@ -152,15 +152,16 @@
             hardware::camera2::params::VendorTagDescriptorCache* cache);
 
     virtual binder::Status     connect(const sp<hardware::ICameraClient>& cameraClient,
-            int32_t cameraId, const String16& clientPackageName,
+            int32_t cameraId, const std::string& clientPackageName,
             int32_t clientUid, int clientPid, int targetSdkVersion,
             bool overrideToPortrait, bool forceSlowJpegMode,
             /*out*/
             sp<hardware::ICamera>* device) override;
 
     virtual binder::Status     connectDevice(
-            const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
-            const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
+            const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+            const std::string& cameraId,
+            const std::string& clientPackageName, const std::optional<std::string>& clientFeatureId,
             int32_t clientUid, int scoreOffset, int targetSdkVersion, bool overrideToPortrait,
             /*out*/
             sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -182,15 +183,15 @@
     virtual binder::Status    getLegacyParameters(
             int32_t cameraId,
             /*out*/
-            String16* parameters);
+            std::string* parameters);
 
-    virtual binder::Status    setTorchMode(const String16& cameraId, bool enabled,
+    virtual binder::Status    setTorchMode(const std::string& cameraId, bool enabled,
             const sp<IBinder>& clientBinder);
 
-    virtual binder::Status    turnOnTorchWithStrengthLevel(const String16& cameraId,
+    virtual binder::Status    turnOnTorchWithStrengthLevel(const std::string& cameraId,
             int32_t torchStrength, const sp<IBinder>& clientBinder);
 
-    virtual binder::Status    getTorchStrengthLevel(const String16& cameraId,
+    virtual binder::Status    getTorchStrengthLevel(const std::string& cameraId,
             int32_t* torchStrength);
 
     virtual binder::Status    notifySystemEvent(int32_t eventId,
@@ -202,24 +203,24 @@
 
     // OK = supports api of that version, -EOPNOTSUPP = does not support
     virtual binder::Status    supportsCameraApi(
-            const String16& cameraId, int32_t apiVersion,
+            const std::string& cameraId, int32_t apiVersion,
             /*out*/
             bool *isSupported);
 
     virtual binder::Status    isHiddenPhysicalCamera(
-            const String16& cameraId,
+            const std::string& cameraId,
             /*out*/
             bool *isSupported);
 
     virtual binder::Status injectCamera(
-            const String16& packageName, const String16& internalCamId,
-            const String16& externalCamId,
+            const std::string& packageName, const std::string& internalCamId,
+            const std::string& externalCamId,
             const sp<hardware::camera2::ICameraInjectionCallback>& callback,
             /*out*/
             sp<hardware::camera2::ICameraInjectionSession>* cameraInjectionSession);
 
     virtual binder::Status reportExtensionSessionStats(
-            const hardware::CameraExtensionSessionStats& stats, String16* sessionKey /*out*/);
+            const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/);
 
     // Extra permissions checks
     virtual status_t    onTransact(uint32_t code, const Parcel& data,
@@ -242,7 +243,7 @@
     void cacheDump();
 
     // Register an offline client for a given active camera id
-    status_t addOfflineClient(String8 cameraId, sp<BasicClient> offlineClient);
+    status_t addOfflineClient(const std::string &cameraId, sp<BasicClient> offlineClient);
 
     /////////////////////////////////////////////////////////////////////
     // Client functionality
@@ -261,7 +262,7 @@
 
     /////////////////////////////////////////////////////////////////////
     // CameraDeviceFactory functionality
-    std::pair<int, IPCTransport>    getDeviceVersion(const String8& cameraId,
+    std::pair<int, IPCTransport>    getDeviceVersion(const std::string& cameraId,
             bool overrideToPortrait, int* portraitRotation,
             int* facing = nullptr, int* orientation = nullptr);
 
@@ -289,7 +290,7 @@
     friend class CameraService;
     public:
         virtual status_t       initialize(sp<CameraProviderManager> manager,
-                const String8& monitorTags) = 0;
+                const std::string& monitorTags) = 0;
         virtual binder::Status disconnect();
 
         // because we can't virtually inherit IInterface, which breaks
@@ -310,12 +311,12 @@
         // Internal dump method to be called by CameraService
         virtual status_t dumpClient(int fd, const Vector<String16>& args) = 0;
 
-        virtual status_t startWatchingTags(const String8 &tags, int outFd);
+        virtual status_t startWatchingTags(const std::string &tags, int outFd);
         virtual status_t stopWatchingTags(int outFd);
         virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
 
         // Return the package name for this client
-        virtual String16 getPackageName() const;
+        virtual std::string getPackageName() const;
 
         // Return the camera facing for this client
         virtual int getCameraFacing() const;
@@ -383,7 +384,7 @@
 
         // The injection camera session to replace the internal camera
         // session.
-        virtual status_t injectCamera(const String8& injectedCamId,
+        virtual status_t injectCamera(const std::string& injectedCamId,
                 sp<CameraProviderManager> manager) = 0;
 
         // Stop the injection camera and restore to internal camera session.
@@ -392,10 +393,10 @@
     protected:
         BasicClient(const sp<CameraService>& cameraService,
                 const sp<IBinder>& remoteCallback,
-                const String16& clientPackageName,
+                const std::string& clientPackageName,
                 bool nativeClient,
-                const std::optional<String16>& clientFeatureId,
-                const String8& cameraIdStr,
+                const std::optional<std::string>& clientFeatureId,
+                const std::string& cameraIdStr,
                 int cameraFacing,
                 int sensorOrientation,
                 int clientPid,
@@ -413,12 +414,12 @@
 
         // these are initialized in the constructor.
         static sp<CameraService>        sCameraService;
-        const String8                   mCameraIdStr;
+        const std::string               mCameraIdStr;
         const int                       mCameraFacing;
         const int                       mOrientation;
-        String16                        mClientPackageName;
+        std::string                     mClientPackageName;
         bool                            mSystemNativeClient;
-        std::optional<String16>         mClientFeatureId;
+        std::optional<std::string>      mClientFeatureId;
         pid_t                           mClientPid;
         const uid_t                     mClientUid;
         const pid_t                     mServicePid;
@@ -505,10 +506,10 @@
         // Interface used by CameraService
         Client(const sp<CameraService>& cameraService,
                 const sp<hardware::ICameraClient>& cameraClient,
-                const String16& clientPackageName,
+                const std::string& clientPackageName,
                 bool systemNativeClient,
-                const std::optional<String16>& clientFeatureId,
-                const String8& cameraIdStr,
+                const std::optional<std::string>& clientFeatureId,
+                const std::string& cameraIdStr,
                 int api1CameraId,
                 int cameraFacing,
                 int sensorOrientation,
@@ -552,13 +553,13 @@
      */
     class ClientEventListener {
     public:
-        void onClientAdded(const resource_policy::ClientDescriptor<String8,
+        void onClientAdded(const resource_policy::ClientDescriptor<std::string,
                 sp<CameraService::BasicClient>>& descriptor);
-        void onClientRemoved(const resource_policy::ClientDescriptor<String8,
+        void onClientRemoved(const resource_policy::ClientDescriptor<std::string,
                 sp<CameraService::BasicClient>>& descriptor);
     }; // class ClientEventListener
 
-    typedef std::shared_ptr<resource_policy::ClientDescriptor<String8,
+    typedef std::shared_ptr<resource_policy::ClientDescriptor<std::string,
             sp<CameraService::BasicClient>>> DescriptorPtr;
 
     /**
@@ -569,7 +570,7 @@
      * This class manages the eviction behavior for the camera clients.  See the parent class
      * implementation in utils/ClientManager for the specifics of this behavior.
      */
-    class CameraClientManager : public resource_policy::ClientManager<String8,
+    class CameraClientManager : public resource_policy::ClientManager<std::string,
             sp<CameraService::BasicClient>, ClientEventListener> {
     public:
         CameraClientManager();
@@ -579,18 +580,19 @@
          * Return a strong pointer to the active BasicClient for this camera ID, or an empty
          * if none exists.
          */
-        sp<CameraService::BasicClient> getCameraClient(const String8& id) const;
+        sp<CameraService::BasicClient> getCameraClient(const std::string& id) const;
 
         /**
          * Return a string describing the current state.
          */
-        String8 toString() const;
+        std::string toString() const;
 
         /**
          * Make a ClientDescriptor object wrapping the given BasicClient strong pointer.
          */
-        static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
-                int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
+        static DescriptorPtr makeClientDescriptor(const std::string& key,
+                const sp<BasicClient>& value, int32_t cost,
+                const std::set<std::string>& conflictingKeys, int32_t score,
                 int32_t ownerId, int32_t state, int oomScoreOffset, bool systemNativeClient);
 
         /**
@@ -650,7 +652,7 @@
          * Make a new CameraState and set the ID, cost, and conflicting devices using the values
          * returned in the HAL's camera_info struct for each device.
          */
-        CameraState(const String8& id, int cost, const std::set<String8>& conflicting,
+        CameraState(const std::string& id, int cost, const std::set<std::string>& conflicting,
                 SystemCameraKind deviceKind, const std::vector<std::string>& physicalCameras);
         virtual ~CameraState();
 
@@ -664,7 +666,7 @@
         /**
          * This function updates the status for this camera device, unless the given status
          * is in the given list of rejected status states, and execute the function passed in
-         * with a signature onStatusUpdateLocked(const String8&, int32_t)
+         * with a signature onStatusUpdateLocked(const std::string&, int32_t)
          * if the status has changed.
          *
          * This method is idempotent, and will not result in the function passed to
@@ -673,7 +675,7 @@
          */
         template<class Func>
         void updateStatus(StatusInternal status,
-                const String8& cameraId,
+                const std::string& cameraId,
                 std::initializer_list<StatusInternal> rejectSourceStates,
                 Func onStatusUpdatedLocked);
 
@@ -696,12 +698,7 @@
         /**
          * Return a set of the IDs of conflicting devices advertised by the HAL for this device.
          */
-        std::set<String8> getConflicting() const;
-
-        /**
-         * Return the ID of this camera device.
-         */
-        String8 getId() const;
+        std::set<std::string> getConflicting() const;
 
         /**
          * Return the kind (SystemCameraKind) of this camera device.
@@ -717,28 +714,28 @@
         /**
          * Add/Remove the unavailable physical camera ID.
          */
-        bool addUnavailablePhysicalId(const String8& physicalId);
-        bool removeUnavailablePhysicalId(const String8& physicalId);
+        bool addUnavailablePhysicalId(const std::string& physicalId);
+        bool removeUnavailablePhysicalId(const std::string& physicalId);
 
         /**
          * Set and get client package name.
          */
-        void setClientPackage(const String8& clientPackage);
-        String8 getClientPackage() const;
+        void setClientPackage(const std::string& clientPackage);
+        std::string getClientPackage() const;
 
         /**
          * Return the unavailable physical ids for this device.
          *
          * This method acquires mStatusLock.
          */
-        std::vector<String8> getUnavailablePhysicalIds() const;
+        std::vector<std::string> getUnavailablePhysicalIds() const;
     private:
-        const String8 mId;
+        const std::string mId;
         StatusInternal mStatus; // protected by mStatusLock
         const int mCost;
-        std::set<String8> mConflicting;
-        std::set<String8> mUnavailablePhysicalIds;
-        String8 mClientPackage;
+        std::set<std::string> mConflicting;
+        std::set<std::string> mUnavailablePhysicalIds;
+        std::string mClientPackage;
         mutable Mutex mStatusLock;
         CameraParameters mShimParams;
         const SystemCameraKind mSystemCameraKind;
@@ -758,7 +755,7 @@
         void registerSelf();
         void unregisterSelf();
 
-        bool isUidActive(uid_t uid, String16 callingPackage);
+        bool isUidActive(uid_t uid, const std::string &callingPackage);
         int32_t getProcState(uid_t uid);
 
         // IUidObserver
@@ -769,8 +766,8 @@
                 int32_t capability) override;
         void onUidProcAdjChanged(uid_t uid, int adj) override;
 
-        void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
-        void removeOverrideUid(uid_t uid, String16 callingPackage);
+        void addOverrideUid(uid_t uid, const std::string &callingPackage, bool active);
+        void removeOverrideUid(uid_t uid, const std::string &callingPackage);
 
         void registerMonitorUid(uid_t uid, bool openCamera);
         void unregisterMonitorUid(uid_t uid, bool closeCamera);
@@ -781,9 +778,10 @@
         // IBinder::DeathRecipient implementation
         virtual void binderDied(const wp<IBinder> &who);
     private:
-        bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+        bool isUidActiveLocked(uid_t uid, const std::string &callingPackage);
         int32_t getProcStateLocked(uid_t uid);
-        void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
+        void updateOverrideUid(uid_t uid, const std::string &callingPackage, bool active,
+                bool insert);
         void registerWithActivityManager();
 
         struct MonitoredUid {
@@ -853,8 +851,8 @@
 
     // Add/remove a new camera to camera and torch state lists or remove an unplugged one
     // Caller must not hold mServiceLock
-    void addStates(const String8 id);
-    void removeStates(const String8 id);
+    void addStates(const std::string& id);
+    void removeStates(const std::string& id);
 
     // Check if we can connect, before we acquire the service lock.
     // The returned originalClientPid is the PID of the original process that wants to connect to
@@ -863,24 +861,25 @@
     // originalClientPid and clientPid are usually the same except when the application uses
     // mediaserver to connect to camera (using MediaRecorder to connect to camera). In that case,
     // clientPid is the PID of mediaserver and originalClientPid is the PID of the application.
-    binder::Status validateConnectLocked(const String8& cameraId, const String8& clientName8,
+    binder::Status validateConnectLocked(const std::string& cameraId, const std::string& clientName,
             /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const;
-    binder::Status validateClientPermissionsLocked(const String8& cameraId, const String8& clientName8,
-            /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const;
+    binder::Status validateClientPermissionsLocked(const std::string& cameraId,
+            const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid,
+            /*out*/int& originalClientPid) const;
 
     // Handle active client evictions, and update service state.
     // Only call with with mServiceLock held.
-    status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
-        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
-        int scoreOffset, bool systemNativeClient,
+    status_t handleEvictionsLocked(const std::string& cameraId, int clientPid,
+        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback,
+        const std::string& packageName, int scoreOffset, bool systemNativeClient,
         /*out*/
         sp<BasicClient>* client,
-        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
+        std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial);
 
     // Should an operation attempt on a cameraId be rejected ? (this can happen
     // under various conditions. For example if a camera device is advertised as
     // system only or hidden secure camera, amongst possible others.
-    bool shouldRejectSystemCameraConnection(const String8 & cameraId) const;
+    bool shouldRejectSystemCameraConnection(const std::string& cameraId) const;
 
     // 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
@@ -892,7 +891,7 @@
     // getSystemCameraKind() needs mInterfaceMutex which might lead to deadlocks
     // if held along with mStatusListenerLock (depending on lock ordering, b/141756275), it is
     // recommended that we don't call this function with mStatusListenerLock held.
-    status_t getSystemCameraKind(const String8& cameraId, SystemCameraKind *kind) const;
+    status_t getSystemCameraKind(const std::string& cameraId, SystemCameraKind *kind) const;
 
     // Update the set of API1Compatible camera devices without including system
     // cameras and secure cameras. This is used for hiding system only cameras
@@ -908,13 +907,13 @@
     // as for legacy apps we will toggle the app op for all packages in the UID.
     // The caveat is that the operation may be attributed to the wrong package and
     // stats based on app ops may be slightly off.
-    String16 getPackageNameFromUid(int clientUid);
+    std::string getPackageNameFromUid(int clientUid);
 
     // Single implementation shared between the various connect calls
     template<class CALLBACK, class CLIENT>
-    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
-            int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
-            const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
+    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
+            int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
+            const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
             apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
             bool overrideToPortrait, bool forceSlowJpegMode,
             /*out*/sp<CLIENT>& device);
@@ -926,37 +925,38 @@
     std::shared_ptr<WaitableMutexWrapper> mServiceLockWrapper;
 
     // Return NO_ERROR if the device with a give ID can be connected to
-    status_t checkIfDeviceIsUsable(const String8& cameraId) const;
+    status_t checkIfDeviceIsUsable(const std::string& cameraId) const;
 
     // Container for managing currently active application-layer clients
     CameraClientManager mActiveClientManager;
 
     // Adds client logs during open session to the file pointed by fd.
-    void dumpOpenSessionClientLogs(int fd, const Vector<String16>& args, const String8& cameraId);
+    void dumpOpenSessionClientLogs(int fd, const Vector<String16>& args,
+            const std::string& cameraId);
 
     // Adds client logs during closed session to the file pointed by fd.
-    void dumpClosedSessionClientLogs(int fd, const String8& cameraId);
+    void dumpClosedSessionClientLogs(int fd, const std::string& cameraId);
 
     // Mapping from camera ID -> state for each device, map is protected by mCameraStatesLock
-    std::map<String8, std::shared_ptr<CameraState>> mCameraStates;
+    std::map<std::string, std::shared_ptr<CameraState>> mCameraStates;
 
     // Mutex guarding mCameraStates map
     mutable Mutex mCameraStatesLock;
 
     // Circular buffer for storing event logging for dumps
-    RingBuffer<String8> mEventLog;
+    RingBuffer<std::string> mEventLog;
     Mutex mLogLock;
 
     // set of client package names to watch. if this set contains 'all', then all clients will
     // be watched. Access should be guarded by mLogLock
-    std::set<String16> mWatchedClientPackages;
+    std::set<std::string> mWatchedClientPackages;
     // cache of last monitored tags dump immediately before the client disconnects. If a client
     // re-connects, its entry is not updated until it disconnects again. Access should be guarded
     // by mLogLock
-    std::map<String16, std::string> mWatchedClientsDumpCache;
+    std::map<std::string, std::string> mWatchedClientsDumpCache;
 
     // The last monitored tags set by client
-    String8 mMonitorTags;
+    std::string mMonitorTags;
 
     // Currently allowed user IDs
     std::set<userid_t> mAllowedUsers;
@@ -966,7 +966,7 @@
      *
      * This acquires mCameraStatesLock.
      */
-    std::shared_ptr<CameraService::CameraState> getCameraState(const String8& cameraId) const;
+    std::shared_ptr<CameraService::CameraState> getCameraState(const std::string& cameraId) const;
 
     /**
      * Evict client who's remote binder has died.  Returns true if this client was in the active
@@ -997,7 +997,7 @@
      * Returns the underlying camera Id string mapped to a camera id int
      * Empty string is returned when the cameraIdInt is invalid.
      */
-    String8 cameraIdIntToStr(int cameraIdInt);
+    std::string cameraIdIntToStr(int cameraIdInt);
 
     /**
      * Returns the underlying camera Id string mapped to a camera id int
@@ -1011,7 +1011,7 @@
      *
      * This method must be called with mServiceLock held.
      */
-    sp<CameraService::BasicClient> removeClientLocked(const String8& cameraId);
+    sp<CameraService::BasicClient> removeClientLocked(const std::string& cameraId);
 
     /**
      * Handle a notification that the current device user has changed.
@@ -1021,39 +1021,41 @@
     /**
      * Add an event log message.
      */
-    void logEvent(const char* event);
+    void logEvent(const std::string &event);
 
     /**
      * Add an event log message that a client has been disconnected.
      */
-    void logDisconnected(const char* cameraId, int clientPid, const char* clientPackage);
+    void logDisconnected(const std::string &cameraId, int clientPid,
+            const std::string &clientPackage);
 
     /**
      * Add an event log message that a client has been disconnected from offline device.
      */
-    void logDisconnectedOffline(const char* cameraId, int clientPid, const char* clientPackage);
+    void logDisconnectedOffline(const std::string &cameraId, int clientPid,
+            const std::string &clientPackage);
 
     /**
      * Add an event log message that an offline client has been connected.
      */
-    void logConnectedOffline(const char* cameraId, int clientPid,
-            const char* clientPackage);
+    void logConnectedOffline(const std::string &cameraId, int clientPid,
+            const std::string &clientPackage);
 
     /**
      * Add an event log message that a client has been connected.
      */
-    void logConnected(const char* cameraId, int clientPid, const char* clientPackage);
+    void logConnected(const std::string &cameraId, int clientPid, const std::string &clientPackage);
 
     /**
      * Add an event log message that a client's connect attempt has been rejected.
      */
-    void logRejected(const char* cameraId, int clientPid, const char* clientPackage,
-            const char* reason);
+    void logRejected(const std::string &cameraId, int clientPid, const std::string &clientPackage,
+            const std::string &reason);
 
     /**
      * Add an event log message when a client calls setTorchMode succesfully.
      */
-    void logTorchEvent(const char* cameraId, const char *torchState, int clientPid);
+    void logTorchEvent(const std::string &cameraId, const std::string &torchState, int clientPid);
 
     /**
      * Add an event log message that the current device user has been switched.
@@ -1064,30 +1066,30 @@
     /**
      * Add an event log message that a device has been removed by the HAL
      */
-    void logDeviceRemoved(const char* cameraId, const char* reason);
+    void logDeviceRemoved(const std::string &cameraId, const std::string &reason);
 
     /**
      * Add an event log message that a device has been added by the HAL
      */
-    void logDeviceAdded(const char* cameraId, const char* reason);
+    void logDeviceAdded(const std::string &cameraId, const std::string &reason);
 
     /**
      * Add an event log message that a client has unexpectedly died.
      */
-    void logClientDied(int clientPid, const char* reason);
+    void logClientDied(int clientPid, const std::string &reason);
 
     /**
      * Add a event log message that a serious service-level error has occured
      * The errorCode should be one of the Android Errors
      */
-    void logServiceError(const char* msg, int errorCode);
+    void logServiceError(const std::string &msg, int errorCode);
 
     /**
      * Dump the event log to an FD
      */
     void dumpEventLog(int fd);
 
-    void cacheClientTagDumpIfNeeded(const char *cameraId, BasicClient *client);
+    void cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient *client);
 
     /**
      * This method will acquire mServiceLock
@@ -1203,18 +1205,19 @@
      * This method acquires mStatusLock and mStatusListenerLock.
      */
     void updateStatus(StatusInternal status,
-            const String8& cameraId,
+            const std::string& cameraId,
             std::initializer_list<StatusInternal>
                 rejectedSourceStates);
     void updateStatus(StatusInternal status,
-            const String8& cameraId);
+            const std::string& cameraId);
 
     /**
      * Update the opened/closed status of the given camera id.
      *
      * This method acqiures mStatusListenerLock.
      */
-    void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName);
+    void updateOpenCloseStatus(const std::string& cameraId, bool open,
+            const std::string& packageName);
 
     // flashlight control
     sp<CameraFlashlight> mFlashlight;
@@ -1225,38 +1228,38 @@
     // guard mTorchUidMap
     Mutex                mTorchUidMapMutex;
     // camera id -> torch status
-    KeyedVector<String8, TorchModeStatus>
+    KeyedVector<std::string, TorchModeStatus>
             mTorchStatusMap;
     // camera id -> torch client binder
     // only store the last client that turns on each camera's torch mode
-    KeyedVector<String8, sp<IBinder>> mTorchClientMap;
+    KeyedVector<std::string, sp<IBinder>> mTorchClientMap;
     // camera id -> [incoming uid, current uid] pair
-    std::map<String8, std::pair<int, int>> mTorchUidMap;
+    std::map<std::string, std::pair<int, int>> mTorchUidMap;
 
     // check and handle if torch client's process has died
     void handleTorchClientBinderDied(const wp<IBinder> &who);
 
     // handle torch mode status change and invoke callbacks. mTorchStatusMutex
     // should be locked.
-    void onTorchStatusChangedLocked(const String8& cameraId,
+    void onTorchStatusChangedLocked(const std::string& cameraId,
             TorchModeStatus newStatus,
             SystemCameraKind systemCameraKind);
 
     // get a camera's torch status. mTorchStatusMutex should be locked.
-    status_t getTorchStatusLocked(const String8 &cameraId,
+    status_t getTorchStatusLocked(const std::string &cameraId,
              TorchModeStatus *status) const;
 
     // set a camera's torch status. mTorchStatusMutex should be locked.
-    status_t setTorchStatusLocked(const String8 &cameraId,
+    status_t setTorchStatusLocked(const std::string &cameraId,
             TorchModeStatus status);
 
     // notify physical camera status when the physical camera is public.
     // Expects mStatusListenerLock to be locked.
-    void notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId,
-            const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind);
+    void notifyPhysicalCameraStatusLocked(int32_t status, const std::string& physicalCameraId,
+            const std::list<std::string>& logicalCameraIds, SystemCameraKind deviceKind);
 
     // get list of logical cameras which are backed by physicalCameraId
-    std::list<String16> getLogicalCameras(const String8& physicalCameraId);
+    std::list<std::string> getLogicalCameras(const std::string& physicalCameraId);
 
 
     // IBinder::DeathRecipient implementation
@@ -1348,7 +1351,7 @@
     // Parses comma separated clients list and adds them to mWatchedClientPackages.
     // Does not acquire mLogLock before modifying mWatchedClientPackages. It is the caller's
     // responsibility to acquire mLogLock before calling this function.
-    void parseClientsToWatchLocked(String8 clients);
+    void parseClientsToWatchLocked(const std::string &clients);
 
     // Prints the shell command help
     status_t printHelp(int out);
@@ -1365,39 +1368,37 @@
     /**
      * Get the current system time as a formatted string.
      */
-    static String8 getFormattedCurrentTime();
+    static std::string getFormattedCurrentTime();
 
     static binder::Status makeClient(const sp<CameraService>& cameraService,
-            const sp<IInterface>& cameraCb, const String16& packageName,
-            bool systemNativeClient, const std::optional<String16>& featureId,
-            const String8& cameraId, int api1CameraId, int facing, int sensorOrientation,
+            const sp<IInterface>& cameraCb, const std::string& packageName,
+            bool systemNativeClient, const std::optional<std::string>& featureId,
+            const std::string& cameraId, int api1CameraId, int facing, int sensorOrientation,
             int clientPid, uid_t clientUid, int servicePid,
             std::pair<int, IPCTransport> deviceVersionAndIPCTransport, apiLevel effectiveApiLevel,
             bool overrideForPerfClass, bool overrideToPortrait, bool forceSlowJpegMode,
             /*out*/sp<BasicClient>* client);
 
-    status_t checkCameraAccess(const String16& opPackageName);
-
-    static String8 toString(std::set<userid_t> intSet);
+    static std::string toString(std::set<userid_t> intSet);
     static int32_t mapToInterface(TorchModeStatus status);
     static StatusInternal mapToInternal(CameraDeviceStatus status);
     static int32_t mapToInterface(StatusInternal status);
 
 
-    void broadcastTorchModeStatus(const String8& cameraId,
+    void broadcastTorchModeStatus(const std::string& cameraId,
             TorchModeStatus status, SystemCameraKind systemCameraKind);
 
-    void broadcastTorchStrengthLevel(const String8& cameraId, int32_t newTorchStrengthLevel);
+    void broadcastTorchStrengthLevel(const std::string& cameraId, int32_t newTorchStrengthLevel);
 
-    void disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect);
+    void disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect);
 
     // Regular online and offline devices must not be in conflict at camera service layer.
     // Use separate keys for offline devices.
-    static const String8 kOfflineDevice;
+    static const std::string kOfflineDevice;
 
     // Sentinel value to be stored in `mWatchedClientsPackages` to indicate that all clients should
     // be watched.
-    static const String16 kWatchAllClientsFlag;
+    static const std::string kWatchAllClientsFlag;
 
     // TODO: right now each BasicClient holds one AppOpsManager instance.
     // We can refactor the code so all of clients share this instance
@@ -1438,7 +1439,7 @@
 
             void addListener(const sp<hardware::camera2::ICameraInjectionCallback>& callback);
             void removeListener();
-            void notifyInjectionError(String8 injectedCamId, status_t err);
+            void notifyInjectionError(const std::string &injectedCamId, status_t err);
 
             // IBinder::DeathRecipient implementation
             virtual void binderDied(const wp<IBinder>& who);
@@ -1467,15 +1468,15 @@
 
     // When injecting the camera, it will check whether the injecting camera status is unavailable.
     // If it is, the disconnect function will be called to to prevent camera access on the device.
-    status_t checkIfInjectionCameraIsPresent(const String8& externalCamId,
+    status_t checkIfInjectionCameraIsPresent(const std::string& externalCamId,
             sp<BasicClient> clientSp);
 
     void clearInjectionParameters();
 
     // This is the existing camera id being replaced.
-    String8 mInjectionInternalCamId;
+    std::string mInjectionInternalCamId;
     // This is the external camera Id replacing the internalId.
-    String8 mInjectionExternalCamId;
+    std::string mInjectionExternalCamId;
     bool mInjectionInitPending = false;
     // Guard mInjectionInternalCamId and mInjectionInitPending.
     Mutex mInjectionParametersLock;
@@ -1483,7 +1484,7 @@
     // Track the folded/unfoled device state. 0 == UNFOLDED, 4 == FOLDED
     int64_t mDeviceState;
 
-    void updateTorchUidMapLocked(const String16& cameraId, int uid);
+    void updateTorchUidMapLocked(const std::string& cameraId, int uid);
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.h b/services/camera/libcameraservice/CameraServiceWatchdog.h
index de6ac9e..9f25865 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.h
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.h
@@ -32,7 +32,6 @@
 #include <chrono>
 #include <thread>
 #include <time.h>
-#include <utils/String8.h>
 #include <utils/Thread.h>
 #include <utils/Log.h>
 #include <unordered_map>
@@ -58,13 +57,13 @@
 };
 
 public:
-    explicit CameraServiceWatchdog(const String8 &cameraId,
+    explicit CameraServiceWatchdog(const std::string &cameraId,
             std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
                     mCameraId(cameraId), mPause(true), mMaxCycles(kMaxCycles),
                     mCycleLengthMs(kCycleLengthMs), mEnabled(true),
                     mCameraServiceProxyWrapper(cameraServiceProxyWrapper) {};
 
-    explicit CameraServiceWatchdog (const String8 &cameraId, size_t maxCycles,
+    explicit CameraServiceWatchdog (const std::string &cameraId, size_t maxCycles,
             uint32_t cycleLengthMs, bool enabled,
             std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
                     mCameraId(cameraId), mPause(true), mMaxCycles(maxCycles),
@@ -151,7 +150,7 @@
     Mutex           mWatchdogLock;      // Lock for condition variable
     Mutex           mEnabledLock;       // Lock for enabled status
     Condition       mWatchdogCondition; // Condition variable for stop/start
-    String8         mCameraId;          // Camera Id the watchdog belongs to
+    std::string     mCameraId;          // Camera Id the watchdog belongs to
     bool            mPause;             // True if tid map is empty
     uint32_t        mMaxCycles;         // Max cycles
     uint32_t        mCycleLengthMs;     // Length of time elapsed per cycle
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.cpp b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
index 4232a81..a62f6de 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraService.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
@@ -86,7 +86,7 @@
     if (_aidl_return == nullptr) { return fromSStatus(SStatus::ILLEGAL_ARGUMENT); }
 
     ::android::CameraMetadata cameraMetadata;
-    UStatus ret = mCameraService->getCameraCharacteristics(String16(in_cameraId.c_str()),
+    UStatus ret = mCameraService->getCameraCharacteristics(in_cameraId,
                                                            mVndkVersion,
                                                            /* overrideToPortrait= */ false,
                                                            &cameraMetadata);
@@ -140,8 +140,8 @@
     sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
     binder::Status serviceRet = mCameraService->connectDevice(
             callbacks,
-            String16(in_cameraId.c_str()),
-            String16(""),
+            in_cameraId,
+            std::string(),
             /* clientFeatureId= */{},
             hardware::ICameraService::USE_CALLING_UID,
             /* scoreOffset= */ 0,
@@ -249,7 +249,7 @@
             [this](const hardware::CameraStatus& s) {
                 bool supportsHAL3 = false;
                 binder::Status sRet =
-                            mCameraService->supportsCameraApi(String16(s.cameraId),
+                            mCameraService->supportsCameraApi(s.cameraId,
                                     UICameraService::API_VERSION_2, &supportsHAL3);
                 return !sRet.isOk() || !supportsHAL3;
             }), cameraStatusAndIds->end());
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
index e183063..d7ab0d9 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
@@ -18,6 +18,7 @@
 #include <aidl/AidlUtils.h>
 #include <aidl/android/frameworks/cameraservice/common/Status.h>
 #include <aidl/android/frameworks/cameraservice/service/CameraStatusAndId.h>
+#include <camera/StringUtils.h>
 
 namespace android::frameworks::cameraservice::service::implementation {
 
@@ -27,34 +28,31 @@
 using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
 
 binder::Status AidlCameraServiceListener::onStatusChanged(
-        int32_t status, const ::android::String16& cameraId) {
+        int32_t status, const std::string& cameraId) {
     SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
-    std::string sCameraId = String8(cameraId).string();
-    auto ret = mBase->onStatusChanged(sStatus, sCameraId);
+    auto ret = mBase->onStatusChanged(sStatus, cameraId);
     LOG_STATUS_ERROR_IF_NOT_OK(ret, "onStatusChanged")
     return binder::Status::ok();
 }
 
 binder::Status AidlCameraServiceListener::onPhysicalCameraStatusChanged(
-        int32_t status, const ::android::String16& cameraId,
-        const ::android::String16& physicalCameraId) {
+        int32_t status, const std::string& cameraId,
+        const std::string& physicalCameraId) {
     SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
-    std::string sCameraId = String8(cameraId).string();
-    std::string sPhysicalCameraId = String8(physicalCameraId).string();
 
-    auto ret = mBase->onPhysicalCameraStatusChanged(sStatus, sCameraId, sPhysicalCameraId);
+    auto ret = mBase->onPhysicalCameraStatusChanged(sStatus, cameraId, physicalCameraId);
     LOG_STATUS_ERROR_IF_NOT_OK(ret, "onPhysicalCameraStatusChanged")
     return binder::Status::ok();
 }
 
 ::android::binder::Status AidlCameraServiceListener::onTorchStatusChanged(
-    int32_t, const ::android::String16&) {
+    int32_t, const std::string&) {
   // We don't implement onTorchStatusChanged
   return binder::Status::ok();
 }
 
 ::android::binder::Status AidlCameraServiceListener::onTorchStrengthLevelChanged(
-    const ::android::String16&, int32_t) {
+    const std::string&, int32_t) {
     // We don't implement onTorchStrengthLevelChanged
     return binder::Status::ok();
 }
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
index 906dd8e..6483fe1 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
@@ -45,25 +45,25 @@
     ~AidlCameraServiceListener() = default;
 
     ::android::binder::Status onStatusChanged(int32_t status,
-            const ::android::String16& cameraId) override;
+            const std::string& cameraId) override;
     ::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
-            const ::android::String16& cameraId,
-            const ::android::String16& physicalCameraId) override;
+            const std::string& cameraId,
+            const std::string& physicalCameraId) override;
 
     ::android::binder::Status onTorchStatusChanged(
-            int32_t status, const ::android::String16& cameraId) override;
+            int32_t status, const std::string& cameraId) override;
     ::android::binder::Status onTorchStrengthLevelChanged(
-            const ::android::String16& cameraId, int32_t newStrengthLevel) override;
+            const std::string& cameraId, int32_t newStrengthLevel) override;
     binder::Status onCameraAccessPrioritiesChanged() override {
         // TODO: no implementation yet.
         return binder::Status::ok();
     }
-    binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
-            const ::android::String16& /*clientPackageId*/) override {
+    binder::Status onCameraOpened(const std::string& /*cameraId*/,
+            const std::string& /*clientPackageId*/) override {
         // empty implementation
         return binder::Status::ok();
     }
-    binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) override {
+    binder::Status onCameraClosed(const std::string& /*cameraId*/) override {
         // empty implementation
         return binder::Status::ok();
     }
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index 1b8e53b..7291c5f 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -22,6 +22,7 @@
 #include <device3/Camera3StreamInterface.h>
 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
 #include <mediautils/AImageReaderUtils.h>
+#include <camera/StringUtils.h>
 
 namespace android::hardware::cameraservice::utils::conversion::aidl {
 
@@ -80,9 +81,8 @@
         iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(nh)));
         native_handle_delete(nh);
     }
-    String16 physicalCameraId16(src.physicalCameraId.c_str());
     UOutputConfiguration outputConfiguration(
-        iGBPs, convertFromAidl(src.rotation), physicalCameraId16,
+        iGBPs, convertFromAidl(src.rotation), src.physicalCameraId,
         src.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
         (windowHandles.size() > 1));
     return outputConfiguration;
@@ -175,7 +175,7 @@
     dst.frameNumber = src.frameNumber;
     dst.partialResultCount = src.partialResultCount;
     dst.errorStreamId = src.errorStreamId;
-    dst.errorPhysicalCameraId = String8(src.errorPhysicalCameraId).string();
+    dst.errorPhysicalCameraId = src.errorPhysicalCameraId;
     return dst;
 }
 
@@ -217,7 +217,7 @@
 SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo & src,
                                          std::shared_ptr<CaptureResultMetadataQueue> & fmq) {
     SPhysicalCaptureResultInfo dst;
-    dst.physicalCameraId = String8(src.mPhysicalCameraId).string();
+    dst.physicalCameraId = src.mPhysicalCameraId;
 
     const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
     // Try using fmq at first.
@@ -242,12 +242,12 @@
     size_t i = 0;
     for (const auto &statusAndId : src) {
         auto &a = (*dst)[i++];
-        a.cameraId = statusAndId.cameraId.c_str();
+        a.cameraId = statusAndId.cameraId;
         a.deviceStatus = convertCameraStatusToAidl(statusAndId.status);
         size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
         a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
         for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
-            a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
+            a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
         }
     }
 }
@@ -302,4 +302,4 @@
     return OK;
 }
 
-} // namespace android::hardware::cameraservice::utils::conversion::aidl
\ No newline at end of file
+} // namespace android::hardware::cameraservice::utils::conversion::aidl
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 8348cd9..b388e5a 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -18,11 +18,14 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <sstream>
+
 #include <inttypes.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
 #include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
 #include <cutils/properties.h>
 #include <gui/Surface.h>
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
@@ -53,9 +56,9 @@
 Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
         const sp<hardware::ICameraClient>& cameraClient,
         std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-        const String16& clientPackageName,
-        const std::optional<String16>& clientFeatureId,
-        const String8& cameraDeviceId,
+        const std::string& clientPackageName,
+        const std::optional<std::string>& clientFeatureId,
+        const std::string& cameraDeviceId,
         int api1CameraId,
         int cameraFacing,
         int sensorOrientation,
@@ -83,7 +86,8 @@
     l.mParameters.isSlowJpegModeForced = forceSlowJpegMode;
 }
 
-status_t Camera2Client::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
+status_t Camera2Client::initialize(sp<CameraProviderManager> manager,
+        const std::string& monitorTags) {
     return initializeImpl(manager, monitorTags);
 }
 
@@ -103,7 +107,7 @@
 }
 
 template<typename TProviderPtr>
-status_t Camera2Client::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags)
+status_t Camera2Client::initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags)
 {
     ATRACE_CALL();
     ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
@@ -135,16 +139,11 @@
     CameraUtils::getRotationTransform(staticInfo, OutputConfiguration::MIRROR_MODE_AUTO,
             &mRotateAndCropPreviewTransform);
 
-    String8 threadName;
-
     mStreamingProcessor = new StreamingProcessor(this);
-    threadName = String8::format("C2-%d-StreamProc",
-            mCameraId);
 
+    std::string threadName = std::string("C2-") + std::to_string(mCameraId);
     mFrameProcessor = new FrameProcessor(mDevice, this);
-    threadName = String8::format("C2-%d-FrameProc",
-            mCameraId);
-    res = mFrameProcessor->run(threadName.string());
+    res = mFrameProcessor->run((threadName + "-FrameProc").c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start frame processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -152,9 +151,7 @@
     }
 
     mCaptureSequencer = new CaptureSequencer(this);
-    threadName = String8::format("C2-%d-CaptureSeq",
-            mCameraId);
-    res = mCaptureSequencer->run(threadName.string());
+    res = mCaptureSequencer->run((threadName + "-CaptureSeq").c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start capture sequencer thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -162,9 +159,7 @@
     }
 
     mJpegProcessor = new JpegProcessor(this, mCaptureSequencer);
-    threadName = String8::format("C2-%d-JpegProc",
-            mCameraId);
-    res = mJpegProcessor->run(threadName.string());
+    res = mJpegProcessor->run((threadName + "-JpegProc").c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start jpeg processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -172,10 +167,7 @@
     }
 
     mZslProcessor = new ZslProcessor(this, mCaptureSequencer);
-
-    threadName = String8::format("C2-%d-ZslProc",
-            mCameraId);
-    res = mZslProcessor->run(threadName.string());
+    res = mZslProcessor->run((threadName + "-ZslProc").c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start zsl processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -183,9 +175,7 @@
     }
 
     mCallbackProcessor = new CallbackProcessor(this);
-    threadName = String8::format("C2-%d-CallbkProc",
-            mCameraId);
-    res = mCallbackProcessor->run(threadName.string());
+    res = mCallbackProcessor->run((threadName + "-CallbkProc").c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start callback processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -196,7 +186,7 @@
         SharedParameters::Lock l(mParameters);
         ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
               mCameraId);
-        ALOGD("%s", l.mParameters.paramsFlattened.string());
+        ALOGD("%s", l.mParameters.paramsFlattened.c_str());
     }
 
     return OK;
@@ -218,47 +208,47 @@
 }
 
 status_t Camera2Client::dumpClient(int fd, const Vector<String16>& args) {
-    String8 result;
-    result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n", mCameraId,
+    std::ostringstream result;
+    result << fmt::sprintf("Client2[%d] (%p) PID: %d, dump:\n", mCameraId,
             (getRemoteCallback() != NULL ?
-                    (IInterface::asBinder(getRemoteCallback()).get()) : NULL),
+                    (void *) (IInterface::asBinder(getRemoteCallback()).get()) : NULL),
             mClientPid);
-    result.append("  State: ");
-#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
+    result << "  State: ";
+#define CASE_APPEND_ENUM(x) case x: result << #x "\n"; break;
 
     const Parameters& p = mParameters.unsafeAccess();
 
-    result.append(Parameters::getStateName(p.state));
+    result << Parameters::getStateName(p.state);
 
-    result.append("\n  Current parameters:\n");
-    result.appendFormat("    Preview size: %d x %d\n",
+    result << "\n  Current parameters:\n";
+    result << fmt::sprintf("    Preview size: %d x %d\n",
             p.previewWidth, p.previewHeight);
-    result.appendFormat("    Preview FPS range: %d - %d\n",
+    result << fmt::sprintf("    Preview FPS range: %d - %d\n",
             p.previewFpsRange[0], p.previewFpsRange[1]);
-    result.appendFormat("    Preview HAL pixel format: 0x%x\n",
+    result << fmt::sprintf("    Preview HAL pixel format: 0x%x\n",
             p.previewFormat);
-    result.appendFormat("    Preview transform: %x\n",
+    result << fmt::sprintf("    Preview transform: %x\n",
             p.previewTransform);
-    result.appendFormat("    Picture size: %d x %d\n",
+    result << fmt::sprintf("    Picture size: %d x %d\n",
             p.pictureWidth, p.pictureHeight);
-    result.appendFormat("    Jpeg thumbnail size: %d x %d\n",
+    result << fmt::sprintf("    Jpeg thumbnail size: %d x %d\n",
             p.jpegThumbSize[0], p.jpegThumbSize[1]);
-    result.appendFormat("    Jpeg quality: %d, thumbnail quality: %d\n",
+    result << fmt::sprintf("    Jpeg quality: %d, thumbnail quality: %d\n",
             p.jpegQuality, p.jpegThumbQuality);
-    result.appendFormat("    Jpeg rotation: %d\n", p.jpegRotation);
-    result.appendFormat("    GPS tags %s\n",
+    result << fmt::sprintf("    Jpeg rotation: %d\n", p.jpegRotation);
+    result << fmt::sprintf("    GPS tags %s\n",
             p.gpsEnabled ? "enabled" : "disabled");
     if (p.gpsEnabled) {
-        result.appendFormat("    GPS lat x long x alt: %f x %f x %f\n",
+        result << fmt::sprintf("    GPS lat x long x alt: %f x %f x %f\n",
                 p.gpsCoordinates[0], p.gpsCoordinates[1],
                 p.gpsCoordinates[2]);
-        result.appendFormat("    GPS timestamp: %" PRId64 "\n",
+        result << fmt::sprintf("    GPS timestamp: %" PRId64 "\n",
                 p.gpsTimestamp);
-        result.appendFormat("    GPS processing method: %s\n",
-                p.gpsProcessingMethod.string());
+        result << fmt::sprintf("    GPS processing method: %s\n",
+                p.gpsProcessingMethod.c_str());
     }
 
-    result.append("    White balance mode: ");
+    result << "    White balance mode: ";
     switch (p.wbMode) {
         CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_AUTO)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_INCANDESCENT)
@@ -268,10 +258,10 @@
         CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_TWILIGHT)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_SHADE)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Effect mode: ");
+    result << "    Effect mode: ";
     switch (p.effectMode) {
         CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_OFF)
         CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_MONO)
@@ -282,22 +272,22 @@
         CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD)
         CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD)
         CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_AQUA)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Antibanding mode: ");
+    result << "    Antibanding mode: ";
     switch (p.antibandingMode) {
         CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Scene mode: ");
+    result << "    Scene mode: ";
     switch (p.sceneMode) {
         case ANDROID_CONTROL_SCENE_MODE_DISABLED:
-            result.append("AUTO\n"); break;
+            result << "AUTO\n"; break;
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY)
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
@@ -314,10 +304,10 @@
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
         CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Flash mode: ");
+    result << "    Flash mode: ";
     switch (p.flashMode) {
         CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
         CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
@@ -325,10 +315,10 @@
         CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
         CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
         CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Focus mode: ");
+    result << "    Focus mode: ";
     switch (p.focusMode) {
         CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
         CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
@@ -338,10 +328,10 @@
         CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
         CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
         CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("   Focus state: ");
+    result << "   Focus state: ";
     switch (p.focusState) {
         CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_INACTIVE)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN)
@@ -350,12 +340,12 @@
         CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED)
         CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED)
-        default: result.append("UNKNOWN\n");
+        default: result << "UNKNOWN\n";
     }
 
-    result.append("    Focusing areas:\n");
+    result << "    Focusing areas:\n";
     for (size_t i = 0; i < p.focusingAreas.size(); i++) {
-        result.appendFormat("      [ (%d, %d, %d, %d), weight %d ]\n",
+        result << fmt::sprintf("      [ (%d, %d, %d, %d), weight %d ]\n",
                 p.focusingAreas[i].left,
                 p.focusingAreas[i].top,
                 p.focusingAreas[i].right,
@@ -363,16 +353,16 @@
                 p.focusingAreas[i].weight);
     }
 
-    result.appendFormat("    Exposure compensation index: %d\n",
+    result << fmt::sprintf("    Exposure compensation index: %d\n",
             p.exposureCompensation);
 
-    result.appendFormat("    AE lock %s, AWB lock %s\n",
+    result << fmt::sprintf("    AE lock %s, AWB lock %s\n",
             p.autoExposureLock ? "enabled" : "disabled",
             p.autoWhiteBalanceLock ? "enabled" : "disabled" );
 
-    result.appendFormat("    Metering areas:\n");
+    result << "    Metering areas:\n";
     for (size_t i = 0; i < p.meteringAreas.size(); i++) {
-        result.appendFormat("      [ (%d, %d, %d, %d), weight %d ]\n",
+        result << fmt::sprintf("      [ (%d, %d, %d, %d), weight %d ]\n",
                 p.meteringAreas[i].left,
                 p.meteringAreas[i].top,
                 p.meteringAreas[i].right,
@@ -380,54 +370,56 @@
                 p.meteringAreas[i].weight);
     }
 
-    result.appendFormat("    Zoom index: %d\n", p.zoom);
-    result.appendFormat("    Video size: %d x %d\n", p.videoWidth,
+    result << fmt::sprintf("    Zoom index: %d\n", p.zoom);
+    result << fmt::sprintf("    Video size: %d x %d\n", p.videoWidth,
             p.videoHeight);
 
-    result.appendFormat("    Recording hint is %s\n",
+    result << fmt::sprintf("    Recording hint is %s\n",
             p.recordingHint ? "set" : "not set");
 
-    result.appendFormat("    Video stabilization is %s\n",
+    result << fmt::sprintf("    Video stabilization is %s\n",
             p.videoStabilization ? "enabled" : "disabled");
 
-    result.appendFormat("    Selected still capture FPS range: %d - %d\n",
+    result << fmt::sprintf("    Selected still capture FPS range: %d - %d\n",
             p.fastInfo.bestStillCaptureFpsRange[0],
             p.fastInfo.bestStillCaptureFpsRange[1]);
 
-    result.appendFormat("    Use zero shutter lag: %s\n",
+    result << fmt::sprintf("    Use zero shutter lag: %s\n",
             p.useZeroShutterLag() ? "yes" : "no");
 
-    result.append("  Current streams:\n");
-    result.appendFormat("    Preview stream ID: %d\n",
+    result << "  Current streams:\n";
+    result << fmt::sprintf("    Preview stream ID: %d\n",
             getPreviewStreamId());
-    result.appendFormat("    Capture stream ID: %d\n",
+    result << fmt::sprintf("    Capture stream ID: %d\n",
             getCaptureStreamId());
-    result.appendFormat("    Recording stream ID: %d\n",
+    result << fmt::sprintf("    Recording stream ID: %d\n",
             getRecordingStreamId());
 
-    result.append("  Quirks for this camera:\n");
+    result << "  Quirks for this camera:\n";
     bool haveQuirk = false;
     if (p.quirks.triggerAfWithAuto) {
-        result.appendFormat("    triggerAfWithAuto\n");
+        result << "    triggerAfWithAuto\n";
         haveQuirk = true;
     }
     if (p.quirks.useZslFormat) {
-        result.appendFormat("    useZslFormat\n");
+        result << "    useZslFormat\n";
         haveQuirk = true;
     }
     if (p.quirks.meteringCropRegion) {
-        result.appendFormat("    meteringCropRegion\n");
+        result << "    meteringCropRegion\n";
         haveQuirk = true;
     }
     if (p.quirks.partialResults) {
-        result.appendFormat("    usePartialResult\n");
+        result << "    usePartialResult\n";
         haveQuirk = true;
     }
     if (!haveQuirk) {
-        result.appendFormat("    none\n");
+        result << "    none\n";
     }
 
-    write(fd, result.string(), result.size());
+    std::string resultStr = std::move(result.str());
+
+    write(fd, resultStr.c_str(), resultStr.size());
 
     mStreamingProcessor->dump(fd, args);
 
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 6bdb644..fe12690 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -107,9 +107,9 @@
     Camera2Client(const sp<CameraService>& cameraService,
             const sp<hardware::ICameraClient>& cameraClient,
             std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-            const String16& clientPackageName,
-            const std::optional<String16>& clientFeatureId,
-            const String8& cameraDeviceId,
+            const std::string& clientPackageName,
+            const std::optional<std::string>& clientFeatureId,
+            const std::string& cameraDeviceId,
             int api1CameraId,
             int cameraFacing,
             int sensorOrientation,
@@ -123,7 +123,7 @@
     virtual ~Camera2Client();
 
     virtual status_t initialize(sp<CameraProviderManager> manager,
-            const String8& monitorTags) override;
+            const std::string& monitorTags) override;
 
     virtual status_t dump(int fd, const Vector<String16>& args);
 
@@ -248,7 +248,7 @@
     status_t overrideVideoSnapshotSize(Parameters &params);
 
     template<typename TProviderPtr>
-    status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+    status_t initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
 
     bool isZslEnabledInStillTemplate();
     // The current rotate & crop mode passed by camera service
diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
index ee764ec..17db20b 100644
--- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
@@ -158,7 +158,7 @@
         res = device->createStream(mCallbackWindow,
                 params.previewWidth, params.previewHeight, callbackFormat,
                 HAL_DATASPACE_V0_JFIF, CAMERA_STREAM_ROTATION_0, &mCallbackStreamId,
-                String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+                std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
                     "%s (%d)", __FUNCTION__, mId,
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 4c9b7ed..0b5e03f 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -23,6 +23,7 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <utils/Vector.h>
+#include <camera/StringUtils.h>
 
 #include "api1/Camera2Client.h"
 #include "api1/client2/CaptureSequencer.h"
@@ -174,19 +175,19 @@
 
 
 void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
-    String8 result;
+    std::string result;
     if (mCaptureRequest.entryCount() != 0) {
         result = "    Capture request:\n";
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         mCaptureRequest.dump(fd, 2, 6);
     } else {
         result = "    Capture request: undefined\n";
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
-    result = String8::format("    Current capture state: %s\n",
+    result = fmt::sprintf("    Current capture state: %s\n",
             kStateNames[mCaptureState]);
-    result.append("    Latest captured frame:\n");
-    write(fd, result.string(), result.size());
+    result += "    Latest captured frame:\n";
+    write(fd, result.c_str(), result.size());
     mNewFrame.dump(fd, 2, 6);
 }
 
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index 467108d..eb00bf8 100755
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -83,7 +83,7 @@
     }
 
     // Find out buffer size for JPEG
-    ssize_t maxJpegSize = device->getJpegBufferSize(device->infoPhysical(String8("")),
+    ssize_t maxJpegSize = device->getJpegBufferSize(device->infoPhysical(""),
             params.pictureWidth, params.pictureHeight);
     if (maxJpegSize <= 0) {
         ALOGE("%s: Camera %d: Jpeg buffer size (%zu) is invalid ",
@@ -157,7 +157,7 @@
                 params.pictureWidth, params.pictureHeight,
                 HAL_PIXEL_FORMAT_BLOB, HAL_DATASPACE_V0_JFIF,
                 CAMERA_STREAM_ROTATION_0, &mCaptureStreamId,
-                String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+                std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for capture: "
                     "%s (%d)", __FUNCTION__, mId,
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 13dcbaa..aa3d1bb 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -164,7 +164,7 @@
                     availablePreviewSizes[i].width,
                     availablePreviewSizes[i].height);
         }
-        ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.string());
+        ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.c_str());
         params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
                 supportedPreviewSizes);
 
@@ -175,7 +175,7 @@
                     availableVideoSizes[i].width,
                     availableVideoSizes[i].height);
         }
-        ALOGV("Supported video sizes are: %s", supportedVideoSizes.string());
+        ALOGV("Supported video sizes are: %s", supportedVideoSizes.c_str());
         params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
                 supportedVideoSizes);
     }
@@ -315,7 +315,7 @@
                     fps);
 
             ALOGV("%s: Supported preview frame rates: %s",
-                    __FUNCTION__, supportedPreviewFrameRates.string());
+                    __FUNCTION__, supportedPreviewFrameRates.c_str());
         }
         params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
                 supportedPreviewFrameRates);
@@ -2832,7 +2832,7 @@
     String8 areasStr(areasCStr);
     ssize_t areaStart = areasStr.find("(", 0) + 1;
     while (areaStart != 0) {
-        const char* area = areasStr.string() + areaStart;
+        const char* area = areasStr.c_str() + areaStart;
         char *numEnd;
         int vals[NUM_FIELDS];
         for (size_t i = 0; i < NUM_FIELDS; i++) {
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 2d3597c..ff71e6b 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -31,6 +31,7 @@
 #include <gui/BufferItem.h>
 #include <gui/Surface.h>
 #include <media/hardware/HardwareAPI.h>
+#include <camera/StringUtils.h>
 
 #include "common/CameraDeviceBase.h"
 #include "api1/Camera2Client.h"
@@ -198,7 +199,7 @@
         res = device->createStream(mPreviewWindow,
                 params.previewWidth, params.previewHeight,
                 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
-                CAMERA_STREAM_ROTATION_0, &mPreviewStreamId, String8(),
+                CAMERA_STREAM_ROTATION_0, &mPreviewStreamId, std::string(),
                 std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
@@ -385,7 +386,7 @@
                 params.videoWidth, params.videoHeight,
                 params.videoFormat, params.videoDataSpace,
                 CAMERA_STREAM_ROTATION_0, &mRecordingStreamId,
-                String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+                std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for recording: "
                     "%s (%d)", __FUNCTION__, mId,
@@ -585,21 +586,21 @@
 }
 
 status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
-    String8 result;
+    std::string result;
 
-    result.append("  Current requests:\n");
+    result += "  Current requests:\n";
     if (mPreviewRequest.entryCount() != 0) {
-        result.append("    Preview request:\n");
-        write(fd, result.string(), result.size());
+        result += "    Preview request:\n";
+        write(fd, result.c_str(), result.size());
         mPreviewRequest.dump(fd, 2, 6);
         result.clear();
     } else {
-        result.append("    Preview request: undefined\n");
+        result += "    Preview request: undefined\n";
     }
 
     if (mRecordingRequest.entryCount() != 0) {
         result = "    Recording request:\n";
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         mRecordingRequest.dump(fd, 2, 6);
         result.clear();
     } else {
@@ -609,11 +610,11 @@
     const char* streamTypeString[] = {
         "none", "preview", "record"
     };
-    result.append(String8::format("   Active request: %s (paused: %s)\n",
-                                  streamTypeString[mActiveRequest],
-                                  mPaused ? "yes" : "no"));
+    result += fmt::sprintf("   Active request: %s (paused: %s\n",
+            streamTypeString[mActiveRequest],
+            mPaused ? "yes" : "no");
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     return OK;
 }
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 1321e6b..d6c2415 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -30,6 +30,7 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <gui/Surface.h>
+#include <camera/StringUtils.h>
 
 #include "common/CameraDeviceBase.h"
 #include "api1/Camera2Client.h"
@@ -255,13 +256,13 @@
         BufferQueue::createBufferQueue(&producer, &consumer);
         mProducer = new RingBufferConsumer(consumer, GRALLOC_USAGE_HW_CAMERA_ZSL,
             mBufferQueueDepth);
-        mProducer->setName(String8("Camera2-ZslRingBufferConsumer"));
+        mProducer->setName("Camera2-ZslRingBufferConsumer");
         sp<Surface> outSurface = new Surface(producer);
 
         res = device->createStream(outSurface, params.fastInfo.usedZslSize.width,
             params.fastInfo.usedZslSize.height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
             HAL_DATASPACE_UNKNOWN, CAMERA_STREAM_ROTATION_0, &mZslStreamId,
-            String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+            std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create ZSL stream: "
                     "%s (%d)", __FUNCTION__, client->getCameraId(),
@@ -680,12 +681,12 @@
 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
     Mutex::Autolock l(mInputMutex);
     if (!mLatestCapturedRequest.isEmpty()) {
-        String8 result("    Latest ZSL capture request:\n");
-        write(fd, result.string(), result.size());
+        std::string result = "    Latest ZSL capture request:\n";
+        write(fd, result.c_str(), result.size());
         mLatestCapturedRequest.dump(fd, 2, 6);
     } else {
-        String8 result("    Latest ZSL capture request: none yet\n");
-        write(fd, result.string(), result.size());
+        std::string result = "    Latest ZSL capture request: none yet\n";
+        write(fd, result.c_str(), result.size());
     }
     dumpZslQueue(fd);
 }
@@ -706,12 +707,12 @@
 }
 
 void ZslProcessor::dumpZslQueue(int fd) const {
-    String8 header("ZSL queue contents:");
-    String8 indent("    ");
-    ALOGV("%s", header.string());
+    std::string header = "ZSL queue contents:";
+    std::string indent = "    ";
+    ALOGV("%s", header.c_str());
     if (fd != -1) {
         header = indent + header + "\n";
-        write(fd, header.string(), header.size());
+        write(fd, header.c_str(), header.size());
     }
     for (size_t i = 0; i < mZslQueue.size(); i++) {
         const ZslPair &queueEntry = mZslQueue[i];
@@ -725,13 +726,13 @@
             entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
             if (entry.count > 0) frameAeState = entry.data.u8[0];
         }
-        String8 result =
-                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
+        std::string result =
+                fmt::sprintf("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
                         bufferTimestamp, frameTimestamp, frameAeState);
-        ALOGV("%s", result.string());
+        ALOGV("%s", result.c_str());
         if (fd != -1) {
             result = indent + result + "\n";
-            write(fd, result.string(), result.size());
+            write(fd, result.c_str(), result.size());
         }
 
     }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 38c615d..c60f327 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -26,6 +26,7 @@
 #include <gui/Surface.h>
 #include <camera/camera2/CaptureRequest.h>
 #include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
 
 #include "common/CameraDeviceBase.h"
 #include "device3/Camera3Device.h"
@@ -42,12 +43,12 @@
 
 #define STATUS_ERROR(errorCode, errorString) \
     binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
+            fmt::sprintf("%s:%d: %s", __FUNCTION__, __LINE__, errorString).c_str())
 
 #define STATUS_ERROR_FMT(errorCode, errorString, ...) \
     binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
-                    __VA_ARGS__))
+            fmt::sprintf("%s:%d: " errorString, __FUNCTION__, __LINE__, \
+                    __VA_ARGS__).c_str())
 
 namespace android {
 using namespace camera2;
@@ -57,10 +58,10 @@
 CameraDeviceClientBase::CameraDeviceClientBase(
         const sp<CameraService>& cameraService,
         const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
-        const String16& clientPackageName,
+        const std::string& clientPackageName,
         bool systemNativeClient,
-        const std::optional<String16>& clientFeatureId,
-        const String8& cameraId,
+        const std::optional<std::string>& clientFeatureId,
+        const std::string& cameraId,
         [[maybe_unused]] int api1CameraId,
         int cameraFacing,
         int sensorOrientation,
@@ -88,10 +89,10 @@
 CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
         const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
         std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-        const String16& clientPackageName,
+        const std::string& clientPackageName,
         bool systemNativeClient,
-        const std::optional<String16>& clientFeatureId,
-        const String8& cameraId,
+        const std::optional<std::string>& clientFeatureId,
+        const std::string& cameraId,
         int cameraFacing,
         int sensorOrientation,
         int clientPid,
@@ -109,16 +110,17 @@
     mOverrideForPerfClass(overrideForPerfClass) {
 
     ATRACE_CALL();
-    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
+    ALOGI("CameraDeviceClient %s: Opened", cameraId.c_str());
 }
 
 status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
-        const String8& monitorTags) {
+        const std::string& monitorTags) {
     return initializeImpl(manager, monitorTags);
 }
 
 template<typename TProviderPtr>
-status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
+status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr,
+        const std::string& monitorTags) {
     ATRACE_CALL();
     status_t res;
 
@@ -127,10 +129,9 @@
         return res;
     }
 
-    String8 threadName;
     mFrameProcessor = new FrameProcessorBase(mDevice);
-    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
-    res = mFrameProcessor->run(threadName.string());
+    std::string threadName = std::string("CDU-") + mCameraIdStr + "-FrameProc";
+    res = mFrameProcessor->run(threadName.c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start frame processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -188,13 +189,13 @@
     mProviderManager = providerPtr;
     // Cache physical camera ids corresponding to this device and also the high
     // resolution sensors in this device + physical camera ids
-    mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
+    mProviderManager->isLogicalCamera(mCameraIdStr, &mPhysicalCameraIds);
     if (supportsUltraHighResolutionCapture(mCameraIdStr)) {
-        mHighResolutionSensors.insert(mCameraIdStr.string());
+        mHighResolutionSensors.insert(mCameraIdStr);
     }
     for (auto &physicalId : mPhysicalCameraIds) {
-        if (supportsUltraHighResolutionCapture(String8(physicalId.c_str()))) {
-            mHighResolutionSensors.insert(physicalId.c_str());
+        if (supportsUltraHighResolutionCapture(physicalId)) {
+            mHighResolutionSensors.insert(physicalId);
         }
     }
     return OK;
@@ -222,7 +223,7 @@
     if (idx == NAME_NOT_FOUND) {
         ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
                 " we have not called createStream on",
-                __FUNCTION__, mCameraIdStr.string());
+                __FUNCTION__, mCameraIdStr.c_str());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Request targets Surface that is not part of current capture session");
     } else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
@@ -239,7 +240,7 @@
     (*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
 
     ALOGV("%s: Camera %s: Appending output stream %d surface %d to request",
-            __FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
+            __FUNCTION__, mCameraIdStr.c_str(), streamSurfaceId.streamId(),
             streamSurfaceId.surfaceId());
 
     if (currentStreamId != nullptr) {
@@ -282,7 +283,7 @@
 
     if (requests.empty()) {
         ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
-              __FUNCTION__, mCameraIdStr.string());
+              __FUNCTION__, mCameraIdStr.c_str());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
     }
 
@@ -295,19 +296,19 @@
         if (request.mIsReprocess) {
             if (!mInputStream.configured) {
                 ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
-                        mCameraIdStr.string());
+                        mCameraIdStr.c_str());
                 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "No input configured for camera %s but request is for reprocessing",
-                        mCameraIdStr.string());
+                        mCameraIdStr.c_str());
             } else if (streaming) {
                 ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
-                        mCameraIdStr.string());
+                        mCameraIdStr.c_str());
                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "Repeating reprocess requests not supported");
             } else if (request.mPhysicalCameraSettings.size() > 1) {
                 ALOGE("%s: Camera %s: reprocess requests not supported for "
                         "multiple physical cameras.", __FUNCTION__,
-                        mCameraIdStr.string());
+                        mCameraIdStr.c_str());
                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "Reprocess requests not supported for multiple cameras");
             }
@@ -315,23 +316,23 @@
 
         if (request.mPhysicalCameraSettings.empty()) {
             ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
-                    mCameraIdStr.string());
+                    mCameraIdStr.c_str());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                     "Request doesn't contain any settings");
         }
 
         //The first capture settings should always match the logical camera id
-        String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
+        const std::string &logicalId = request.mPhysicalCameraSettings.begin()->id;
         if (mDevice->getId() != logicalId) {
             ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
-                    mCameraIdStr.string());
+                    mCameraIdStr.c_str());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                     "Invalid camera request settings");
         }
 
         if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
             ALOGE("%s: Camera %s: Requests must have at least one surface target. "
-                    "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
+                    "Rejecting request.", __FUNCTION__, mCameraIdStr.c_str());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                     "Request has no output targets");
         }
@@ -357,9 +358,9 @@
 
                 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
                 if (index >= 0) {
-                    String8 requestedPhysicalId(
-                            mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
-                    requestedPhysicalIds.push_back(requestedPhysicalId.string());
+                    const std::string &requestedPhysicalId =
+                            mConfiguredOutputs.valueAt(index).getPhysicalCameraId();
+                    requestedPhysicalIds.push_back(requestedPhysicalId);
                     dynamicProfileBitmap |=
                             mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
                 } else {
@@ -375,7 +376,7 @@
                 if (index < 0) {
                     ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
                             " we have not called createStream on: stream %d",
-                            __FUNCTION__, mCameraIdStr.string(), streamId);
+                            __FUNCTION__, mCameraIdStr.c_str(), streamId);
                     return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                             "Request targets Surface that is not part of current capture session");
                 }
@@ -384,7 +385,7 @@
                 if ((size_t)surfaceIdx >= gbps.size()) {
                     ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
                             " we have not called createStream on: stream %d, surfaceIdx %d",
-                            __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
+                            __FUNCTION__, mCameraIdStr.c_str(), streamId, surfaceIdx);
                     return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                             "Request targets Surface has invalid surface index");
                 }
@@ -394,9 +395,9 @@
                     return res;
                 }
 
-                String8 requestedPhysicalId(
-                        mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
-                requestedPhysicalIds.push_back(requestedPhysicalId.string());
+                const std::string &requestedPhysicalId =
+                        mConfiguredOutputs.valueAt(index).getPhysicalCameraId();
+                requestedPhysicalIds.push_back(requestedPhysicalId);
                 dynamicProfileBitmap |=
                         mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
             }
@@ -418,7 +419,7 @@
                     } else {
                         ALOGE("%s: Camera %s: Tried to submit a request with a surfaces that"
                                 " reference an unsupported dynamic range profile combination"
-                                " 0x%" PRIx64 "!", __FUNCTION__, mCameraIdStr.string(),
+                                " 0x%" PRIx64 "!", __FUNCTION__, mCameraIdStr.c_str(),
                                 dynamicProfileBitmap);
                         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                                 "Request targets an unsupported dynamic range profile"
@@ -427,7 +428,7 @@
                 } else {
                     ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
                             " references unsupported dynamic range profile 0x%x!",
-                            __FUNCTION__, mCameraIdStr.string(), i);
+                            __FUNCTION__, mCameraIdStr.c_str(), i);
                     return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                             "Request targets 10-bit Surface with unsupported dynamic range"
                             " profile");
@@ -439,7 +440,7 @@
         for (const auto& it : request.mPhysicalCameraSettings) {
             if (it.settings.isEmpty()) {
                 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
-                        __FUNCTION__, mCameraIdStr.string());
+                        __FUNCTION__, mCameraIdStr.c_str());
                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "Request settings are empty");
             }
@@ -462,7 +463,7 @@
                 }
             }
 
-            String8 physicalId(it.id.c_str());
+            const std::string &physicalId = it.id;
             bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
                     mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
                     mSupportedPhysicalRequestKeys.end();
@@ -474,7 +475,7 @@
                         it.id);
                 if (found == requestedPhysicalIds.end()) {
                     ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
-                            __FUNCTION__, mCameraIdStr.string(), physicalId.string());
+                            __FUNCTION__, mCameraIdStr.c_str(), physicalId.c_str());
                     return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                             "Invalid physical camera id");
                 }
@@ -520,7 +521,7 @@
                 &(submitInfo->mRequestId), /*size*/1);
         loopCounter++; // loopCounter starts from 1
         ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
-                __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
+                __FUNCTION__, mCameraIdStr.c_str(), submitInfo->mRequestId,
                 loopCounter, requests.size());
 
         metadataRequestList.push_back(physicalSettingsList);
@@ -543,12 +544,12 @@
         err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
                 &(submitInfo->mLastFrameNumber));
         if (err != OK) {
-            String8 msg = String8::format(
+            std::string msg = fmt::sprintf(
                 "Camera %s:  Got error %s (%d) after trying to set streaming request",
-                mCameraIdStr.string(), strerror(-err), err);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
+                mCameraIdStr.c_str(), strerror(-err), err);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
             res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
-                    msg.string());
+                    msg.c_str());
         } else {
             Mutex::Autolock idLock(mStreamingRequestIdLock);
             mStreamingRequestId = submitInfo->mRequestId;
@@ -557,17 +558,17 @@
         err = mDevice->captureList(metadataRequestList, surfaceMapList,
                 &(submitInfo->mLastFrameNumber));
         if (err != OK) {
-            String8 msg = String8::format(
+            std::string msg = fmt::sprintf(
                 "Camera %s: Got error %s (%d) after trying to submit capture request",
-                mCameraIdStr.string(), strerror(-err), err);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
+                mCameraIdStr.c_str(), strerror(-err), err);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
             res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
-                    msg.string());
+                    msg.c_str());
         }
         ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
     }
 
-    ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
+    ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.c_str());
     return res;
 }
 
@@ -591,22 +592,22 @@
 
     Mutex::Autolock idLock(mStreamingRequestIdLock);
     if (mStreamingRequestId != requestId) {
-        String8 msg = String8::format("Camera %s: Canceling request ID %d doesn't match "
-                "current request ID %d", mCameraIdStr.string(), requestId, mStreamingRequestId);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Canceling request ID %d doesn't match "
+                "current request ID %d", mCameraIdStr.c_str(), requestId, mStreamingRequestId);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     err = mDevice->clearStreamingRequest(lastFrameNumber);
 
     if (err == OK) {
         ALOGV("%s: Camera %s: Successfully cleared streaming request",
-                __FUNCTION__, mCameraIdStr.string());
+                __FUNCTION__, mCameraIdStr.c_str());
         mStreamingRequestId = REQUEST_ID_NONE;
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error clearing streaming request: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+                mCameraIdStr.c_str(), strerror(-err), err);
     }
 
     return res;
@@ -631,9 +632,9 @@
     if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
 
     if (offlineStreamIds == nullptr) {
-        String8 msg = String8::format("Invalid offline stream ids");
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = "Invalid offline stream ids";
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     Mutex::Autolock icl(mBinderSerializationLock);
@@ -650,15 +651,15 @@
 
     status_t err = mDevice->configureStreams(sessionParams, operatingMode);
     if (err == BAD_VALUE) {
-        String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
-                mCameraIdStr.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Unsupported set of inputs/outputs provided",
+                mCameraIdStr.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     } else if (err != OK) {
-        String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Error configuring streams: %s (%d)",
+                mCameraIdStr.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     } else {
         offlineStreamIds->clear();
         mDevice->getOfflineStreamIds(offlineStreamIds);
@@ -667,10 +668,10 @@
         for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
             err = mCompositeStreamMap.valueAt(i)->configureStream();
             if (err != OK) {
-                String8 msg = String8::format("Camera %s: Error configuring composite "
-                        "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
-                ALOGE("%s: %s", __FUNCTION__, msg.string());
-                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+                std::string msg = fmt::sprintf("Camera %s: Error configuring composite "
+                        "streams: %s (%d)", mCameraIdStr.c_str(), strerror(-err), err);
+                ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
                 break;
             }
 
@@ -729,35 +730,36 @@
     }
 
     if (status == nullptr) {
-        String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf( "Camera %s: Invalid status!", mCameraIdStr.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     *status = false;
-    camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+    camera3::metadataGetter getMetadata = [this](const std::string &id,
+            bool /*overrideForPerfClass*/) {
           return mDevice->infoPhysical(id);};
-    ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
+    ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.c_str(),
             sessionConfiguration, mOverrideForPerfClass, getMetadata, status);
     switch (ret) {
         case OK:
             // Expected, do nothing.
             break;
         case INVALID_OPERATION: {
-                String8 msg = String8::format(
+                std::string msg = fmt::sprintf(
                         "Camera %s: Session configuration query not supported!",
-                        mCameraIdStr.string());
-                ALOGD("%s: %s", __FUNCTION__, msg.string());
-                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+                        mCameraIdStr.c_str());
+                ALOGD("%s: %s", __FUNCTION__, msg.c_str());
+                res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
             }
 
             break;
         default: {
-                String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
+                std::string msg = fmt::sprintf( "Camera %s: Error: %s (%d)", mCameraIdStr.c_str(),
                         strerror(-ret), ret);
-                ALOGE("%s: %s", __FUNCTION__, msg.string());
+                ALOGE("%s: %s", __FUNCTION__, msg.c_str());
                 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                        msg.string());
+                        msg.c_str());
             }
     }
 
@@ -809,10 +811,10 @@
         }
 
         if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
-            String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
-                    " stream created yet", mCameraIdStr.string(), streamId);
-            ALOGW("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no such"
+                    " stream created yet", mCameraIdStr.c_str(), streamId);
+            ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
     }
 
@@ -820,10 +822,10 @@
     status_t err = mDevice->deleteStream(streamId);
 
     if (err != OK) {
-        String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when deleting stream %d",
-                mCameraIdStr.string(), strerror(-err), err, streamId);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Unexpected error %s (%d) when deleting stream "
+                "%d", mCameraIdStr.c_str(), strerror(-err), err, streamId);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     } else {
         if (isInput) {
             mInputStream.configured = false;
@@ -843,11 +845,11 @@
                 status_t ret;
                 if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
                         != OK) {
-                    String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
-                            "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
-                            streamId);
-                    ALOGE("%s: %s", __FUNCTION__, msg.string());
-                    res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+                    std::string msg = fmt::sprintf("Camera %s: Unexpected error %s (%d) when "
+                            "deleting composite stream %d", mCameraIdStr.c_str(), strerror(-err),
+                            err, streamId);
+                    ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+                    res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
                 }
                 mCompositeStreamMap.removeItemsAt(compositeIndex);
             }
@@ -880,7 +882,7 @@
     size_t numBufferProducers = bufferProducers.size();
     bool deferredConsumer = outputConfiguration.isDeferred();
     bool isShared = outputConfiguration.isShared();
-    String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
+    const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
     bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
     bool isMultiResolution = outputConfiguration.isMultiResolution();
     int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
@@ -923,10 +925,11 @@
         sp<IBinder> binder = IInterface::asBinder(bufferProducer);
         ssize_t index = mStreamMap.indexOfKey(binder);
         if (index != NAME_NOT_FOUND) {
-            String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
-                    "(ID %zd)", mCameraIdStr.string(), index);
-            ALOGW("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+            std::string msg = std::string("Camera ") + mCameraIdStr
+                    + ": Surface already has a stream created for it (ID "
+                    + std::to_string(index) + ")";
+            ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.c_str());
         }
 
         sp<Surface> surface;
@@ -994,7 +997,7 @@
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
-                mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
+                mCameraIdStr.c_str(), streamInfo.width, streamInfo.height, streamInfo.format,
                 streamInfo.dataSpace, strerror(-err), err);
     } else {
         int i = 0;
@@ -1010,20 +1013,19 @@
 
         ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
                     " (%d x %d) with format 0x%x.",
-                  __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
+                  __FUNCTION__, mCameraIdStr.c_str(), streamId, streamInfo.width,
                   streamInfo.height, streamInfo.format);
 
         // Set transform flags to ensure preview to be rotated correctly.
         res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);
 
         // Fill in mHighResolutionCameraIdToStreamIdSet map
-        const String8 &cameraIdUsed =
+        const std::string &cameraIdUsed =
                 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
-        const char *cameraIdUsedCStr = cameraIdUsed.string();
         // Only needed for high resolution sensors
-        if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
+        if (mHighResolutionSensors.find(cameraIdUsed) !=
                 mHighResolutionSensors.end()) {
-            mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
+            mHighResolutionCameraIdToStreamIdSet[cameraIdUsed].insert(streamId);
         }
 
         *newStreamId = streamId;
@@ -1063,8 +1065,8 @@
     int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
     std::vector<sp<Surface>> noSurface;
     std::vector<int> surfaceIds;
-    String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
-    const String8 &cameraIdUsed =
+    const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
+    const std::string &cameraIdUsed =
             physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
     // Here, we override sensor pixel modes
     std::unordered_set<int32_t> overriddenSensorPixelModesUsed;
@@ -1093,7 +1095,7 @@
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
-                mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
+                mCameraIdStr.c_str(), width, height, format, dataSpace, strerror(-err), err);
     } else {
         // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
         // a separate list to track. Once the deferred surface is set, this id will be
@@ -1110,18 +1112,17 @@
 
         ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
                 " (%d x %d) stream with format 0x%x.",
-              __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
+              __FUNCTION__, mCameraIdStr.c_str(), streamId, width, height, format);
 
         // Set transform flags to ensure preview to be rotated correctly.
         res = setStreamTransformLocked(streamId, outputConfiguration.getMirrorMode());
 
         *newStreamId = streamId;
         // Fill in mHighResolutionCameraIdToStreamIdSet
-        const char *cameraIdUsedCStr = cameraIdUsed.string();
         // Only needed for high resolution sensors
-        if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
+        if (mHighResolutionSensors.find(cameraIdUsed) !=
                 mHighResolutionSensors.end()) {
-            mHighResolutionCameraIdToStreamIdSet[cameraIdUsed.string()].insert(streamId);
+            mHighResolutionCameraIdToStreamIdSet[cameraIdUsed].insert(streamId);
         }
     }
     return res;
@@ -1145,10 +1146,10 @@
 
     err = mDevice->setStreamTransform(streamId, transform);
     if (err != OK) {
-        String8 msg = String8::format("Failed to set stream transform (stream id %d)",
+        std::string msg = fmt::sprintf("Failed to set stream transform (stream id %d)",
                 streamId);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
 
     return res;
@@ -1173,10 +1174,10 @@
     }
 
     if (mInputStream.configured) {
-        String8 msg = String8::format("Camera %s: Already has an input stream "
-                "configured (ID %d)", mCameraIdStr.string(), mInputStream.id);
-        ALOGE("%s: %s", __FUNCTION__, msg.string() );
-        return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Already has an input stream "
+                "configured (ID %d)", mCameraIdStr.c_str(), mInputStream.id);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str() );
+        return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.c_str());
     }
 
     int streamId = -1;
@@ -1189,12 +1190,12 @@
         mInputStream.id = streamId;
 
         ALOGV("%s: Camera %s: Successfully created a new input stream ID %d",
-                __FUNCTION__, mCameraIdStr.string(), streamId);
+                __FUNCTION__, mCameraIdStr.c_str(), streamId);
 
         *newStreamId = streamId;
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.string(),
+                "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.c_str(),
                 strerror(-err), err);
     }
 
@@ -1219,9 +1220,9 @@
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error getting input Surface: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+                mCameraIdStr.c_str(), strerror(-err), err);
     } else {
-        inputSurface->name = String16("CameraInput");
+        inputSurface->name = toString16("CameraInput");
         inputSurface->graphicBufferProducer = producer;
     }
     return res;
@@ -1242,7 +1243,7 @@
 
     const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
             outputConfiguration.getGraphicBufferProducers();
-    String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
+    const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
 
     auto producerCount = bufferProducers.size();
     if (producerCount == 0) {
@@ -1329,12 +1330,12 @@
             case -EBUSY:
                 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                         "Camera %s: Error updating stream: %s (%d)",
-                        mCameraIdStr.string(), strerror(ret), ret);
+                        mCameraIdStr.c_str(), strerror(ret), ret);
                 break;
             default:
                 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                         "Camera %s: Error updating stream: %s (%d)",
-                        mCameraIdStr.string(), strerror(ret), ret);
+                        mCameraIdStr.c_str(), strerror(ret), ret);
                 break;
         }
     } else {
@@ -1350,7 +1351,7 @@
         mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
 
         ALOGV("%s: Camera %s: Successful stream ID %d update",
-                  __FUNCTION__, mCameraIdStr.string(), streamId);
+                  __FUNCTION__, mCameraIdStr.c_str(), streamId);
     }
 
     return res;
@@ -1385,12 +1386,12 @@
     } else if (err == BAD_VALUE) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
-                mCameraIdStr.string(), templateId, strerror(-err), err);
+                mCameraIdStr.c_str(), templateId, strerror(-err), err);
 
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error creating default request for template %d: %s (%d)",
-                mCameraIdStr.string(), templateId, strerror(-err), err);
+                mCameraIdStr.c_str(), templateId, strerror(-err), err);
     }
     return res;
 }
@@ -1437,17 +1438,17 @@
     // FIXME: Also need check repeating burst.
     Mutex::Autolock idLock(mStreamingRequestIdLock);
     if (mStreamingRequestId != REQUEST_ID_NONE) {
-        String8 msg = String8::format(
+        std::string msg = fmt::sprintf(
             "Camera %s: Try to waitUntilIdle when there are active streaming requests",
-            mCameraIdStr.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+            mCameraIdStr.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
     status_t err = mDevice->waitUntilDrained();
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error waiting to drain: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+                mCameraIdStr.c_str(), strerror(-err), err);
     }
     ALOGV("%s Done", __FUNCTION__);
     return res;
@@ -1473,7 +1474,8 @@
     status_t err = mDevice->flush(lastFrameNumber);
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
+                "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.c_str(), strerror(-err),
+                err);
     }
     return res;
 }
@@ -1497,10 +1499,10 @@
     }
 
     if (index == NAME_NOT_FOUND) {
-        String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
-              "with that ID exists", mCameraIdStr.string(), streamId);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+              "with that ID exists", mCameraIdStr.c_str(), streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     // Also returns BAD_VALUE if stream ID was not valid, or stream already
@@ -1509,10 +1511,10 @@
     if (err == BAD_VALUE) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Stream %d has already been used, and cannot be prepared",
-                mCameraIdStr.string(), streamId);
+                mCameraIdStr.c_str(), streamId);
     } else if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+                "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
                 strerror(-err), err);
     }
     return res;
@@ -1537,17 +1539,17 @@
     }
 
     if (index == NAME_NOT_FOUND) {
-        String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
-              "with that ID exists", mCameraIdStr.string(), streamId);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+              "with that ID exists", mCameraIdStr.c_str(), streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     if (maxCount <= 0) {
-        String8 msg = String8::format("Camera %s: maxCount (%d) must be greater than 0",
-                mCameraIdStr.string(), maxCount);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: maxCount (%d) must be greater than 0",
+                mCameraIdStr.c_str(), maxCount);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     // Also returns BAD_VALUE if stream ID was not valid, or stream already
@@ -1556,10 +1558,10 @@
     if (err == BAD_VALUE) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Stream %d has already been used, and cannot be prepared",
-                mCameraIdStr.string(), streamId);
+                mCameraIdStr.c_str(), streamId);
     } else if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+                "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
                 strerror(-err), err);
     }
 
@@ -1585,10 +1587,10 @@
     }
 
     if (index == NAME_NOT_FOUND) {
-        String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
-              "with that ID exists", mCameraIdStr.string(), streamId);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+              "with that ID exists", mCameraIdStr.c_str(), streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
@@ -1597,10 +1599,10 @@
     if (err == BAD_VALUE) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Stream %d is still in use, cannot be torn down",
-                mCameraIdStr.string(), streamId);
+                mCameraIdStr.c_str(), streamId);
     } else if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+                "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
                 strerror(-err), err);
     }
 
@@ -1618,7 +1620,7 @@
 
     const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
             outputConfiguration.getGraphicBufferProducers();
-    String8 physicalId(outputConfiguration.getPhysicalCameraId());
+    const std::string &physicalId = outputConfiguration.getPhysicalCameraId();
 
     if (bufferProducers.size() == 0) {
         ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
@@ -1643,17 +1645,17 @@
 
     }
     if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
-        String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
-                "(ID %d)", mCameraIdStr.string(), streamId);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: deferred surface is set to a unknown stream"
+                "(ID %d)", mCameraIdStr.c_str(), streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     if (mStreamInfoMap[streamId].finalized) {
-        String8 msg = String8::format("Camera %s: finalizeOutputConfigurations has been called"
-                " on stream ID %d", mCameraIdStr.string(), streamId);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: finalizeOutputConfigurations has been called"
+                " on stream ID %d", mCameraIdStr.c_str(), streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     if (!mDevice.get()) {
@@ -1673,7 +1675,7 @@
         ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
         if (index != NAME_NOT_FOUND) {
             ALOGV("Camera %s: Surface already has a stream created "
-                    " for it (ID %zd)", mCameraIdStr.string(), index);
+                    " for it (ID %zd)", mCameraIdStr.c_str(), index);
             continue;
         }
 
@@ -1716,11 +1718,11 @@
     } else if (err == NO_INIT) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Deferred surface is invalid: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+                mCameraIdStr.c_str(), strerror(-err), err);
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %s: Error setting output stream deferred surface: %s (%d)",
-                mCameraIdStr.string(), strerror(-err), err);
+                mCameraIdStr.c_str(), strerror(-err), err);
     }
 
     return res;
@@ -1732,10 +1734,10 @@
     if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
 
     if (!isValidAudioRestriction(mode)) {
-        String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
-                mCameraIdStr.string(), mode);
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: invalid audio restriction mode %d",
+                mCameraIdStr.c_str(), mode);
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     Mutex::Autolock icl(mBinderSerializationLock);
@@ -1814,15 +1816,15 @@
     }
 
     if (offlineOutputIds.empty()) {
-        String8 msg = String8::format("Offline surfaces must not be empty");
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = "Offline surfaces must not be empty";
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     if (session == nullptr) {
-        String8 msg = String8::format("Invalid offline session");
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = "Invalid offline session";
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     std::vector<int32_t> offlineStreamIds;
@@ -1831,17 +1833,17 @@
     for (const auto& streamId : offlineOutputIds) {
         ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
         if (index == NAME_NOT_FOUND) {
-            String8 msg = String8::format("Offline surface with id: %d is not registered",
+            std::string msg = fmt::sprintf("Offline surface with id: %d is not registered",
                     streamId);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
 
         if (!mStreamInfoMap[streamId].supportsOffline) {
-            String8 msg = String8::format("Offline surface with id: %d doesn't support "
+            std::string msg = fmt::sprintf("Offline surface with id: %d doesn't support "
                     "offline mode", streamId);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
 
         Mutex::Autolock l(mCompositeLock);
@@ -1878,7 +1880,7 @@
     if (ret != OK) {
         return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                 "Camera %s: Error switching to offline mode: %s (%d)",
-                mCameraIdStr.string(), strerror(ret), ret);
+                mCameraIdStr.c_str(), strerror(ret), ret);
     }
 
     sp<CameraOfflineSessionClient> offlineClient;
@@ -1903,7 +1905,7 @@
     } else {
         // In case we failed to register the offline client, ensure that it still initialized
         // so that all failing requests can return back correctly once the object is released.
-        offlineClient->initialize(nullptr /*cameraProviderManager*/, String8()/*monitorTags*/);
+        offlineClient->initialize(nullptr /*cameraProviderManager*/, std::string()/*monitorTags*/);
 
         switch(ret) {
             case BAD_VALUE:
@@ -1930,7 +1932,7 @@
 
 status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
     dprintf(fd, "  CameraDeviceClient[%s] (%p) dump:\n",
-            mCameraIdStr.string(),
+            mCameraIdStr.c_str(),
             (getRemoteCallback() != NULL ?
                     IInterface::asBinder(getRemoteCallback()).get() : NULL) );
     dprintf(fd, "    Current client UID %u\n", mClientUid);
@@ -1963,7 +1965,7 @@
     return dumpDevice(fd, args);
 }
 
-status_t CameraDeviceClient::startWatchingTags(const String8 &tags, int out) {
+status_t CameraDeviceClient::startWatchingTags(const std::string &tags, int out) {
     sp<CameraDeviceBase> device = mDevice;
     if (!device) {
         dprintf(out, "  Device is detached.");
@@ -2087,16 +2089,16 @@
     if (mDevice == 0) return;
 
     nsecs_t startTime = systemTime();
-    ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
+    ALOGV("Camera %s: Stopping processors", mCameraIdStr.c_str());
 
     if (mFrameProcessor.get() != nullptr) {
         mFrameProcessor->removeListener(
                 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
                 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID, /*listener*/this);
         mFrameProcessor->requestExit();
-        ALOGV("Camera %s: Waiting for threads", mCameraIdStr.string());
+        ALOGV("Camera %s: Waiting for threads", mCameraIdStr.c_str());
         mFrameProcessor->join();
-        ALOGV("Camera %s: Disconnecting device", mCameraIdStr.string());
+        ALOGV("Camera %s: Disconnecting device", mCameraIdStr.c_str());
     }
 
     // WORKAROUND: HAL refuses to disconnect while there's streams in flight
@@ -2202,7 +2204,7 @@
     entry = metadata.find(ANDROID_LED_TRANSMIT);
     if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
         String16 permissionString =
-            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
+            toString16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
         if (!checkCallingPermission(permissionString)) {
             const int uid = CameraThreadState::getCallingUid();
             ALOGE("Permission Denial: "
@@ -2228,7 +2230,7 @@
 
     if (tempId == nullptr) {
         ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                "Camera %s: Invalid template argument", mCameraIdStr.string());
+                "Camera %s: Invalid template argument", mCameraIdStr.c_str());
         return ret;
     }
     switch(templateId) {
@@ -2253,21 +2255,21 @@
         default:
             ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
                     "Camera %s: Template ID %d is invalid or not supported",
-                    mCameraIdStr.string(), templateId);
+                    mCameraIdStr.c_str(), templateId);
             return ret;
     }
 
     return ret;
 }
 
-const CameraMetadata &CameraDeviceClient::getStaticInfo(const String8 &cameraId) {
+const CameraMetadata &CameraDeviceClient::getStaticInfo(const std::string &cameraId) {
     if (mDevice->getId() == cameraId) {
         return mDevice->info();
     }
     return mDevice->infoPhysical(cameraId);
 }
 
-bool CameraDeviceClient::supportsUltraHighResolutionCapture(const String8 &cameraId) {
+bool CameraDeviceClient::supportsUltraHighResolutionCapture(const std::string &cameraId) {
     const CameraMetadata &deviceInfo = getStaticInfo(cameraId);
     return SessionConfigurationUtils::supportsUltraHighResolutionCapture(deviceInfo);
 }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 1533cf5..45c904a 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,10 +50,10 @@
 protected:
     CameraDeviceClientBase(const sp<CameraService>& cameraService,
             const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
-            const String16& clientPackageName,
+            const std::string& clientPackageName,
             bool systemNativeClient,
-            const std::optional<String16>& clientFeatureId,
-            const String8& cameraId,
+            const std::optional<std::string>& clientFeatureId,
+            const std::string& cameraId,
             int api1CameraId,
             int cameraFacing,
             int sensorOrientation,
@@ -181,10 +181,10 @@
     CameraDeviceClient(const sp<CameraService>& cameraService,
             const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
             std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-            const String16& clientPackageName,
+            const std::string& clientPackageName,
             bool clientPackageOverride,
-            const std::optional<String16>& clientFeatureId,
-            const String8& cameraId,
+            const std::optional<std::string>& clientFeatureId,
+            const std::string& cameraId,
             int cameraFacing,
             int sensorOrientation,
             int clientPid,
@@ -195,7 +195,7 @@
     virtual ~CameraDeviceClient();
 
     virtual status_t      initialize(sp<CameraProviderManager> manager,
-            const String8& monitorTags) override;
+            const std::string& monitorTags) override;
 
     virtual status_t      setRotateAndCropOverride(uint8_t rotateAndCrop) override;
 
@@ -211,7 +211,7 @@
 
     virtual status_t      dumpClient(int fd, const Vector<String16>& args);
 
-    virtual status_t      startWatchingTags(const String8 &tags, int out);
+    virtual status_t      startWatchingTags(const std::string &tags, int out);
     virtual status_t      stopWatchingTags(int out);
     virtual status_t      dumpWatchedEventsToVector(std::vector<std::string> &out);
 
@@ -245,12 +245,12 @@
     // Calculate the ANativeWindow transform from android.sensor.orientation
     status_t              getRotationTransformLocked(int mirrorMode, /*out*/int32_t* transform);
 
-    bool supportsUltraHighResolutionCapture(const String8 &cameraId);
+    bool supportsUltraHighResolutionCapture(const std::string &cameraId);
 
     bool isSensorPixelModeConsistent(const std::list<int> &streamIdList,
             const CameraMetadata &settings);
 
-    const CameraMetadata &getStaticInfo(const String8 &cameraId);
+    const CameraMetadata &getStaticInfo(const std::string &cameraId);
 
 private:
     // StreamSurfaceId encapsulates streamId + surfaceId for a particular surface.
@@ -289,7 +289,7 @@
     std::vector<int32_t> mSupportedPhysicalRequestKeys;
 
     template<typename TProviderPtr>
-    status_t      initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+    status_t      initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
 
     /** Utility members */
     binder::Status checkPidStatus(const char* checkLocation);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 86a0ebc..99bdb0e 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -21,12 +21,13 @@
 #include "CameraOfflineSessionClient.h"
 #include "utils/CameraThreadState.h"
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 
 namespace android {
 
 using binder::Status;
 
-status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const String8&) {
+status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const std::string&) {
     ATRACE_CALL();
 
     if (mFrameProcessor.get() != nullptr) {
@@ -42,14 +43,13 @@
 
     if (mOfflineSession.get() == nullptr) {
         ALOGE("%s: Camera %s: No valid offline session",
-                __FUNCTION__, mCameraIdStr.string());
+                __FUNCTION__, mCameraIdStr.c_str());
         return NO_INIT;
     }
 
-    String8 threadName;
     mFrameProcessor = new camera2::FrameProcessorBase(mOfflineSession);
-    threadName = String8::format("Offline-%s-FrameProc", mCameraIdStr.string());
-    res = mFrameProcessor->run(threadName.string());
+    std::string threadName = fmt::sprintf("Offline-%s-FrameProc", mCameraIdStr.c_str());
+    res = mFrameProcessor->run(threadName.c_str());
     if (res != OK) {
         ALOGE("%s: Unable to start frame processor thread: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -65,7 +65,7 @@
     res = mOfflineSession->initialize(weakThis);
     if (res != OK) {
         ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
-                __FUNCTION__, mCameraIdStr.string(), strerror(-res), res);
+                __FUNCTION__, mCameraIdStr.c_str(), strerror(-res), res);
         return res;
     }
 
@@ -119,14 +119,14 @@
 }
 
 status_t CameraOfflineSessionClient::dumpClient(int fd, const Vector<String16>& args) {
-    String8 result;
+    std::string result;
 
     result = "  Offline session dump:\n";
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     if (mOfflineSession.get() == nullptr) {
         result = "  *** Offline session is detached\n";
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         return NO_ERROR;
     }
 
@@ -134,15 +134,15 @@
 
     auto res = mOfflineSession->dump(fd);
     if (res != OK) {
-        result = String8::format("   Error dumping offline session: %s (%d)",
+        result = fmt::sprintf("   Error dumping offline session: %s (%d)",
                 strerror(-res), res);
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
 
     return OK;
 }
 
-status_t CameraOfflineSessionClient::startWatchingTags(const String8 &tags, int outFd) {
+status_t CameraOfflineSessionClient::startWatchingTags(const std::string &tags, int outFd) {
     return BasicClient::startWatchingTags(tags, outFd);
 }
 
@@ -171,7 +171,7 @@
     mDisconnected = true;
 
     sCameraService->removeByClient(this);
-    sCameraService->logDisconnectedOffline(mCameraIdStr, mClientPid, String8(mClientPackageName));
+    sCameraService->logDisconnectedOffline(mCameraIdStr, mClientPid, mClientPackageName);
 
     sp<IBinder> remote = getRemote();
     if (remote != nullptr) {
@@ -186,7 +186,7 @@
 
     finishCameraOps();
     ALOGI("%s: Disconnected client for offline camera %s for PID %d", __FUNCTION__,
-            mCameraIdStr.string(), mClientPid);
+            mCameraIdStr.c_str(), mClientPid);
 
     // client shouldn't be able to call into us anymore
     mClientPid = 0;
@@ -231,7 +231,7 @@
     ATRACE_CALL();
     {
         ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
-              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+              __FUNCTION__, mClientPackageName.c_str(), mClientUid);
     }
 
     if (mAppOpsManager != nullptr) {
@@ -240,14 +240,14 @@
         int32_t res;
         // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
         mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
-                mClientPackageName, mOpsCallback);
+                toString16(mClientPackageName), mOpsCallback);
         // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
         res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
-                mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+                mClientUid, toString16(mClientPackageName), /*startIfModeDefault*/ false);
 
         if (res == AppOpsManager::MODE_ERRORED) {
             ALOGI("Offline Camera %s: Access for \"%s\" has been revoked",
-                    mCameraIdStr.string(), String8(mClientPackageName).string());
+                    mCameraIdStr.c_str(), mClientPackageName.c_str());
             return PERMISSION_DENIED;
         }
 
@@ -255,7 +255,7 @@
         // return MODE_IGNORED. Do not treat such case as error.
         if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
             ALOGI("Offline Camera %s: Access for \"%s\" has been restricted",
-                    mCameraIdStr.string(), String8(mClientPackageName).string());
+                    mCameraIdStr.c_str(), mClientPackageName.c_str());
             // Return the same error as for device policy manager rejection
             return -EACCES;
         }
@@ -278,7 +278,7 @@
         if (mAppOpsManager != nullptr) {
         // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
             mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
-                    mClientPackageName);
+                    toString16(mClientPackageName));
             mOpsActive = false;
         }
     }
@@ -368,10 +368,10 @@
                 CaptureResultExtras());
 }
 
-status_t CameraOfflineSessionClient::injectCamera(const String8& injectedCamId,
+status_t CameraOfflineSessionClient::injectCamera(const std::string& injectedCamId,
             sp<CameraProviderManager> manager) {
     ALOGV("%s: This client doesn't support the injection camera. injectedCamId: %s providerPtr: %p",
-            __FUNCTION__, injectedCamId.string(), manager.get());
+            __FUNCTION__, injectedCamId.c_str(), manager.get());
 
     return OK;
 }
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index ad763f9..70bad03 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -47,9 +47,9 @@
             sp<CameraOfflineSessionBase> session,
             const KeyedVector<sp<IBinder>, sp<CompositeStream>>& offlineCompositeStreamMap,
             const sp<ICameraDeviceCallbacks>& remoteCallback,
-            const String16& clientPackageName,
-            const std::optional<String16>& clientFeatureId,
-            const String8& cameraIdStr, int cameraFacing, int sensorOrientation,
+            const std::string& clientPackageName,
+            const std::optional<std::string>& clientFeatureId,
+            const std::string& cameraIdStr, int cameraFacing, int sensorOrientation,
             int clientPid, uid_t clientUid, int servicePid) :
             CameraService::BasicClient(
                     cameraService,
@@ -73,12 +73,12 @@
 
     status_t dumpClient(int /*fd*/, const Vector<String16>& /*args*/) override;
 
-    status_t startWatchingTags(const String8 &tags, int outFd) override;
+    status_t startWatchingTags(const std::string &tags, int outFd) override;
     status_t stopWatchingTags(int outFd) override;
     status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
 
     status_t initialize(sp<CameraProviderManager> /*manager*/,
-            const String8& /*monitorTags*/) override;
+            const std::string& /*monitorTags*/) override;
 
     status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
 
@@ -117,7 +117,7 @@
     void notifyPrepared(int streamId) override;
     void notifyRequestQueueEmpty() override;
     void notifyRepeatingRequestError(long lastFrameNumber) override;
-    status_t injectCamera(const String8& injectedCamId,
+    status_t injectCamera(const std::string& injectedCamId,
             sp<CameraProviderManager> manager) override;
     status_t stopInjection() override;
 
diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp
index 4ed1c28..8f53458 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/CompositeStream.cpp
@@ -46,7 +46,7 @@
 
 status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-        camera_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int * id, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         std::vector<int> * surfaceIds,
         int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
index a551d11..1b7fc6e 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.h
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -43,7 +43,7 @@
 
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds,
             int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
@@ -57,7 +57,7 @@
     // Create and register all internal camera streams.
     virtual status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds,
             int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
index 737c2b5..1bd0b85 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -20,6 +20,7 @@
 
 #include <aidl/android/hardware/camera/device/CameraBlob.h>
 #include <aidl/android/hardware/camera/device/CameraBlobId.h>
+#include <camera/StringUtils.h>
 
 #include "api1/client2/JpegProcessor.h"
 #include "common/CameraProviderManager.h"
@@ -495,17 +496,17 @@
     status_t err;
     int format;
     if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
-        String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+        std::string msg = fmt::sprintf("Failed to query Surface format: %s (%d)", strerror(-err),
                 err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return false;
     }
 
     int dataspace;
     if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
-        String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+        std::string msg = fmt::sprintf("Failed to query Surface dataspace: %s (%d)", strerror(-err),
                 err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return false;
     }
 
@@ -578,7 +579,7 @@
 
 status_t DepthCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
         bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
-        camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         std::vector<int> *surfaceIds,
         int /*streamSetId*/, bool /*isShared*/, int32_t /*colorSpace*/,
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h
index fbe99dd..f797f9c 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.h
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h
@@ -50,7 +50,7 @@
     // CompositeStream overrides
     status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds,
             int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 694aff3..68e9ad4 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -29,6 +29,7 @@
 #include <gui/Surface.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 
 #include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
@@ -98,17 +99,17 @@
     status_t err;
     int format;
     if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
-        String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+        std::string msg = fmt::sprintf("Failed to query Surface format: %s (%d)", strerror(-err),
                 err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return false;
     }
 
     int dataspace;
     if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
-        String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+        std::string msg = fmt::sprintf("Failed to query Surface dataspace: %s (%d)", strerror(-err),
                 err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return false;
     }
 
@@ -117,7 +118,7 @@
 
 status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
         bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
-        camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         std::vector<int> *surfaceIds,
         int /*streamSetId*/, bool /*isShared*/, int32_t colorSpace,
@@ -451,15 +452,27 @@
         newFormat->setString(KEY_MIME, mimeHeic);
         newFormat->setInt32(KEY_WIDTH, mOutputWidth);
         newFormat->setInt32(KEY_HEIGHT, mOutputHeight);
-        if (mUseGrid) {
+    }
+
+    if (mUseGrid || mUseHeic) {
+        int32_t gridRows, gridCols, tileWidth, tileHeight;
+        if (newFormat->findInt32(KEY_GRID_ROWS, &gridRows) &&
+                newFormat->findInt32(KEY_GRID_COLUMNS, &gridCols) &&
+                newFormat->findInt32(KEY_TILE_WIDTH, &tileWidth) &&
+                newFormat->findInt32(KEY_TILE_HEIGHT, &tileHeight)) {
+            mGridWidth = tileWidth;
+            mGridHeight = tileHeight;
+            mGridRows = gridRows;
+            mGridCols = gridCols;
+        } else {
             newFormat->setInt32(KEY_TILE_WIDTH, mGridWidth);
             newFormat->setInt32(KEY_TILE_HEIGHT, mGridHeight);
             newFormat->setInt32(KEY_GRID_ROWS, mGridRows);
             newFormat->setInt32(KEY_GRID_COLUMNS, mGridCols);
-            int32_t left, top, right, bottom;
-            if (newFormat->findRect("crop", &left, &top, &right, &bottom)) {
-                newFormat->setRect("crop", 0, 0, mOutputWidth - 1, mOutputHeight - 1);
-            }
+        }
+        int32_t left, top, right, bottom;
+        if (newFormat->findRect("crop", &left, &top, &right, &bottom)) {
+            newFormat->setRect("crop", 0, 0, mOutputWidth - 1, mOutputHeight - 1);
         }
     }
     newFormat->setInt32(KEY_IS_DEFAULT, 1 /*isPrimary*/);
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 602a247..b539cdd 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -45,7 +45,7 @@
 
     status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared, int32_t colorSpace,
             int64_t dynamicProfile, int64_t streamUseCase, bool useReadoutTimestamp) override;
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
index 6588470..988446b 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
@@ -548,7 +548,7 @@
 
 status_t JpegRCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
         bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
-        camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         std::vector<int> *surfaceIds,
         int /*streamSetId*/, bool /*isShared*/, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.h b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
index 3dfed30..016d57c 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.h
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
@@ -47,7 +47,7 @@
     // CompositeStream overrides
     status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds,
             int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6e10f30..a54ba9b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -28,6 +28,7 @@
 #include <gui/Surface.h>
 
 #include <camera/CameraSessionStats.h>
+#include <camera/StringUtils.h>
 
 #include "common/Camera2ClientBase.h"
 
@@ -49,10 +50,10 @@
         const sp<CameraService>& cameraService,
         const sp<TCamCallbacks>& remoteCallback,
         std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-        const String16& clientPackageName,
+        const std::string& clientPackageName,
         bool systemNativeClient,
-        const std::optional<String16>& clientFeatureId,
-        const String8& cameraId,
+        const std::optional<std::string>& clientFeatureId,
+        const std::string& cameraId,
         int api1CameraId,
         int cameraFacing,
         int sensorOrientation,
@@ -69,8 +70,8 @@
         mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
         mDeviceActive(false), mApi1CameraId(api1CameraId)
 {
-    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
-            String8(clientPackageName).string(), clientPid, clientUid);
+    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.c_str(),
+            clientPackageName.c_str(), clientPid, clientUid);
 
     mInitialClientPid = clientPid;
     mOverrideForPerfClass = overrideForPerfClass;
@@ -91,21 +92,21 @@
 
 template <typename TClientBase>
 status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
-        const String8& monitorTags) {
+        const std::string& monitorTags) {
     return initializeImpl(manager, monitorTags);
 }
 
 template <typename TClientBase>
 template <typename TProviderPtr>
 status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
-        const String8& monitorTags) {
+        const std::string& monitorTags) {
     ATRACE_CALL();
     ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
-          TClientBase::mCameraIdStr.string());
+          TClientBase::mCameraIdStr.c_str());
     status_t res;
 
     IPCTransport providerTransport = IPCTransport::INVALID;
-    res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr.string(),
+    res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr,
             &providerTransport);
     if (res != OK) {
         return res;
@@ -125,19 +126,19 @@
              break;
         default:
             ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
-                    TClientBase::mCameraIdStr.string());
+                    TClientBase::mCameraIdStr.c_str());
             return NO_INIT;
     }
     if (mDevice == NULL) {
         ALOGE("%s: Camera %s: No device connected",
-                __FUNCTION__, TClientBase::mCameraIdStr.string());
+                __FUNCTION__, TClientBase::mCameraIdStr.c_str());
         return NO_INIT;
     }
 
     res = mDevice->initialize(providerPtr, monitorTags);
     if (res != OK) {
         ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
-                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
+                __FUNCTION__, TClientBase::mCameraIdStr.c_str(), strerror(-res), res);
         return res;
     }
 
@@ -152,7 +153,7 @@
     res = mDevice->setNotifyCallback(weakThis);
     if (res != OK) {
         ALOGE("%s: Camera %s: Unable to set notify callback: %s (%d)",
-                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
+                __FUNCTION__, TClientBase::mCameraIdStr.c_str(), strerror(-res), res);
         return res;
     }
 
@@ -183,30 +184,30 @@
     }
 
     ALOGI("%s: Client object's dtor for Camera Id %s completed. Client was: %s (PID %d, UID %u)",
-            __FUNCTION__, TClientBase::mCameraIdStr.string(),
-            String8(TClientBase::mClientPackageName).string(),
+            __FUNCTION__, TClientBase::mCameraIdStr.c_str(),
+            TClientBase::mClientPackageName.c_str(),
             mInitialClientPid, TClientBase::mClientUid);
 }
 
 template <typename TClientBase>
 status_t Camera2ClientBase<TClientBase>::dumpClient(int fd,
                                               const Vector<String16>& args) {
-    String8 result;
-    result.appendFormat("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
-            TClientBase::mCameraIdStr.string(),
+    std::string result;
+    result += fmt::sprintf("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
+            TClientBase::mCameraIdStr.c_str(),
             (TClientBase::getRemoteCallback() != NULL ?
-                    IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
+                    (void *)IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
             TClientBase::mClientPid);
-    result.append("  State: ");
+    result += "  State: ";
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     // TODO: print dynamic/request section from most recent requests
 
     return dumpDevice(fd, args);
 }
 
 template <typename TClientBase>
-status_t Camera2ClientBase<TClientBase>::startWatchingTags(const String8 &tags, int out) {
+status_t Camera2ClientBase<TClientBase>::startWatchingTags(const std::string &tags, int out) {
   sp<CameraDeviceBase> device = mDevice;
   if (!device) {
     dprintf(out, "  Device is detached");
@@ -241,23 +242,23 @@
 status_t Camera2ClientBase<TClientBase>::dumpDevice(
                                                 int fd,
                                                 const Vector<String16>& args) {
-    String8 result;
+    std::string result;
 
     result = "  Device dump:\n";
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
 
     sp<CameraDeviceBase> device = mDevice;
     if (!device.get()) {
         result = "  *** Device is detached\n";
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         return NO_ERROR;
     }
 
     status_t res = device->dump(fd, args);
     if (res != OK) {
-        result = String8::format("   Error dumping device: %s (%d)",
+        result = fmt::sprintf("   Error dumping device: %s (%d)",
                 strerror(-res), res);
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
     }
 
     return NO_ERROR;
@@ -284,23 +285,23 @@
 template <typename TClientBase>
 binder::Status Camera2ClientBase<TClientBase>::disconnectImpl() {
     ATRACE_CALL();
-    ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.string());
+    ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.c_str());
     Mutex::Autolock icl(mBinderSerializationLock);
 
-    ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.string());
+    ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.c_str());
     binder::Status res = binder::Status::ok();
     // Allow both client and the media server to disconnect at all times
     int callingPid = CameraThreadState::getCallingPid();
     if (callingPid != TClientBase::mClientPid &&
         callingPid != TClientBase::mServicePid) return res;
 
-    ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
+    ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.c_str());
 
     // Before detaching the device, cache the info from current open session.
     // The disconnected check avoids duplication of info and also prevents
     // deadlock while acquiring service lock in cacheDump.
     if (!TClientBase::mDisconnected) {
-        ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.string());
+        ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.c_str());
         Camera2ClientBase::getCameraService()->cacheDump();
     }
 
@@ -308,7 +309,7 @@
 
     CameraService::BasicClient::disconnect();
 
-    ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.string());
+    ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.c_str());
 
     return res;
 }
@@ -318,7 +319,7 @@
     if (mDevice == 0) return;
     mDevice->disconnect();
 
-    ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string());
+    ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.c_str());
 }
 
 template <typename TClientBase>
@@ -334,7 +335,7 @@
         ALOGE("%s: Camera %s: Connection attempt from pid %d; "
                 "current locked to pid %d",
                 __FUNCTION__,
-                TClientBase::mCameraIdStr.string(),
+                TClientBase::mCameraIdStr.c_str(),
                 CameraThreadState::getCallingPid(),
                 TClientBase::mClientPid);
         return BAD_VALUE;
@@ -365,8 +366,7 @@
         return;
     }
 
-    String8 physicalId8(physicalId.c_str());
-    auto physicalCameraMetadata = mDevice->infoPhysical(physicalId8);
+    auto physicalCameraMetadata = mDevice->infoPhysical(physicalId);
     auto orientationEntry = physicalCameraMetadata.find(ANDROID_SENSOR_ORIENTATION);
 
     if (orientationEntry.count == 1) {
@@ -387,7 +387,7 @@
         status_t res = TClientBase::startCameraStreamingOps();
         if (res != OK) {
             ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__,
-                    TClientBase::mCameraIdStr.string(), res);
+                    TClientBase::mCameraIdStr.c_str(), res);
             return res;
         }
         mCameraServiceProxyWrapper->logActive(TClientBase::mCameraIdStr, maxPreviewFps);
@@ -407,7 +407,7 @@
         status_t res = TClientBase::finishCameraStreamingOps();
         if (res != OK) {
             ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__,
-                    TClientBase::mCameraIdStr.string(), res);
+                    TClientBase::mCameraIdStr.c_str(), res);
         }
         mCameraServiceProxyWrapper->logIdle(TClientBase::mCameraIdStr,
                 requestCount, resultErrorCount, deviceError, userTag, videoStabilizationMode,
@@ -522,7 +522,7 @@
 }
 
 template <typename TClientBase>
-status_t Camera2ClientBase<TClientBase>::injectCamera(const String8& injectedCamId,
+status_t Camera2ClientBase<TClientBase>::injectCamera(const std::string& injectedCamId,
         sp<CameraProviderManager> manager) {
     return mDevice->injectCamera(injectedCamId, manager);
 }
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 5cf3033..30c763d 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -50,10 +50,10 @@
     Camera2ClientBase(const sp<CameraService>& cameraService,
                       const sp<TCamCallbacks>& remoteCallback,
                       std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
-                      const String16& clientPackageName,
+                      const std::string& clientPackageName,
                       bool systemNativeClient,
-                      const std::optional<String16>& clientFeatureId,
-                      const String8& cameraId,
+                      const std::optional<std::string>& clientFeatureId,
+                      const std::string& cameraId,
                       int api1CameraId,
                       int cameraFacing,
                       int sensorOrientation,
@@ -65,11 +65,12 @@
                       bool legacyClient = false);
     virtual ~Camera2ClientBase();
 
-    virtual status_t      initialize(sp<CameraProviderManager> manager, const String8& monitorTags);
-    virtual status_t      dumpClient(int fd, const Vector<String16>& args);
-    virtual status_t      startWatchingTags(const String8 &tags, int out);
-    virtual status_t      stopWatchingTags(int out);
-    virtual status_t      dumpWatchedEventsToVector(std::vector<std::string> &out);
+    virtual status_t      initialize(sp<CameraProviderManager> manager,
+            const std::string& monitorTags) override;
+    virtual status_t      dumpClient(int fd, const Vector<String16>& args) override;
+    virtual status_t      startWatchingTags(const std::string &tags, int out) override;
+    virtual status_t      stopWatchingTags(int out) override;
+    virtual status_t      dumpWatchedEventsToVector(std::vector<std::string> &out) override;
 
     /**
      * NotificationListener implementation
@@ -130,7 +131,7 @@
         mutable Mutex mRemoteCallbackLock;
     } mSharedCameraCallbacks;
 
-    status_t      injectCamera(const String8& injectedCamId,
+    status_t      injectCamera(const std::string& injectedCamId,
                                sp<CameraProviderManager> manager) override;
     status_t      stopInjection() override;
 
@@ -181,7 +182,7 @@
 
 private:
     template<typename TProviderPtr>
-    status_t              initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+    status_t              initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
 
     binder::Status disconnectImpl();
 
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 919108d..017da0f 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -20,7 +20,6 @@
 #include <list>
 
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
@@ -99,11 +98,12 @@
      */
     virtual metadata_vendor_id_t getVendorTagId() const = 0;
 
-    virtual status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) = 0;
+    virtual status_t initialize(sp<CameraProviderManager> manager,
+            const std::string& monitorTags) = 0;
     virtual status_t disconnect() = 0;
 
     virtual status_t dump(int fd, const Vector<String16> &args) = 0;
-    virtual status_t startWatchingTags(const String8 &tags) = 0;
+    virtual status_t startWatchingTags(const std::string &tags) = 0;
     virtual status_t stopWatchingTags() = 0;
     virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out) = 0;
 
@@ -111,7 +111,7 @@
      * The physical camera device's static characteristics metadata buffer, or
      * the logical camera's static characteristics if physical id is empty.
      */
-    virtual const CameraMetadata& infoPhysical(const String8& physicalId) const = 0;
+    virtual const CameraMetadata& infoPhysical(const std::string& physicalId) const = 0;
 
     virtual bool isCompositeJpegRDisabled() const { return false; };
 
@@ -188,7 +188,7 @@
     virtual status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t>  &sensorPixelModesUsed,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -212,7 +212,7 @@
     virtual status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -510,7 +510,7 @@
      * The injection camera session to replace the internal camera
      * session.
      */
-    virtual status_t injectCamera(const String8& injectedCamId,
+    virtual status_t injectCamera(const std::string& injectedCamId,
             sp<CameraProviderManager> manager) = 0;
 
     /**
diff --git a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
index 63abcf0..976c47c 100644
--- a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
+++ b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
@@ -20,7 +20,6 @@
 #include <vector>
 
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/Timers.h>
 
 #include "camera/CaptureResult.h"
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 1a6e341..23051ef 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -43,6 +43,7 @@
 #include <hwbinder/IPCThreadState.h>
 #include <utils/Trace.h>
 #include <ui/PublicFormat.h>
+#include <camera/StringUtils.h>
 
 #include "api2/HeicCompositeStream.h"
 #include "device3/ZoomRatioMapper.h"
@@ -143,7 +144,7 @@
             String16(aidlHalServiceDescriptor));
     for (const auto &aidlInstance : aidlProviders) {
         std::string aidlServiceName =
-                getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
+                getFullAidlProviderName(toStdString(aidlInstance));
         auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
         if (res != OK) {
             ALOGE("%s Unable to register for notifications with AIDL service manager",
@@ -774,14 +775,14 @@
         primaryMap = &mCameraProviderByCameraId;
         alternateMap = &mTorchProviderByCameraId;
     }
-    auto id = cameraId.c_str();
-    (*primaryMap)[id] = provider;
-    auto search = alternateMap->find(id);
+
+    (*primaryMap)[cameraId] = provider;
+    auto search = alternateMap->find(cameraId);
     if (search != alternateMap->end()) {
         ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
-                "That should not be possible", __FUNCTION__, id);
+                "That should not be possible", __FUNCTION__, cameraId.c_str());
     }
-    ALOGV("%s: Camera device %s connected", __FUNCTION__, id);
+    ALOGV("%s: Camera device %s connected", __FUNCTION__, cameraId.c_str());
 }
 
 void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
@@ -796,7 +797,7 @@
         providerMap = &mCameraProviderByCameraId;
     }
     std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
-    auto search = providerMap->find(cameraId.c_str());
+    auto search = providerMap->find(cameraId);
     if (search != providerMap->end()) {
         // Drop the reference to this ICameraProvider. This is safe to do immediately (without an
         // added delay) because hwservicemanager guarantees to hold the reference for at least five
@@ -805,7 +806,7 @@
         // restart it. An example when this could happen is switching from a front-facing to a
         // rear-facing camera. If the HAL were to exit during the camera switch, the camera could
         // appear janky to the user.
-        providerMap->erase(cameraId.c_str());
+        providerMap->erase(cameraId);
         IPCThreadState::self()->flushCommands();
     } else {
         ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
@@ -823,7 +824,7 @@
     {
         std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
-        res = addAidlProviderLocked(String8(name).c_str());
+        res = addAidlProviderLocked(toStdString(name));
     }
 
     sp<StatusListener> listener = getStatusListener();
@@ -2035,14 +2036,14 @@
 status_t CameraProviderManager::removeProvider(const std::string& provider) {
     std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
     std::unique_lock<std::mutex> lock(mInterfaceMutex);
-    std::vector<String8> removedDeviceIds;
+    std::vector<std::string> removedDeviceIds;
     status_t res = NAME_NOT_FOUND;
     std::string removedProviderName;
     for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
         if ((*it)->mProviderInstance == provider) {
             removedDeviceIds.reserve((*it)->mDevices.size());
             for (auto& deviceInfo : (*it)->mDevices) {
-                removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
+                removedDeviceIds.push_back(deviceInfo->mId);
             }
             removedProviderName = (*it)->mProviderName;
             mProviders.erase(it);
@@ -2182,7 +2183,7 @@
     return OK;
 }
 
-void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
+void CameraProviderManager::ProviderInfo::removeDevice(const std::string &id) {
     for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
         if ((*it)->mId == id) {
             mUniqueCameraIds.erase(id);
@@ -2222,8 +2223,7 @@
             ALOGV("%s: notify device not_present: %s",
                   __FUNCTION__,
                   deviceName.c_str());
-            listener->onDeviceStatusChanged(String8(id.c_str()),
-                                            CameraDeviceStatus::NOT_PRESENT);
+            listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
             mLock.lock();
         }
     }
@@ -2324,8 +2324,7 @@
     CameraDeviceStatus internalNewStatus = newStatus;
     if (!mInitialized) {
         mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
-                cameraDeviceName.c_str(), std::string().c_str(),
-                internalNewStatus);
+                cameraDeviceName, std::string(), internalNewStatus);
         return;
     }
 
@@ -2339,7 +2338,7 @@
 
     // Call without lock held to allow reentrancy into provider manager
     if (listener != nullptr) {
-        listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
+        listener->onDeviceStatusChanged(id, internalNewStatus);
     }
 }
 
@@ -2415,8 +2414,7 @@
     }
     // Call without lock held to allow reentrancy into provider manager
     if (listener != nullptr) {
-        listener->onDeviceStatusChanged(String8(id.c_str()),
-                String8(physicalId.c_str()), newStatus);
+        listener->onDeviceStatusChanged(id, physicalId, newStatus);
     }
     return;
 }
@@ -2467,7 +2465,7 @@
     }
 
     *id = cameraId;
-    *physicalId = physicalCameraDeviceName.c_str();
+    *physicalId = physicalCameraDeviceName;
     return OK;
 }
 
@@ -2511,7 +2509,7 @@
     // findDeviceInfo, which should be holding mLock while iterating through
     // each provider's devices).
     if (listener != nullptr) {
-        listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
+        listener->onTorchStatusChanged(id, newStatus, systemCameraKind);
     }
     return;
 }
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index e6e4619..a2ec576 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -179,15 +179,15 @@
     struct StatusListener : virtual public RefBase {
         ~StatusListener() {}
 
-        virtual void onDeviceStatusChanged(const String8 &cameraId,
+        virtual void onDeviceStatusChanged(const std::string &cameraId,
                 CameraDeviceStatus newStatus) = 0;
-        virtual void onDeviceStatusChanged(const String8 &cameraId,
-                const String8 &physicalCameraId,
+        virtual void onDeviceStatusChanged(const std::string &cameraId,
+                const std::string &physicalCameraId,
                 CameraDeviceStatus newStatus) = 0;
-        virtual void onTorchStatusChanged(const String8 &cameraId,
+        virtual void onTorchStatusChanged(const std::string &cameraId,
                 TorchModeStatus newStatus,
                 SystemCameraKind kind) = 0;
-        virtual void onTorchStatusChanged(const String8 &cameraId,
+        virtual void onTorchStatusChanged(const std::string &cameraId,
                 TorchModeStatus newStatus) = 0;
         virtual void onNewProviderRegistered() = 0;
     };
@@ -784,7 +784,7 @@
         void torchModeStatusChangeInternal(const std::string& cameraDeviceName,
                 TorchModeStatus newStatus);
 
-        void removeDevice(std::string id);
+        void removeDevice(const std::string &id);
 
     };
 
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index e259379..2322def 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -21,6 +21,7 @@
 #include <map>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 
 #include "common/FrameProducer.h"
 #include "common/FrameProcessorBase.h"
@@ -86,8 +87,8 @@
 }
 
 void FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) {
-    String8 result("    Latest received frame:\n");
-    write(fd, result.string(), result.size());
+    std::string result("    Latest received frame:\n");
+    write(fd, result.c_str(), result.size());
 
     CameraMetadata lastFrame;
     std::map<std::string, CameraMetadata> lastPhysicalFrames;
@@ -97,16 +98,16 @@
         lastFrame = CameraMetadata(mLastFrame);
 
         for (const auto& physicalFrame : mLastPhysicalFrames) {
-            lastPhysicalFrames.emplace(String8(physicalFrame.mPhysicalCameraId),
+            lastPhysicalFrames.emplace(physicalFrame.mPhysicalCameraId,
                     physicalFrame.mPhysicalCameraMetadata);
         }
     }
     lastFrame.dump(fd, /*verbosity*/2, /*indentation*/6);
 
     for (const auto& physicalFrame : lastPhysicalFrames) {
-        result = String8::format("   Latest received frame for physical camera %s:\n",
+        result = fmt::sprintf("   Latest received frame for physical camera %s:\n",
                 physicalFrame.first.c_str());
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         CameraMetadata lastPhysicalMetadata = CameraMetadata(physicalFrame.second);
         lastPhysicalMetadata.sort();
         lastPhysicalMetadata.dump(fd, /*verbosity*/2, /*indentation*/6);
@@ -138,7 +139,7 @@
     ATRACE_CALL();
     CaptureResult result;
 
-    ALOGV("%s: Camera %s: Process new frames", __FUNCTION__, device->getId().string());
+    ALOGV("%s: Camera %s: Process new frames", __FUNCTION__, device->getId().c_str());
 
     while ( (res = device->getNextResult(&result)) == OK) {
 
@@ -149,7 +150,7 @@
         entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
         if (entry.count == 0) {
             ALOGE("%s: Camera %s: Error reading frame number",
-                    __FUNCTION__, device->getId().string());
+                    __FUNCTION__, device->getId().c_str());
             break;
         }
         ATRACE_INT("cam2_frame", entry.data.i32[0]);
@@ -167,7 +168,7 @@
     }
     if (res != NOT_ENOUGH_DATA) {
         ALOGE("%s: Camera %s: Error getting next frame: %s (%d)",
-                __FUNCTION__, device->getId().string(), strerror(-res), res);
+                __FUNCTION__, device->getId().c_str(), strerror(-res), res);
         return;
     }
 
@@ -177,7 +178,7 @@
 bool FrameProcessorBase::processSingleFrame(CaptureResult &result,
                                             const sp<FrameProducer> &device) {
     ALOGV("%s: Camera %s: Process single frame (is empty? %d)",
-            __FUNCTION__, device->getId().string(), result.mMetadata.isEmpty());
+            __FUNCTION__, device->getId().c_str(), result.mMetadata.isEmpty());
     return processListeners(result, device) == OK;
 }
 
@@ -197,7 +198,7 @@
     // include CaptureResultExtras.
     entry = result.mMetadata.find(ANDROID_REQUEST_ID);
     if (entry.count == 0) {
-        ALOGE("%s: Camera %s: Error reading frame id", __FUNCTION__, device->getId().string());
+        ALOGE("%s: Camera %s: Error reading frame id", __FUNCTION__, device->getId().c_str());
         return BAD_VALUE;
     }
     int32_t requestId = entry.data.i32[0];
@@ -223,7 +224,7 @@
         }
     }
     ALOGV("%s: Camera %s: Got %zu range listeners out of %zu", __FUNCTION__,
-          device->getId().string(), listeners.size(), mRangeListeners.size());
+          device->getId().c_str(), listeners.size(), mRangeListeners.size());
 
     List<sp<FilteredListener> >::iterator item = listeners.begin();
     for (; item != listeners.end(); item++) {
diff --git a/services/camera/libcameraservice/common/FrameProducer.h b/services/camera/libcameraservice/common/FrameProducer.h
index a14b3d6..dd4df7d 100644
--- a/services/camera/libcameraservice/common/FrameProducer.h
+++ b/services/camera/libcameraservice/common/FrameProducer.h
@@ -18,7 +18,6 @@
 #define ANDROID_SERVERS_CAMERA_FRAMEPRODUCER_H
 
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/Timers.h>
 
 #include "camera/CameraMetadata.h"
@@ -39,7 +38,7 @@
     /**
      * Retrieve the device camera ID
      */
-    virtual const String8& getId() const = 0;
+    virtual const std::string& getId() const = 0;
 
     /**
      * Wait for a new frame to be produced, with timeout in nanoseconds.
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index b18cbd4..5e79d6b 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -431,7 +431,7 @@
     for (const auto& combination : combs) {
         std::unordered_set<std::string> deviceIds;
         for (const auto &cameraDeviceId : combination.combination) {
-            deviceIds.insert(cameraDeviceId.c_str());
+            deviceIds.insert(cameraDeviceId);
         }
         mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
     }
@@ -735,7 +735,7 @@
     camera::device::StreamConfiguration streamConfiguration;
     bool earlyExit = false;
     auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
-            String8(mId.c_str()), mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
+            mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
             mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
 
     if (!bRes.isOk()) {
@@ -789,9 +789,9 @@
             return res;
         }
         camera3::metadataGetter getMetadata =
-                [this](const String8 &id, bool overrideForPerfClass) {
+                [this](const std::string &id, bool overrideForPerfClass) {
                     CameraMetadata physicalDeviceInfo;
-                    mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+                    mManager->getCameraCharacteristicsLocked(id, overrideForPerfClass,
                                                    &physicalDeviceInfo,
                                                    /*overrideToPortrait*/false);
                     return physicalDeviceInfo;
@@ -801,7 +801,7 @@
         bStatus =
             SessionConfigurationUtils::convertToHALStreamCombination(
                     cameraIdAndSessionConfig.mSessionConfiguration,
-                    String8(cameraId.c_str()), deviceInfo,
+                    cameraId, deviceInfo,
                     mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
                     physicalCameraIds, streamConfiguration,
                     overrideForPerfClass, &shouldExit);
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index 8ff5c3f..bf7a471 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -533,7 +533,7 @@
                 for (auto& combination : cameraDeviceIdCombinations) {
                     std::unordered_set<std::string> deviceIds;
                     for (auto &cameraDeviceId : combination) {
-                        deviceIds.insert(cameraDeviceId.c_str());
+                        deviceIds.insert(cameraDeviceId);
                     }
                     mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
                 }
@@ -837,7 +837,7 @@
     hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
     bool earlyExit = false;
     auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
-            String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
+            mId, mCameraCharacteristics, getMetadata, mPhysicalIds,
             configuration_3_7, overrideForPerfClass, &earlyExit);
 
     if (!bRes.isOk()) {
@@ -927,9 +927,9 @@
             return res;
         }
         camera3::metadataGetter getMetadata =
-                [this](const String8 &id, bool overrideForPerfClass) {
+                [this](const std::string &id, bool overrideForPerfClass) {
                     CameraMetadata physicalDeviceInfo;
-                    mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+                    mManager->getCameraCharacteristicsLocked(id, overrideForPerfClass,
                             &physicalDeviceInfo, /*overrideToPortrait*/false);
                     return physicalDeviceInfo;
                 };
@@ -938,7 +938,7 @@
         bStatus =
             SessionConfigurationUtils::convertToHALStreamCombination(
                     cameraIdAndSessionConfig.mSessionConfiguration,
-                    String8(cameraId.c_str()), deviceInfo, getMetadata,
+                    cameraId, deviceInfo, getMetadata,
                     physicalCameraIds, streamConfiguration,
                     overrideForPerfClass, &shouldExit);
         if (!bStatus.isOk()) {
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 2ac38d5..c42e51a 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -18,10 +18,13 @@
 #define LOG_TAG "Camera3-BufferManager"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 
+#include <sstream>
+
 #include <gui/ISurfaceComposer.h>
 #include <private/gui/ComposerService.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 #include "utils/CameraTraces.h"
 #include "Camera3BufferManager.h"
 
@@ -454,34 +457,36 @@
 void Camera3BufferManager::dump(int fd, [[maybe_unused]] const Vector<String16>& args) const {
     Mutex::Autolock l(mLock);
 
-    String8 lines;
-    lines.appendFormat("      Total stream sets: %zu\n", mStreamSetMap.size());
+    std::ostringstream lines;
+    lines << fmt::sprintf("      Total stream sets: %zu\n", mStreamSetMap.size());
     for (size_t i = 0; i < mStreamSetMap.size(); i++) {
-        lines.appendFormat("        Stream set %d(%d) has below streams:\n",
+        lines << fmt::sprintf("        Stream set %d(%d) has below streams:\n",
                 mStreamSetMap.keyAt(i).id, mStreamSetMap.keyAt(i).isMultiRes);
         for (size_t j = 0; j < mStreamSetMap[i].streamInfoMap.size(); j++) {
-            lines.appendFormat("          Stream %d\n", mStreamSetMap[i].streamInfoMap[j].streamId);
+            lines << fmt::sprintf("          Stream %d\n",
+                    mStreamSetMap[i].streamInfoMap[j].streamId);
         }
-        lines.appendFormat("          Stream set max allowed buffer count: %zu\n",
+        lines << fmt::sprintf("          Stream set max allowed buffer count: %zu\n",
                 mStreamSetMap[i].maxAllowedBufferCount);
-        lines.appendFormat("          Stream set buffer count water mark: %zu\n",
+        lines << fmt::sprintf("          Stream set buffer count water mark: %zu\n",
                 mStreamSetMap[i].allocatedBufferWaterMark);
-        lines.appendFormat("          Handout buffer counts:\n");
+        lines << "          Handout buffer counts:\n";
         for (size_t m = 0; m < mStreamSetMap[i].handoutBufferCountMap.size(); m++) {
             int streamId = mStreamSetMap[i].handoutBufferCountMap.keyAt(m);
             size_t bufferCount = mStreamSetMap[i].handoutBufferCountMap.valueAt(m);
-            lines.appendFormat("            stream id: %d, buffer count: %zu.\n",
+            lines << fmt::sprintf("            stream id: %d, buffer count: %zu.\n",
                     streamId, bufferCount);
         }
-        lines.appendFormat("          Attached buffer counts:\n");
+        lines << "          Attached buffer counts:\n";
         for (size_t m = 0; m < mStreamSetMap[i].attachedBufferCountMap.size(); m++) {
             int streamId = mStreamSetMap[i].attachedBufferCountMap.keyAt(m);
             size_t bufferCount = mStreamSetMap[i].attachedBufferCountMap.valueAt(m);
-            lines.appendFormat("            stream id: %d, attached buffer count: %zu.\n",
+            lines << fmt::sprintf("            stream id: %d, attached buffer count: %zu.\n",
                     streamId, bufferCount);
         }
     }
-    write(fd, lines.string(), lines.size());
+    std::string linesStr = std::move(lines.str());
+    write(fd, linesStr.c_str(), linesStr.size());
 }
 
 bool Camera3BufferManager::checkIfStreamRegisteredLocked(int streamId,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 61c3298..a0e2778 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -26,10 +26,10 @@
 #endif
 
 // Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
             ##__VA_ARGS__)
 
-#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
             ##__VA_ARGS__)
 
 // Convenience macros for transitioning to the error state
@@ -44,10 +44,12 @@
 
 #include <utility>
 
+#include <android-base/stringprintf.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <utils/Timers.h>
 #include <cutils/properties.h>
+#include <camera/StringUtils.h>
 
 #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
 #include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -75,7 +77,8 @@
 namespace android {
 
 Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
-        const String8 &id, bool overrideForPerfClass, bool overrideToPortrait, bool legacyClient):
+        const std::string &id, bool overrideForPerfClass, bool overrideToPortrait,
+        bool legacyClient):
         mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
         mId(id),
         mLegacyClient(legacyClient),
@@ -107,17 +110,17 @@
         mActivePhysicalId("")
 {
     ATRACE_CALL();
-    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.c_str());
 }
 
 Camera3Device::~Camera3Device()
 {
     ATRACE_CALL();
-    ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.c_str());
     disconnectImpl();
 }
 
-const String8& Camera3Device::getId() const {
+const std::string& Camera3Device::getId() const {
     return mId;
 }
 
@@ -125,7 +128,7 @@
 
     /** Start up status tracker thread */
     mStatusTracker = new StatusTracker(this);
-    status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
+    status_t res = mStatusTracker->run((std::string("C3Dev-") + mId + "-Status").c_str());
     if (res != OK) {
         SET_ERR_L("Unable to start status tracking thread: %s (%d)",
                 strerror(-res), res);
@@ -188,7 +191,7 @@
             this, mStatusTracker, mInterface, sessionParamKeys,
             mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait,
             mSupportZoomOverride);
-    res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
+    res = mRequestThread->run((std::string("C3Dev-") + mId + "-ReqQueue").c_str());
     if (res != OK) {
         SET_ERR_L("Unable to start request queue thread: %s (%d)",
                 strerror(-res), res);
@@ -225,23 +228,23 @@
 
     bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
     if (usePrecorrectArray) {
-        res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
+        res = mDistortionMappers[mId].setupStaticInfo(mDeviceInfo);
         if (res != OK) {
             SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
             return res;
         }
     }
 
-    mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
+    mZoomRatioMappers[mId] = ZoomRatioMapper(&mDeviceInfo,
             mSupportNativeZoomRatio, usePrecorrectArray);
 
     if (SessionConfigurationUtils::supportsUltraHighResolutionCapture(mDeviceInfo)) {
-        mUHRCropAndMeteringRegionMappers[mId.c_str()] =
+        mUHRCropAndMeteringRegionMappers[mId] =
                 UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray);
     }
 
     if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
-        mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
+        mRotateAndCropMappers.emplace(mId, &mDeviceInfo);
     }
 
     // Hidl/AidlCamera3DeviceInjectionMethods
@@ -428,7 +431,7 @@
                     /*isUltraHighResolution*/true);
     if (maxDefaultJpegResolution.width == 0) {
         ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
-                __FUNCTION__, mId.string());
+                __FUNCTION__, mId.c_str());
         return BAD_VALUE;
     }
     bool useMaxSensorPixelModeThreshold = false;
@@ -443,7 +446,7 @@
     camera_metadata_ro_entry jpegBufMaxSize = info.find(ANDROID_JPEG_MAX_SIZE);
     if (jpegBufMaxSize.count == 0) {
         ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
-                mId.string());
+                mId.c_str());
         return BAD_VALUE;
     }
     maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
@@ -475,7 +478,7 @@
     camera_metadata_ro_entry maxPointCount = info.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
     if (maxPointCount.count == 0) {
         ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
-                __FUNCTION__, mId.string());
+                __FUNCTION__, mId.c_str());
         return BAD_VALUE;
     }
     ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
@@ -497,7 +500,7 @@
     size_t count = rawOpaqueSizes.count;
     if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
         ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
-                __FUNCTION__, mId.string(), count);
+                __FUNCTION__, mId.c_str(), count);
         return BAD_VALUE;
     }
 
@@ -509,7 +512,7 @@
     }
 
     ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
-            __FUNCTION__, mId.string(), width, height);
+            __FUNCTION__, mId.c_str(), width, height);
     return BAD_VALUE;
 }
 
@@ -523,10 +526,10 @@
 
     ALOGW_IF(!gotInterfaceLock,
             "Camera %s: %s: Unable to lock interface lock, proceeding anyway",
-            mId.string(), __FUNCTION__);
+            mId.c_str(), __FUNCTION__);
     ALOGW_IF(!gotLock,
             "Camera %s: %s: Unable to lock main lock, proceeding anyway",
-            mId.string(), __FUNCTION__);
+            mId.c_str(), __FUNCTION__);
 
     bool dumpTemplates = false;
 
@@ -536,9 +539,9 @@
         if (args[i] == templatesOption) {
             dumpTemplates = true;
         }
-        if (args[i] == TagMonitor::kMonitorOption) {
+        if (args[i] == toString16(TagMonitor::kMonitorOption)) {
             if (i + 1 < n) {
-                String8 monitorTags = String8(args[i + 1]);
+                std::string monitorTags = toStdString(args[i + 1]);
                 if (monitorTags == "off") {
                     mTagMonitor.disableMonitoring();
                 } else {
@@ -550,7 +553,7 @@
         }
     }
 
-    String8 lines;
+    std::string lines;
 
     const char *status =
             mStatus == STATUS_ERROR         ? "ERROR" :
@@ -560,42 +563,42 @@
             mStatus == STATUS_ACTIVE        ? "ACTIVE" :
             "Unknown";
 
-    lines.appendFormat("    Device status: %s\n", status);
+    lines += fmt::sprintf("    Device status: %s\n", status);
     if (mStatus == STATUS_ERROR) {
-        lines.appendFormat("    Error cause: %s\n", mErrorCause.string());
+        lines += fmt::sprintf("    Error cause: %s\n", mErrorCause.c_str());
     }
-    lines.appendFormat("    Stream configuration:\n");
+    lines += "    Stream configuration:\n";
     const char *mode =
             mOperatingMode == CAMERA_STREAM_CONFIGURATION_NORMAL_MODE ? "NORMAL" :
             mOperatingMode == CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE ?
                     "CONSTRAINED_HIGH_SPEED" : "CUSTOM";
-    lines.appendFormat("    Operation mode: %s (%d) \n", mode, mOperatingMode);
+    lines += fmt::sprintf("    Operation mode: %s (%d) \n", mode, mOperatingMode);
 
     if (mInputStream != NULL) {
-        write(fd, lines.string(), lines.size());
+        write(fd, lines.c_str(), lines.size());
         mInputStream->dump(fd, args);
     } else {
-        lines.appendFormat("      No input stream.\n");
-        write(fd, lines.string(), lines.size());
+        lines += "      No input stream.\n";
+        write(fd, lines.c_str(), lines.size());
     }
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
         mOutputStreams[i]->dump(fd,args);
     }
 
     if (mBufferManager != NULL) {
-        lines = String8("    Camera3 Buffer Manager:\n");
-        write(fd, lines.string(), lines.size());
+        lines = "    Camera3 Buffer Manager:\n";
+        write(fd, lines.c_str(), lines.size());
         mBufferManager->dump(fd, args);
     }
 
-    lines = String8("    In-flight requests:\n");
+    lines = "    In-flight requests:\n";
     if (mInFlightLock.try_lock()) {
         if (mInFlightMap.size() == 0) {
-            lines.append("      None\n");
+            lines += "      None\n";
         } else {
             for (size_t i = 0; i < mInFlightMap.size(); i++) {
                 InFlightRequest r = mInFlightMap.valueAt(i);
-                lines.appendFormat("      Frame %d |  Timestamp: %" PRId64 ", metadata"
+                lines += fmt::sprintf("      Frame %d |  Timestamp: %" PRId64 ", metadata"
                         " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
                         r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
                         r.numBuffersLeft);
@@ -603,9 +606,9 @@
         }
         mInFlightLock.unlock();
     } else {
-        lines.append("      Failed to acquire In-flight lock!\n");
+        lines += "      Failed to acquire In-flight lock!\n";
     }
-    write(fd, lines.string(), lines.size());
+    write(fd, lines.c_str(), lines.size());
 
     if (mRequestThread != NULL) {
         mRequestThread->dumpCaptureRequestLatency(fd,
@@ -613,8 +616,8 @@
     }
 
     {
-        lines = String8("    Last request sent:\n");
-        write(fd, lines.string(), lines.size());
+        lines = "    Last request sent:\n";
+        write(fd, lines.c_str(), lines.size());
 
         CameraMetadata lastRequest = getLatestRequestLocked();
         lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
@@ -634,12 +637,12 @@
             camera_metadata_t *templateRequest = nullptr;
             mInterface->constructDefaultRequestSettings(
                     (camera_request_template_t) i, &templateRequest);
-            lines = String8::format("    HAL Request %s:\n", templateNames[i-1]);
+            lines = fmt::sprintf("    HAL Request %s:\n", templateNames[i-1]);
             if (templateRequest == nullptr) {
-                lines.append("       Not supported\n");
-                write(fd, lines.string(), lines.size());
+                lines += "       Not supported\n";
+                write(fd, lines.c_str(), lines.size());
             } else {
-                write(fd, lines.string(), lines.size());
+                write(fd, lines.c_str(), lines.size());
                 dump_indented_camera_metadata(templateRequest,
                         fd, /*verbosity*/2, /*indentation*/8);
             }
@@ -650,8 +653,8 @@
     mTagMonitor.dumpMonitoredMetadata(fd);
 
     if (mInterface->valid()) {
-        lines = String8("     HAL device dump:\n");
-        write(fd, lines.string(), lines.size());
+        lines = "     HAL device dump:\n";
+        write(fd, lines.c_str(), lines.size());
         mInterface->dump(fd);
     }
 
@@ -661,7 +664,7 @@
     return OK;
 }
 
-status_t Camera3Device::startWatchingTags(const String8 &tags) {
+status_t Camera3Device::startWatchingTags(const std::string &tags) {
     mTagMonitor.parseTagsToMonitor(tags);
     return OK;
 }
@@ -676,7 +679,7 @@
     return OK;
 }
 
-const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
+const CameraMetadata& Camera3Device::infoPhysical(const std::string& physicalId) const {
     ALOGVV("%s: E", __FUNCTION__);
     if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
                     mStatus == STATUS_ERROR)) {
@@ -684,12 +687,11 @@
                 mStatus == STATUS_ERROR ?
                 "when in error state" : "before init");
     }
-    if (physicalId.isEmpty()) {
+    if (physicalId.empty()) {
         return mDeviceInfo;
     } else {
-        std::string id(physicalId.c_str());
-        if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
-            return mPhysicalDeviceInfoMap.at(id);
+        if (mPhysicalDeviceInfoMap.find(physicalId) != mPhysicalDeviceInfoMap.end()) {
+            return mPhysicalDeviceInfoMap.at(physicalId);
         } else {
             ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
             return mDeviceInfo;
@@ -698,8 +700,7 @@
 }
 
 const CameraMetadata& Camera3Device::info() const {
-    String8 emptyId;
-    return infoPhysical(emptyId);
+    return infoPhysical(/*physicalId*/ std::string());
 }
 
 status_t Camera3Device::checkStatusOkToCaptureLocked() {
@@ -793,7 +794,7 @@
         std::list<const SurfaceMap>& surfaceMaps,
         const CameraMetadata& request) {
     PhysicalCameraSettingsList requestList;
-    requestList.push_back({std::string(getId().string()), request});
+    requestList.push_back({getId(), request});
     requestsList.push_back(requestList);
 
     SurfaceMap surfaceMap;
@@ -845,7 +846,7 @@
             SET_ERR_L("Can't transition to active in %f seconds!",
                     kActiveTimeout/1e9);
         }
-        ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
+        ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.c_str(),
               (*(requestList.begin()))->mResultExtras.requestId);
     } else {
         CLOGE("Cannot queue request. Impossible.");
@@ -928,7 +929,7 @@
             SET_ERR_L("Unexpected status: %d", mStatus);
             return INVALID_OPERATION;
     }
-    ALOGV("Camera %s: Clearing repeating request", mId.string());
+    ALOGV("Camera %s: Clearing repeating request", mId.c_str());
 
     return mRequestThread->clearRepeatingRequests(lastFrameNumber);
 }
@@ -947,7 +948,7 @@
     nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
     Mutex::Autolock l(mLock);
     ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
-            mId.string(), mNextStreamId, width, height, format);
+            mId.c_str(), mNextStreamId, width, height, format);
 
     status_t res;
     bool wasActive = false;
@@ -1006,14 +1007,14 @@
         internalResumeLocked();
     }
 
-    ALOGV("Camera %s: Created input stream", mId.string());
+    ALOGV("Camera %s: Created input stream", mId.c_str());
     return OK;
 }
 
 status_t Camera3Device::createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
             uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
@@ -1049,7 +1050,8 @@
 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
         android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-        const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
+        const std::string& physicalCameraId,
+        const std::unordered_set<int32_t> &sensorPixelModesUsed,
         std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
         uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
         int timestampBase, int mirrorMode, int32_t colorSpace, bool useReadoutTimestamp) {
@@ -1062,8 +1064,8 @@
             " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d"
             " dynamicRangeProfile 0x%" PRIx64 ", streamUseCase %" PRId64 ", timestampBase %d,"
             " mirrorMode %d, colorSpace %d, useReadoutTimestamp %d",
-            mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
-            consumerUsage, isShared, physicalCameraId.string(), isMultiResolution,
+            mId.c_str(), mNextStreamId, width, height, format, dataSpace, rotation,
+            consumerUsage, isShared, physicalCameraId.c_str(), isMultiResolution,
             dynamicRangeProfile, streamUseCase, timestampBase, mirrorMode, colorSpace,
             useReadoutTimestamp);
 
@@ -1214,7 +1216,7 @@
         }
         internalResumeLocked();
     }
-    ALOGV("Camera %s: Created new stream", mId.string());
+    ALOGV("Camera %s: Created new stream", mId.c_str());
     return OK;
 }
 
@@ -1299,18 +1301,18 @@
     Mutex::Autolock l(mLock);
     status_t res;
 
-    ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
+    ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.c_str(), id);
 
     // CameraDevice semantics require device to already be idle before
     // deleteStream is called, unlike for createStream.
     if (mStatus == STATUS_ACTIVE) {
-        ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
+        ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.c_str());
         return -EBUSY;
     }
 
     if (mStatus == STATUS_ERROR) {
         ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
-                __FUNCTION__, mId.string());
+                __FUNCTION__, mId.c_str());
         return -EBUSY;
     }
 
@@ -1502,7 +1504,7 @@
         mRequestTemplateCache[templateId].acquire(rawRequest);
 
         // Override the template request with zoomRatioMapper
-        res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
+        res = mZoomRatioMappers[mId].initZoomRatioInTemplate(
                 &mRequestTemplateCache[templateId]);
         if (res != OK) {
             CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
@@ -1555,7 +1557,7 @@
             SET_ERR_L("Unexpected status: %d",mStatus);
             return INVALID_OPERATION;
     }
-    ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
+    ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.c_str(),
             maxExpectedDuration);
     status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                            /*requestThreadInvocation*/ false);
@@ -1583,7 +1585,7 @@
         return NO_INIT;
     }
 
-    ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
+    ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.c_str(),
           maxExpectedDuration);
     status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                            requestThreadInvocation);
@@ -1602,7 +1604,7 @@
 
     mRequestThread->setPaused(false);
 
-    ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
+    ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.c_str(),
             kActiveTimeout);
     // internalResumeLocked is always called from a binder thread.
     res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout,
@@ -1819,7 +1821,7 @@
 
 status_t Camera3Device::flush(int64_t *frameNumber) {
     ATRACE_CALL();
-    ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
+    ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.c_str());
     Mutex::Autolock il(mInterfaceLock);
 
     {
@@ -1851,7 +1853,7 @@
 
 status_t Camera3Device::prepare(int maxCount, int streamId) {
     ATRACE_CALL();
-    ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
+    ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.c_str(), streamId);
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
@@ -1876,7 +1878,7 @@
 
 status_t Camera3Device::tearDown(int streamId) {
     ATRACE_CALL();
-    ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
+    ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.c_str(), streamId);
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
@@ -1897,7 +1899,8 @@
 status_t Camera3Device::addBufferListenerForStream(int streamId,
         wp<Camera3StreamBufferListener> listener) {
     ATRACE_CALL();
-    ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
+    ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.c_str(),
+            streamId);
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
@@ -1945,7 +1948,7 @@
         if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
             return;
         }
-        ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
+        ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.c_str(),
                 idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
         internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
 
@@ -2026,7 +2029,7 @@
         const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
     ATRACE_CALL();
     ALOGV("%s: Camera %s: set consumer surface for stream %d",
-            __FUNCTION__, mId.string(), streamId);
+            __FUNCTION__, mId.c_str(), streamId);
 
     if (surfaceIds == nullptr) {
         return BAD_VALUE;
@@ -2306,7 +2309,7 @@
 
     res = mPreparerThread->resume();
     if (res != OK) {
-        ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
+        ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.c_str());
     }
 }
 
@@ -2466,7 +2469,7 @@
     overrideStreamUseCaseLocked();
 
     // Start configuring the streams
-    ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
+    ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.c_str());
 
     mPreparerThread->pause();
 
@@ -2522,7 +2525,7 @@
                      static_cast<android_dataspace_t>(
                          aidl::android::hardware::graphics::common::Dataspace::JPEG_R))) {
                 bufferSizes[k] = static_cast<uint32_t>(
-                        getJpegBufferSize(infoPhysical(String8(outputStream->physical_camera_id)),
+                        getJpegBufferSize(infoPhysical(outputStream->physical_camera_id),
                                 outputStream->width, outputStream->height));
             } else if (outputStream->data_space ==
                     static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
@@ -2535,7 +2538,7 @@
 
         if (mOutputStreams[i]->isMultiResolution()) {
             int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
-            const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
+            const std::string &physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
             mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
         }
 
@@ -2650,14 +2653,14 @@
     internalUpdateStatusLocked((mFakeStreamId == NO_STREAM) ?
             STATUS_CONFIGURED : STATUS_UNCONFIGURED);
 
-    ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
+    ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.c_str());
 
     // tear down the deleted streams after configure streams.
     mDeletedStreams.clear();
 
     auto rc = mPreparerThread->resume();
     if (rc != OK) {
-        SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
+        SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.c_str());
         return rc;
     }
 
@@ -2671,7 +2674,7 @@
     // configure the injection streams.
     if (mInjectionMethods->isInjecting()) {
         ALOGD("%s: Injection camera %s: Start to configure streams.",
-              __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
+              __FUNCTION__, mInjectionMethods->getInjectedCamId().c_str());
         res = mInjectionMethods->injectCamera(config, bufferSizes);
         if (res != OK) {
             ALOGE("Can't finish inject camera process!");
@@ -2700,11 +2703,11 @@
         // Should never be adding a second fake stream when one is already
         // active
         SET_ERR_L("%s: Camera %s: A fake stream already exists!",
-                __FUNCTION__, mId.string());
+                __FUNCTION__, mId.c_str());
         return INVALID_OPERATION;
     }
 
-    ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.string());
+    ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.c_str());
 
     sp<Camera3OutputStreamInterface> fakeStream =
             new Camera3FakeStream(mNextStreamId);
@@ -2728,7 +2731,7 @@
     if (mFakeStreamId == NO_STREAM) return OK;
     if (mOutputStreams.size() == 1) return OK;
 
-    ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.string());
+    ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.c_str());
 
     // Ok, have a fake stream and there's at least one other output stream,
     // so remove the fake
@@ -2780,8 +2783,9 @@
 
 void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
     // Print out all error messages to log
-    String8 errorCause = String8::formatV(fmt, args);
-    ALOGE("Camera %s: %s", mId.string(), errorCause.string());
+    std::string errorCause;
+    base::StringAppendV(&errorCause, fmt, args);
+    ALOGE("Camera %s: %s", mId.c_str(), errorCause.c_str());
 
     // But only do error state transition steps for the first error
     if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
@@ -2813,7 +2817,7 @@
 status_t Camera3Device::registerInFlight(uint32_t frameNumber,
         int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
         bool hasAppCallback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
-        bool isFixedFps, const std::set<std::set<String8>>& physicalCameraIds,
+        bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
         bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
         const std::set<std::string>& cameraIdsWithZoom,
         const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
@@ -3064,7 +3068,7 @@
 
 void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
         const CameraMetadata& sessionParams,
-        const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
+        const std::map<int32_t, std::set<std::string>>& groupIdPhysicalCameraMap) {
     ATRACE_CALL();
     Mutex::Autolock l(mRequestLock);
     mReconfigured = true;
@@ -3117,8 +3121,8 @@
     return OK;
 }
 
-const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
-    static String8 deadId("<DeadDevice>");
+const std::string& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
+    static std::string deadId("<DeadDevice>");
     sp<Camera3Device> d = device.promote();
     if (d != nullptr) return d->mId;
     return deadId;
@@ -3928,7 +3932,7 @@
         outputBuffers->insertAt(camera_stream_buffer_t(), 0,
                 captureRequest->mOutputStreams.size());
         halRequest->output_buffers = outputBuffers->array();
-        std::set<std::set<String8>> requestedPhysicalCameras;
+        std::set<std::set<std::string>> requestedPhysicalCameras;
 
         sp<Camera3Device> parent = mParent.promote();
         if (parent == NULL) {
@@ -4009,11 +4013,11 @@
             {
                 sp<Camera3Device> parent = mParent.promote();
                 if (parent != nullptr) {
-                    const String8& streamCameraId = outputStream->getPhysicalCameraId();
+                    const std::string& streamCameraId = outputStream->getPhysicalCameraId();
                     for (const auto& settings : captureRequest->mSettingsList) {
-                        if ((streamCameraId.isEmpty() &&
-                                parent->getId() == settings.cameraId.c_str()) ||
-                                streamCameraId == settings.cameraId.c_str()) {
+                        if ((streamCameraId.empty() &&
+                                parent->getId() == settings.cameraId) ||
+                                streamCameraId == settings.cameraId) {
                             outputStream->fireBufferRequestForFrameNumber(
                                     captureRequest->mResultExtras.frameNumber,
                                     settings.metadata);
@@ -4022,12 +4026,12 @@
                 }
             }
 
-            String8 physicalCameraId = outputStream->getPhysicalCameraId();
+            const std::string &physicalCameraId = outputStream->getPhysicalCameraId();
             int32_t streamGroupId = outputStream->getHalStreamGroupId();
             if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
                 requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
-            } else if (!physicalCameraId.isEmpty()) {
-                requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
+            } else if (!physicalCameraId.empty()) {
+                requestedPhysicalCameras.insert(std::set<std::string>({physicalCameraId}));
             }
             halRequest->num_output_buffers++;
         }
@@ -5456,9 +5460,9 @@
     return mRequestThread->setZoomOverride(zoomOverride);
 }
 
-status_t Camera3Device::injectCamera(const String8& injectedCamId,
+status_t Camera3Device::injectCamera(const std::string& injectedCamId,
                                      sp<CameraProviderManager> manager) {
-    ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
+    ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.c_str());
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     // When the camera device is active, injectCamera() and stopInjection() will call
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index b1dd135..0c1bbcb 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -85,7 +85,7 @@
   public:
 
     explicit Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
-            const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+            const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
             bool legacyClient = false);
 
     virtual ~Camera3Device();
@@ -101,7 +101,7 @@
      * CameraDeviceBase interface
      */
 
-    const String8& getId() const override;
+    const std::string& getId() const override;
 
     metadata_vendor_id_t getVendorTagId() const override { return mVendorTagId; }
 
@@ -110,15 +110,15 @@
 
     // Transitions to idle state on success.
     virtual status_t initialize(sp<CameraProviderManager> /*manager*/,
-            const String8& /*monitorTags*/) = 0;
+            const std::string& /*monitorTags*/) = 0;
 
     status_t disconnect() override;
     status_t dump(int fd, const Vector<String16> &args) override;
-    status_t startWatchingTags(const String8 &tags) override;
+    status_t startWatchingTags(const std::string &tags) override;
     status_t stopWatchingTags() override;
     status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
     const CameraMetadata& info() const override;
-    const CameraMetadata& infoPhysical(const String8& physicalId) const override;
+    const CameraMetadata& infoPhysical(const std::string& physicalId) const override;
     bool isCompositeJpegRDisabled() const override { return mIsCompositeJpegRDisabled; };
 
     // Capture and setStreamingRequest will configure streams if currently in
@@ -144,7 +144,7 @@
     status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -162,7 +162,7 @@
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -330,7 +330,7 @@
      * The injection camera session to replace the internal camera
      * session.
      */
-    status_t injectCamera(const String8& injectedCamId,
+    status_t injectCamera(const std::string& injectedCamId,
                           sp<CameraProviderManager> manager);
 
     /**
@@ -376,7 +376,7 @@
     Mutex                      mLock;
 
     // Camera device ID
-    const String8              mId;
+    const std::string          mId;
 
     // Legacy camera client flag
     bool                       mLegacyClient;
@@ -586,14 +586,14 @@
     Condition                  mStatusChanged;
 
     // Tracking cause of fatal errors when in STATUS_ERROR
-    String8                    mErrorCause;
+    std::string                mErrorCause;
 
     camera3::StreamSet         mOutputStreams;
     sp<camera3::Camera3Stream> mInputStream;
     bool                       mIsInputStreamMultiResolution;
     SessionStatsBuilder        mSessionStatsBuilder;
     // Map from stream group ID to physical cameras backing the stream group
-    std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;
+    std::map<int32_t, std::set<std::string>> mGroupIdPhysicalCameraMap;
 
     int                        mNextStreamId;
     bool                       mNeedConfig;
@@ -709,7 +709,7 @@
      */
     virtual CameraMetadata getLatestRequestLocked();
 
-    virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+    virtual status_t injectionCameraInitialize(const std::string &injectCamId,
             sp<CameraProviderManager> manager) = 0;
 
     /**
@@ -891,7 +891,7 @@
          */
         void     configurationComplete(bool isConstrainedHighSpeed,
                 const CameraMetadata& sessionParams,
-                const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap);
+                const std::map<int32_t, std::set<std::string>>& groupIdPhysicalCameraMap);
 
         /**
          * Set or clear the list of repeating requests. Does not block
@@ -996,7 +996,7 @@
 
         virtual bool threadLoop();
 
-        static const String8& getId(const wp<Camera3Device> &device);
+        static const std::string& getId(const wp<Camera3Device> &device);
 
         status_t           queueTriggerLocked(RequestTrigger trigger);
         // Mix-in queued triggers into this request
@@ -1102,7 +1102,7 @@
 
         wp<NotificationListener> mListener;
 
-        const String8      mId;       // The camera ID
+        const std::string  mId;       // The camera ID
         int                mStatusId; // The RequestThread's component ID for
                                       // status tracking
 
@@ -1173,7 +1173,7 @@
         Vector<int32_t>    mSessionParamKeys;
         CameraMetadata     mLatestSessionParams;
 
-        std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;
+        std::map<int32_t, std::set<std::string>> mGroupIdPhysicalCameraMap;
 
         const bool         mUseHalBufManager;
         const bool         mSupportCameraMute;
@@ -1209,7 +1209,7 @@
     status_t registerInFlight(uint32_t frameNumber,
             int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
             bool callback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
-            bool isFixedFps, const std::set<std::set<String8>>& physicalCameraIds,
+            bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
             bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
             const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
             nsecs_t requestTimeNs);
@@ -1503,7 +1503,7 @@
 
         bool isStreamConfigCompleteButNotInjected();
 
-        const String8& getInjectedCamId() const;
+        const std::string& getInjectedCamId() const;
 
         void getInjectionConfig(/*out*/ camera3::camera_stream_configuration* injectionConfig,
                 /*out*/ std::vector<uint32_t>* injectionBufferSizes);
@@ -1557,7 +1557,7 @@
         Mutex mInjectionLock;
 
         // The injection camera ID.
-        String8 mInjectedCamId;
+        std::string mInjectedCamId;
     };
 
     virtual sp<Camera3DeviceInjectionMethods>
diff --git a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
index ab772d4..b0e4ca3 100644
--- a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
@@ -157,7 +157,7 @@
     return mIsStreamConfigCompleteButNotInjected;
 }
 
-const String8& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
+const std::string& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
         const {
     return mInjectedCamId;
 }
@@ -206,7 +206,7 @@
 
     // Start configuring the streams
     ALOGV("%s: Injection camera %s: Starting stream configuration", __FUNCTION__,
-            mInjectedCamId.string());
+            mInjectedCamId.c_str());
 
     parent->mPreparerThread->pause();
 
@@ -249,12 +249,12 @@
     parent->internalUpdateStatusLocked(STATUS_CONFIGURED);
 
     ALOGV("%s: Injection camera %s: Stream configuration complete", __FUNCTION__,
-            mInjectedCamId.string());
+            mInjectedCamId.c_str());
 
     auto rc = parent->mPreparerThread->resume();
     if (rc != OK) {
         ALOGE("%s: Injection camera %s: Preparer thread failed to resume!",
-                 __FUNCTION__, mInjectedCamId.string());
+                 __FUNCTION__, mInjectedCamId.c_str());
         return rc;
     }
 
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
index 8c0ac71..75162bf 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
@@ -20,13 +20,14 @@
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 #include "Camera3FakeStream.h"
 
 namespace android {
 
 namespace camera3 {
 
-const String8 Camera3FakeStream::FAKE_ID;
+const std::string Camera3FakeStream::FAKE_ID;
 
 Camera3FakeStream::Camera3FakeStream(int id) :
         Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, FAKE_WIDTH, FAKE_HEIGHT,
@@ -68,9 +69,9 @@
 }
 
 void Camera3FakeStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
-    String8 lines;
-    lines.appendFormat("    Stream[%d]: Fake\n", mId);
-    write(fd, lines.string(), lines.size());
+    std::string lines;
+    lines += fmt::sprintf("    Stream[%d]: Fake\n", mId);
+    write(fd, lines.c_str(), lines.size());
 
     Camera3IOStreamBase::dump(fd, args);
 }
@@ -115,7 +116,7 @@
     return OK;
 }
 
-const String8& Camera3FakeStream::getPhysicalCameraId() const {
+const std::string& Camera3FakeStream::getPhysicalCameraId() const {
     return FAKE_ID;
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.h b/services/camera/libcameraservice/device3/Camera3FakeStream.h
index 1e9f478..1d82190 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.h
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.h
@@ -65,7 +65,7 @@
     /**
      * Query the physical camera id for the output stream.
      */
-    virtual const String8& getPhysicalCameraId() const override;
+    virtual const std::string& getPhysicalCameraId() const override;
 
     /**
      * Return if this output stream is for video encoding.
@@ -130,7 +130,7 @@
     static const android_dataspace FAKE_DATASPACE = HAL_DATASPACE_UNKNOWN;
     static const camera_stream_rotation_t FAKE_ROTATION = CAMERA_STREAM_ROTATION_0;
     static const uint64_t FAKE_USAGE = GRALLOC_USAGE_HW_COMPOSER;
-    static const String8 FAKE_ID;
+    static const std::string FAKE_ID;
 
     /**
      * Internal Camera3Stream interface
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index fbaaf7b..c59138c 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -18,10 +18,13 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <sstream>
+
 #include <inttypes.h>
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 #include "device3/Camera3IOStreamBase.h"
 #include "device3/StatusTracker.h"
 
@@ -32,7 +35,7 @@
 Camera3IOStreamBase::Camera3IOStreamBase(int id, camera_stream_type_t type,
         uint32_t width, uint32_t height, size_t maxSize, int format,
         android_dataspace dataSpace, camera_stream_rotation_t rotation,
-        const String8& physicalCameraId,
+        const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         int setId, bool isMultiResolution, int64_t dynamicRangeProfile, int64_t streamUseCase,
         bool deviceTimeBaseIsRealtime, int timestampBase, int32_t colorSpace) :
@@ -75,32 +78,34 @@
 }
 
 void Camera3IOStreamBase::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
-    String8 lines;
+    std::ostringstream lines;
 
     uint64_t consumerUsage = 0;
     status_t res = getEndpointUsage(&consumerUsage);
     if (res != OK) consumerUsage = 0;
 
-    lines.appendFormat("      State: %d\n", mState);
-    lines.appendFormat("      Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
+    lines << fmt::sprintf("      State: %d\n", mState);
+    lines << fmt::sprintf("      Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
             camera_stream::width, camera_stream::height,
             camera_stream::format, camera_stream::data_space);
-    lines.appendFormat("      Max size: %zu\n", mMaxSize);
-    lines.appendFormat("      Combined usage: 0x%" PRIx64 ", max HAL buffers: %d\n",
+    lines << fmt::sprintf("      Max size: %zu\n", mMaxSize);
+    lines << fmt::sprintf("      Combined usage: 0x%" PRIx64 ", max HAL buffers: %d\n",
             mUsage | consumerUsage, camera_stream::max_buffers);
-    if (strlen(camera_stream::physical_camera_id) > 0) {
-        lines.appendFormat("      Physical camera id: %s\n", camera_stream::physical_camera_id);
+    if (!camera_stream::physical_camera_id.empty()) {
+        lines << "      Physical camera id: " << camera_stream::physical_camera_id << "\n";
     }
-    lines.appendFormat("      Dynamic Range Profile: 0x%" PRIx64 "\n",
+    lines << fmt::sprintf("      Dynamic Range Profile: 0x%" PRIx64 "\n",
             camera_stream::dynamic_range_profile);
-    lines.appendFormat("      Color Space: %d\n", camera_stream::color_space);
-    lines.appendFormat("      Stream use case: %" PRId64 "\n", camera_stream::use_case);
-    lines.appendFormat("      Timestamp base: %d\n", getTimestampBase());
-    lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
+    lines << fmt::sprintf("      Color Space: %d\n", camera_stream::color_space);
+    lines << fmt::sprintf("      Stream use case: %" PRId64 "\n", camera_stream::use_case);
+    lines << fmt::sprintf("      Timestamp base: %d\n", getTimestampBase());
+    lines << fmt::sprintf("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
-    lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu, currently cached: %zu\n",
-            mTotalBufferCount, mHandoutTotalBufferCount, mCachedOutputBufferCount);
-    write(fd, lines.string(), lines.size());
+    lines << fmt::sprintf("      Total buffers: %zu, currently dequeued: %zu, "
+            "currently cached: %zu\n", mTotalBufferCount, mHandoutTotalBufferCount,
+            mCachedOutputBufferCount);
+    std::string linesStr = std::move(lines.str());
+    write(fd, linesStr.c_str(), linesStr.size());
 
     Camera3Stream::dump(fd, args);
 }
@@ -268,7 +273,7 @@
     // carry on
 
     if (releaseFence != 0) {
-        mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
+        mCombinedFence = Fence::merge(toString8(mName), mCombinedFence, releaseFence);
     }
 
     if (output) {
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 6af0875..239fc71 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -35,7 +35,7 @@
     Camera3IOStreamBase(int id, camera_stream_type_t type,
             uint32_t width, uint32_t height, size_t maxSize, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
             int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index 631bb43..54ffbd7 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -21,13 +21,14 @@
 #include <gui/BufferItem.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 #include "Camera3InputStream.h"
 
 namespace android {
 
 namespace camera3 {
 
-const String8 Camera3InputStream::FAKE_ID;
+const std::string Camera3InputStream::FAKE_ID;
 
 Camera3InputStream::Camera3InputStream(int id,
         uint32_t width, uint32_t height, int format) :
@@ -216,9 +217,9 @@
 }
 
 void Camera3InputStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
-    String8 lines;
-    lines.appendFormat("    Stream[%d]: Input\n", mId);
-    write(fd, lines.string(), lines.size());
+    std::string lines;
+    lines += fmt::sprintf("    Stream[%d]: Input\n", mId);
+    write(fd, lines.c_str(), lines.size());
 
     Camera3IOStreamBase::dump(fd, args);
 }
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 5e0587b..d4f4b15 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -53,7 +53,7 @@
     sp<IGraphicBufferProducer> mProducer;
     Vector<BufferItem> mBuffersInFlight;
 
-    static const String8 FAKE_ID;
+    static const std::string FAKE_ID;
 
     /**
      * Camera3IOStreamBase
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 1e7bd57..172b62a 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -27,7 +27,9 @@
 
 #include <inttypes.h>
 
+#include <android-base/stringprintf.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
 
@@ -42,7 +44,7 @@
 
 namespace android {
 
-Camera3OfflineSession::Camera3OfflineSession(const String8 &id,
+Camera3OfflineSession::Camera3OfflineSession(const std::string &id,
         const sp<camera3::Camera3Stream>& inputStream,
         const camera3::StreamSet& offlineStreamSet,
         camera3::BufferRecords&& bufferRecords,
@@ -75,15 +77,15 @@
         mRotateAndCropMappers(offlineStates.mRotateAndCropMappers),
         mStatus(STATUS_UNINITIALIZED) {
     ATRACE_CALL();
-    ALOGV("%s: Created offline session for camera %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Created offline session for camera %s", __FUNCTION__, mId.c_str());
 }
 
 Camera3OfflineSession::~Camera3OfflineSession() {
     ATRACE_CALL();
-    ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.c_str());
 }
 
-const String8& Camera3OfflineSession::getId() const {
+const std::string& Camera3OfflineSession::getId() const {
     return mId;
 }
 
@@ -109,7 +111,7 @@
             return OK; // don't close twice
         } else if (mStatus == STATUS_ERROR) {
             ALOGE("%s: offline session %s shutting down in error state",
-                    __FUNCTION__, mId.string());
+                    __FUNCTION__, mId.c_str());
         }
         listener = mListener.promote();
     }
@@ -217,8 +219,9 @@
 
 void Camera3OfflineSession::setErrorStateLockedV(const char *fmt, va_list args) {
     // Print out all error messages to log
-    String8 errorCause = String8::formatV(fmt, args);
-    ALOGE("Camera %s: %s", mId.string(), errorCause.string());
+    std::string errorCause;
+    base::StringAppendV(&errorCause, fmt, args);
+    ALOGE("Camera %s: %s", mId.c_str(), errorCause.c_str());
 
     // But only do error state transition steps for the first error
     if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index e780043..b5fd486 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -20,9 +20,6 @@
 #include <memory>
 #include <mutex>
 
-#include <utils/String8.h>
-#include <utils/String16.h>
-
 #include <android/hardware/camera/device/3.6/ICameraOfflineSession.h>
 
 #include <fmq/MessageQueue.h>
@@ -138,7 +135,7 @@
   public:
 
     // initialize by Camera3Device.
-    explicit Camera3OfflineSession(const String8& id,
+    explicit Camera3OfflineSession(const std::string& id,
             const sp<camera3::Camera3Stream>& inputStream,
             const camera3::StreamSet& offlineStreamSet,
             camera3::BufferRecords&& bufferRecords,
@@ -158,7 +155,7 @@
     /**
      * FrameProducer interface
      */
-    const String8& getId() const override;
+    const std::string& getId() const override;
     const CameraMetadata& info() const override;
     status_t waitForNextFrame(nsecs_t timeout) override;
     status_t getNextResult(CaptureResult *frame) override;
@@ -171,7 +168,7 @@
 
   protected:
     // Camera device ID
-    const String8 mId;
+    const std::string mId;
     sp<camera3::Camera3Stream> mInputStream;
     camera3::StreamSet mOutputStreams;
     camera3::BufferRecords mBufferRecords;
@@ -236,7 +233,7 @@
     std::mutex mProcessCaptureResultLock;
 
     // Tracking cause of fatal errors when in STATUS_ERROR
-    String8 mErrorCause;
+    std::string mErrorCause;
 
     // Lock to ensure requestStreamBuffers() callbacks are serialized
     std::mutex mRequestBufferInterfaceLock;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index a387064..7185895 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -31,6 +31,7 @@
 #include <ui/GraphicBuffer.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 
 #include <common/CameraDeviceBase.h>
 #include "api1/client2/JpegProcessor.h"
@@ -53,7 +54,7 @@
         sp<Surface> consumer,
         uint32_t width, uint32_t height, int format,
         android_dataspace dataSpace, camera_stream_rotation_t rotation,
-        nsecs_t timestampOffset, const String8& physicalCameraId,
+        nsecs_t timestampOffset, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
         int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -88,7 +89,7 @@
         sp<Surface> consumer,
         uint32_t width, uint32_t height, size_t maxSize, int format,
         android_dataspace dataSpace, camera_stream_rotation_t rotation,
-        nsecs_t timestampOffset, const String8& physicalCameraId,
+        nsecs_t timestampOffset, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
         int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -128,7 +129,7 @@
         uint32_t width, uint32_t height, int format,
         uint64_t consumerUsage, android_dataspace dataSpace,
         camera_stream_rotation_t rotation, nsecs_t timestampOffset,
-        const String8& physicalCameraId,
+        const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
         int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -164,7 +165,7 @@
         mState = STATE_ERROR;
     }
 
-    mConsumerName = String8("Deferred");
+    mConsumerName = "Deferred";
     bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
     mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
 }
@@ -174,7 +175,7 @@
                                          int format,
                                          android_dataspace dataSpace,
                                          camera_stream_rotation_t rotation,
-                                         const String8& physicalCameraId,
+                                         const std::string& physicalCameraId,
                                          const std::unordered_set<int32_t> &sensorPixelModesUsed,
                                          IPCTransport transport,
                                          uint64_t consumerUsage, nsecs_t timestampOffset,
@@ -523,10 +524,10 @@
 }
 
 void Camera3OutputStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
-    String8 lines;
-    lines.appendFormat("    Stream[%d]: Output\n", mId);
-    lines.appendFormat("      Consumer name: %s\n", mConsumerName.string());
-    write(fd, lines.string(), lines.size());
+    std::string lines;
+    lines += fmt::sprintf("    Stream[%d]: Output\n", mId);
+    lines += fmt::sprintf("      Consumer name: %s\n", mConsumerName);
+    write(fd, lines.c_str(), lines.size());
 
     Camera3IOStreamBase::dump(fd, args);
 
@@ -710,7 +711,8 @@
             // service. So update mMaxCachedBufferCount.
             mMaxCachedBufferCount = 1;
             mTotalBufferCount += mMaxCachedBufferCount;
-            res = mPreviewFrameSpacer->run(String8::format("PreviewSpacer-%d", mId).string());
+            res = mPreviewFrameSpacer->run((std::string("PreviewSpacer-")
+                    + std::to_string(mId)).c_str());
             if (res != OK) {
                 ALOGE("%s: Unable to start preview spacer: %s (%d)", __FUNCTION__,
                         strerror(-res), res);
@@ -1234,7 +1236,7 @@
     return OK;
 }
 
-const String8& Camera3OutputStream::getPhysicalCameraId() const {
+const std::string& Camera3OutputStream::getPhysicalCameraId() const {
     Mutex::Autolock l(mLock);
     return physicalCameraId();
 }
@@ -1338,7 +1340,7 @@
     // Output image data to file
     std::string filePath = "/data/misc/cameraserver/";
     filePath += imageFileName;
-    std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
+    std::ofstream imageFile(filePath, std::ofstream::binary);
     if (!imageFile.is_open()) {
         ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
         graphicBuffer->unlock();
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 1435081..0b456c0 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -89,7 +89,7 @@
     Camera3OutputStream(int id, sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation,
-            nsecs_t timestampOffset, const String8& physicalCameraId,
+            nsecs_t timestampOffset, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
             int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
             int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -108,7 +108,7 @@
     Camera3OutputStream(int id, sp<Surface> consumer,
             uint32_t width, uint32_t height, size_t maxSize, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation,
-            nsecs_t timestampOffset, const String8& physicalCameraId,
+            nsecs_t timestampOffset, const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
             int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
             int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -126,7 +126,7 @@
     Camera3OutputStream(int id, uint32_t width, uint32_t height, int format,
             uint64_t consumerUsage, android_dataspace dataSpace,
             camera_stream_rotation_t rotation, nsecs_t timestampOffset,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
             int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
             int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -214,7 +214,7 @@
     /**
      * Query the physical camera id for the output stream.
      */
-    virtual const String8& getPhysicalCameraId() const override;
+    virtual const std::string& getPhysicalCameraId() const override;
 
     /**
      * Set the graphic buffer manager to get/return the stream buffers.
@@ -276,7 +276,7 @@
     Camera3OutputStream(int id, camera_stream_type_t type,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
             uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
             int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
@@ -327,7 +327,7 @@
     bool mTraceFirstBuffer;
 
     // Name of Surface consumer
-    String8           mConsumerName;
+    std::string           mConsumerName;
 
     /**
      * GraphicBuffer manager this stream is registered to. Used to replace the buffer
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 4baa7e8..1ab8162 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -94,7 +94,7 @@
     /**
      * Query the physical camera id for the output stream.
      */
-    virtual const String8& getPhysicalCameraId() const = 0;
+    virtual const std::string& getPhysicalCameraId() const = 0;
 
     /**
      * Set the batch size for buffer operations. The output stream will request
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f742a6d..1e7e337 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -43,6 +43,7 @@
 #include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
 
 #include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
 #include <camera_metadata_hidden.h>
 
 #include "device3/Camera3OutputUtils.h"
@@ -249,16 +250,16 @@
     // and RotationAndCrop mappers.
     std::set<uint32_t> keysToRemove;
 
-    auto iter = states.distortionMappers.find(states.cameraId.c_str());
+    auto iter = states.distortionMappers.find(states.cameraId);
     if (iter != states.distortionMappers.end()) {
         const auto& remappedKeys = iter->second.getRemappedKeys();
         keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
     }
 
-    const auto& remappedKeys = states.zoomRatioMappers[states.cameraId.c_str()].getRemappedKeys();
+    const auto& remappedKeys = states.zoomRatioMappers[states.cameraId].getRemappedKeys();
     keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
 
-    auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
+    auto mapper = states.rotateAndCropMappers.find(states.cameraId);
     if (mapper != states.rotateAndCropMappers.end()) {
         const auto& remappedKeys = iter->second.getRemappedKeys();
         keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
@@ -342,14 +343,14 @@
                 physicalMetadata.mPhysicalCameraMetadata.find(ANDROID_SENSOR_TIMESTAMP);
         if (timestamp.count == 0) {
             SET_ERR("No timestamp provided by HAL for physical camera %s frame %d!",
-                    String8(physicalMetadata.mPhysicalCameraId).c_str(), frameNumber);
+                    physicalMetadata.mPhysicalCameraId.c_str(), frameNumber);
             return;
         }
     }
 
     // Fix up some result metadata to account for HAL-level distortion correction
     status_t res = OK;
-    auto iter = states.distortionMappers.find(states.cameraId.c_str());
+    auto iter = states.distortionMappers.find(states.cameraId);
     if (iter != states.distortionMappers.end()) {
         res = iter->second.correctCaptureResult(&captureResult.mMetadata);
         if (res != OK) {
@@ -361,8 +362,8 @@
 
     // Fix up result metadata to account for zoom ratio availabilities between
     // HAL and app.
-    bool zoomRatioIs1 = cameraIdsWithZoom.find(states.cameraId.c_str()) == cameraIdsWithZoom.end();
-    res = states.zoomRatioMappers[states.cameraId.c_str()].updateCaptureResult(
+    bool zoomRatioIs1 = cameraIdsWithZoom.find(states.cameraId) == cameraIdsWithZoom.end();
+    res = states.zoomRatioMappers[states.cameraId].updateCaptureResult(
             &captureResult.mMetadata, zoomRatioIs1);
     if (res != OK) {
         SET_ERR("Failed to update capture result zoom ratio metadata for frame %d: %s (%d)",
@@ -372,7 +373,7 @@
 
     // Fix up result metadata to account for rotateAndCrop in AUTO mode
     if (rotateAndCropAuto) {
-        auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
+        auto mapper = states.rotateAndCropMappers.find(states.cameraId);
         if (mapper != states.rotateAndCropMappers.end()) {
             res = mapper->second.updateCaptureResult(
                     &captureResult.mMetadata);
@@ -401,8 +402,8 @@
     }
 
     for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
-        String8 cameraId8(physicalMetadata.mPhysicalCameraId);
-        auto mapper = states.distortionMappers.find(cameraId8.c_str());
+        const std::string cameraId = physicalMetadata.mPhysicalCameraId;
+        auto mapper = states.distortionMappers.find(cameraId);
         if (mapper != states.distortionMappers.end()) {
             res = mapper->second.correctCaptureResult(
                     &physicalMetadata.mPhysicalCameraMetadata);
@@ -413,12 +414,12 @@
             }
         }
 
-        zoomRatioIs1 = cameraIdsWithZoom.find(cameraId8.c_str()) == cameraIdsWithZoom.end();
-        res = states.zoomRatioMappers[cameraId8.c_str()].updateCaptureResult(
+        zoomRatioIs1 = cameraIdsWithZoom.find(cameraId) == cameraIdsWithZoom.end();
+        res = states.zoomRatioMappers[cameraId].updateCaptureResult(
                 &physicalMetadata.mPhysicalCameraMetadata, zoomRatioIs1);
         if (res != OK) {
             SET_ERR("Failed to update camera %s's physical zoom ratio metadata for "
-                    "frame %d: %s(%d)", cameraId8.c_str(), frameNumber, strerror(-res), res);
+                    "frame %d: %s(%d)", cameraId.c_str(), frameNumber, strerror(-res), res);
             return;
         }
     }
@@ -430,9 +431,9 @@
         return;
     }
     for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
-        String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+        const std::string &cameraId = physicalMetadata.mPhysicalCameraId;
         res = fixupMonochromeTags(states,
-                states.physicalDeviceInfoMap.at(cameraId8.c_str()),
+                states.physicalDeviceInfoMap.at(cameraId),
                 physicalMetadata.mPhysicalCameraMetadata);
         if (res != OK) {
             SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
@@ -442,7 +443,7 @@
 
     std::unordered_map<std::string, CameraMetadata> monitoredPhysicalMetadata;
     for (auto& m : physicalMetadatas) {
-        monitoredPhysicalMetadata.emplace(String8(m.mPhysicalCameraId).string(),
+        monitoredPhysicalMetadata.emplace(m.mPhysicalCameraId,
                 CameraMetadata(m.mPhysicalCameraMetadata));
     }
     states.tagMonitor.monitorMetadata(TagMonitor::RESULT,
@@ -528,7 +529,7 @@
 
 // Erase the subset of physicalCameraIds that contains id
 bool erasePhysicalCameraIdSet(
-        std::set<std::set<String8>>& physicalCameraIds, const String8& id) {
+        std::set<std::set<std::string>>& physicalCameraIds, const std::string& id) {
     bool found = false;
     for (auto iter = physicalCameraIds.begin(); iter != physicalCameraIds.end(); iter++) {
         if (iter->count(id) == 1) {
@@ -712,7 +713,7 @@
                 return;
             }
             for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
-                String8 physicalId(result->physcam_ids[i]);
+                const std::string physicalId = result->physcam_ids[i];
                 bool validPhysicalCameraMetadata =
                         erasePhysicalCameraIdSet(request.physicalCameraIds, physicalId);
                 if (!validPhysicalCameraMetadata) {
@@ -768,7 +769,7 @@
             for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
                 CameraMetadata physicalMetadata;
                 physicalMetadata.append(result->physcam_metadata[i]);
-                request.physicalMetadatas.push_back({String16(result->physcam_ids[i]),
+                request.physicalMetadatas.push_back({result->physcam_ids[i],
                         physicalMetadata});
             }
             if (shutterTimestamp == 0) {
@@ -996,7 +997,7 @@
             }
             if (r.hasCallback) {
                 ALOGVV("Camera %s: %s: Shutter fired for frame %d (id %d) at %" PRId64,
-                    states.cameraId.string(), __FUNCTION__,
+                    states.cameraId.c_str(), __FUNCTION__,
                     msg.frame_number, r.resultExtras.requestId, msg.timestamp);
                 // Call listener, if any
                 if (states.listener != nullptr) {
@@ -1053,15 +1054,15 @@
             hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
 
     int streamId = 0;
-    String16 physicalCameraId;
+    std::string physicalCameraId;
     if (msg.error_stream != nullptr) {
         Camera3Stream *stream =
                 Camera3Stream::cast(msg.error_stream);
         streamId = stream->getId();
-        physicalCameraId = String16(stream->physicalCameraId());
+        physicalCameraId = stream->physicalCameraId();
     }
     ALOGV("Camera %s: %s: HAL error, frame %d, stream %d: %d",
-            states.cameraId.string(), __FUNCTION__, msg.frame_number,
+            states.cameraId.c_str(), __FUNCTION__, msg.frame_number,
             streamId, msg.error_code);
 
     CaptureResultExtras resultExtras;
@@ -1083,13 +1084,12 @@
                     if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
                             errorCode) {
                         if (physicalCameraId.size() > 0) {
-                            String8 cameraId(physicalCameraId);
                             bool validPhysicalCameraId =
-                                    erasePhysicalCameraIdSet(r.physicalCameraIds, cameraId);
+                                    erasePhysicalCameraIdSet(r.physicalCameraIds, physicalCameraId);
                             if (!validPhysicalCameraId) {
                                 ALOGE("%s: Reported result failure for physical camera device: %s "
                                         " which is not part of the respective request!",
-                                        __FUNCTION__, cameraId.string());
+                                        __FUNCTION__, physicalCameraId.c_str());
                                 break;
                             }
                             resultExtras.errorPhysicalCameraId = physicalCameraId;
@@ -1114,7 +1114,7 @@
                 } else {
                     resultExtras.frameNumber = msg.frame_number;
                     ALOGE("Camera %s: %s: cannot find in-flight request on "
-                            "frame %" PRId64 " error", states.cameraId.string(), __FUNCTION__,
+                            "frame %" PRId64 " error", states.cameraId.c_str(), __FUNCTION__,
                             resultExtras.frameNumber);
                 }
             }
@@ -1123,7 +1123,7 @@
                 states.listener->notifyError(errorCode, resultExtras);
             } else {
                 ALOGE("Camera %s: %s: no listener available",
-                        states.cameraId.string(), __FUNCTION__);
+                        states.cameraId.c_str(), __FUNCTION__);
             }
             break;
         case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index d5328c5..134c037 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -71,7 +71,7 @@
     // Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
     // callbacks
     struct CaptureOutputStates {
-        const String8& cameraId;
+        const std::string& cameraId;
         std::mutex& inflightLock;
         int64_t& lastCompletedRegularFrameNumber;
         int64_t& lastCompletedReprocessFrameNumber;
@@ -115,7 +115,7 @@
     void notify(CaptureOutputStates& states, const camera_notify_msg *msg);
 
     struct RequestBufferStates {
-        const String8& cameraId;
+        const std::string& cameraId;
         std::mutex& reqBufferLock; // lock to serialize request buffer calls
         const bool useHalBufManager;
         StreamSet& outputStreams;
@@ -126,7 +126,7 @@
     };
 
     struct ReturnBufferStates {
-        const String8& cameraId;
+        const std::string& cameraId;
         const bool useHalBufManager;
         StreamSet& outputStreams;
         SessionStatsBuilder& sessionStatsBuilder;
@@ -134,7 +134,7 @@
     };
 
     struct FlushInflightReqStates {
-        const String8& cameraId;
+        const std::string& cameraId;
         std::mutex& inflightLock;
         InFlightRequestMap& inflightMap; // end of inflightLock scope
         const bool useHalBufManager;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
index 2e05dda..3ac666b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
@@ -296,7 +296,7 @@
         const VecStreamBufferType& buffers) {
     if (!states.useHalBufManager) {
         ALOGE("%s: Camera %s does not support HAL buffer managerment",
-                __FUNCTION__, states.cameraId.string());
+                __FUNCTION__, states.cameraId.c_str());
         return;
     }
 
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index f3a7359..1191f05 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -31,7 +31,7 @@
         uint32_t width, uint32_t height, int format,
         uint64_t consumerUsage, android_dataspace dataSpace,
         camera_stream_rotation_t rotation,
-        nsecs_t timestampOffset, const String8& physicalCameraId,
+        nsecs_t timestampOffset, const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
         int setId, bool useHalBufManager, int64_t dynamicProfile,
         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 1102ecb..c2ff20e 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -37,7 +37,7 @@
             uint32_t width, uint32_t height, int format,
             uint64_t consumerUsage, android_dataspace dataSpace,
             camera_stream_rotation_t rotation, nsecs_t timestampOffset,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
             int setId = CAMERA3_STREAM_SET_ID_INVALID,
             bool useHalBufManager = false,
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 4395455..23afa6e 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -22,6 +22,7 @@
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
+#include <camera/StringUtils.h>
 #include "device3/Camera3Stream.h"
 #include "device3/StatusTracker.h"
 #include "utils/TraceHFR.h"
@@ -52,7 +53,7 @@
         camera_stream_type type,
         uint32_t width, uint32_t height, size_t maxSize, int format,
         android_dataspace dataSpace, camera_stream_rotation_t rotation,
-        const String8& physicalCameraId,
+        const std::string& physicalCameraId,
         const std::unordered_set<int32_t> &sensorPixelModesUsed,
         int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -60,7 +61,7 @@
     camera_stream(),
     mId(id),
     mSetId(setId),
-    mName(String8::format("Camera3Stream[%d]", id)),
+    mName(fmt::sprintf("Camera3Stream[%d]", id)),
     mMaxSize(maxSize),
     mState(STATE_CONSTRUCTED),
     mStatusId(StatusTracker::NO_STATUS_ID),
@@ -92,7 +93,7 @@
     camera_stream::data_space = dataSpace;
     camera_stream::rotation = rotation;
     camera_stream::max_buffers = 0;
-    camera_stream::physical_camera_id = mPhysicalCameraId.string();
+    camera_stream::physical_camera_id = mPhysicalCameraId;
     camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
     camera_stream::dynamic_range_profile = dynamicRangeProfile;
     camera_stream::use_case = streamUseCase;
@@ -177,7 +178,7 @@
     return mOriginalDataSpace;
 }
 
-const String8& Camera3Stream::physicalCameraId() const {
+const std::string& Camera3Stream::physicalCameraId() const {
     return mPhysicalCameraId;
 }
 
@@ -376,7 +377,7 @@
     sp<StatusTracker> statusTracker = mStatusTracker.promote();
     if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
         std::string name = std::string("Stream ") + std::to_string(mId);
-        mStatusId = statusTracker->addComponent(name.c_str());
+        mStatusId = statusTracker->addComponent(name);
     }
 
     // Check if the stream configuration is unchanged, and skip reallocation if
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index f32053b..2bfaaab 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -19,7 +19,6 @@
 
 #include <gui/Surface.h>
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/List.h>
 
@@ -163,25 +162,25 @@
     /**
      * Get the stream's dimensions and format
      */
-    uint32_t          getWidth() const;
-    uint32_t          getHeight() const;
-    int               getFormat() const;
-    android_dataspace getDataSpace() const;
-    int32_t           getColorSpace() const;
-    uint64_t          getUsage() const;
-    void              setUsage(uint64_t usage);
-    void              setFormatOverride(bool formatOverriden);
-    bool              isFormatOverridden() const;
-    int               getOriginalFormat() const;
-    int64_t           getDynamicRangeProfile() const;
-    void              setDataSpaceOverride(bool dataSpaceOverriden);
-    bool              isDataSpaceOverridden() const;
-    android_dataspace getOriginalDataSpace() const;
-    int               getMaxHalBuffers() const;
-    const String8&    physicalCameraId() const;
-    int64_t           getStreamUseCase() const;
-    int               getTimestampBase() const;
-    bool              isDeviceTimeBaseRealtime() const;
+    uint32_t           getWidth() const;
+    uint32_t           getHeight() const;
+    int                getFormat() const;
+    android_dataspace  getDataSpace() const;
+    int32_t            getColorSpace() const;
+    uint64_t           getUsage() const;
+    void               setUsage(uint64_t usage);
+    void               setFormatOverride(bool formatOverridden);
+    bool               isFormatOverridden() const;
+    int                getOriginalFormat() const;
+    int64_t            getDynamicRangeProfile() const;
+    void               setDataSpaceOverride(bool dataSpaceOverridden);
+    bool               isDataSpaceOverridden() const;
+    android_dataspace  getOriginalDataSpace() const;
+    int                getMaxHalBuffers() const;
+    const std::string& physicalCameraId() const;
+    int64_t            getStreamUseCase() const;
+    int                getTimestampBase() const;
+    bool               isDeviceTimeBaseRealtime() const;
 
     void              setOfflineProcessingSupport(bool) override;
     bool              getOfflineProcessingSupport() const override;
@@ -487,7 +486,7 @@
      */
     const int mSetId;
 
-    const String8 mName;
+    const std::string mName;
     // Zero for formats with fixed buffer size for given dimensions.
     const size_t mMaxSize;
 
@@ -507,7 +506,7 @@
     Camera3Stream(int id, camera_stream_type type,
             uint32_t width, uint32_t height, size_t maxSize, int format,
             android_dataspace dataSpace, camera_stream_rotation_t rotation,
-            const String8& physicalCameraId,
+            const std::string& physicalCameraId,
             const std::unordered_set<int32_t> &sensorPixelModesUsed,
             int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
             int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -634,7 +633,7 @@
     bool mDataSpaceOverridden;
     const android_dataspace mOriginalDataSpace;
 
-    String8 mPhysicalCameraId;
+    std::string mPhysicalCameraId;
     nsecs_t mLastTimestamp;
 
     bool mIsMultiResolution = false;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 823be2e..7fa6273 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -62,7 +62,7 @@
     uint32_t max_buffers;
     android_dataspace_t data_space;
     camera_stream_rotation_t rotation;
-    const char* physical_camera_id;
+    std::string physical_camera_id;
 
     std::unordered_set<int32_t> sensor_pixel_modes_used;
     int64_t dynamic_range_profile;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index fd23958..8175eb5 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -25,6 +25,7 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/BufferQueue.h>
 #include <gui/Surface.h>
+#include <camera/StringUtils.h>
 
 #include <ui/GraphicBuffer.h>
 
@@ -92,7 +93,7 @@
     if (mBufferItemConsumer == nullptr) {
         return NO_MEMORY;
     }
-    mConsumer->setConsumerName(mConsumerName);
+    mConsumer->setConsumerName(toString8(mConsumerName));
 
     *consumer = new Surface(mProducer);
     if (*consumer == nullptr) {
@@ -408,9 +409,9 @@
     return res;
 }
 
-String8 Camera3StreamSplitter::getUniqueConsumerName() {
+std::string Camera3StreamSplitter::getUniqueConsumerName() {
     static volatile int32_t counter = 0;
-    return String8::format("Camera3StreamSplitter-%d", android_atomic_inc(&counter));
+    return fmt::sprintf("Camera3StreamSplitter-%d", android_atomic_inc(&counter));
 }
 
 status_t Camera3StreamSplitter::notifyBufferReleased(const sp<GraphicBuffer>& buffer) {
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 0f728a0..639353c 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -30,10 +30,10 @@
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
 
-#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
+#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
 
 namespace android {
 
@@ -222,7 +222,7 @@
             const BufferItem& bufferItem, size_t surfaceId);
 
     // Get unique name for the buffer queue consumer
-    String8 getUniqueConsumerName();
+    std::string getUniqueConsumerName();
 
     // Helper function to get the BufferQueue slot where a particular buffer is attached to.
     int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
@@ -289,7 +289,7 @@
     // Currently acquired input buffers
     size_t mAcquiredInputBuffers;
 
-    String8 mConsumerName;
+    std::string mConsumerName;
 
     const bool mUseHalBufManager;
 };
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index 870825a..665ac73 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -21,7 +21,6 @@
 
 #include <camera/CaptureResult.h>
 #include <camera/CameraMetadata.h>
-#include <utils/String8.h>
 #include <utils/Timers.h>
 
 #include "common/CameraDeviceBase.h"
@@ -168,7 +167,7 @@
     // For request on a physical camera stream, the inside set contains one Id
     // For request on a stream group containing physical camera streams, the
     // inside set contains all stream Ids in the group.
-    std::set<std::set<String8>> physicalCameraIds;
+    std::set<std::set<std::string>> physicalCameraIds;
 
     // Map of physicalCameraId <-> Metadata
     std::vector<PhysicalCaptureResultInfo> physicalMetadatas;
@@ -224,7 +223,7 @@
 
     InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
             bool hasAppCallback, nsecs_t minDuration, nsecs_t maxDuration, bool fixedFps,
-            const std::set<std::set<String8>>& physicalCameraIdSet, bool isStillCapture,
+            const std::set<std::set<std::string>>& physicalCameraIdSet, bool isStillCapture,
             bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
             const std::set<std::string>& idsWithZoom, nsecs_t requestNs,
             const SurfaceMap& outSurfaces = SurfaceMap{}) :
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index aa941b0..af48dd6 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -26,10 +26,10 @@
 #endif
 
 // Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
             ##__VA_ARGS__)
 
-#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
             ##__VA_ARGS__)
 
 // Convenience macros for transitioning to the error state
@@ -53,6 +53,7 @@
 #include <aidlcommonsupport/NativeHandle.h>
 #include <android/binder_ibinder_platform.h>
 #include <android/hardware/camera2/ICameraDeviceUser.h>
+#include <camera/StringUtils.h>
 
 #include "utils/CameraTraces.h"
 #include "mediautils/SchedulingPolicyService.h"
@@ -164,7 +165,7 @@
 
 AidlCamera3Device::AidlCamera3Device(
         std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
-        const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+        const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
         bool legacyClient) :
         Camera3Device(cameraServiceProxyWrapper, id, overrideForPerfClass, overrideToPortrait,
         legacyClient) {
@@ -172,12 +173,12 @@
 }
 
 status_t AidlCamera3Device::initialize(sp<CameraProviderManager> manager,
-        const String8& monitorTags) {
+        const std::string& monitorTags) {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.c_str());
     if (mStatus != STATUS_UNINITIALIZED) {
         CLOGE("Already initialized!");
         return INVALID_OPERATION;
@@ -186,7 +187,7 @@
 
     std::shared_ptr<camera::device::ICameraDeviceSession> session;
     ATRACE_BEGIN("CameraHal::openSession");
-    status_t res = manager->openAidlSession(mId.string(), mCallbacks,
+    status_t res = manager->openAidlSession(mId, mCallbacks,
             /*out*/ &session);
     ATRACE_END();
     if (res != OK) {
@@ -197,18 +198,18 @@
       SET_ERR("Session iface returned is null");
       return INVALID_OPERATION;
     }
-    res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo,
+    res = manager->getCameraCharacteristics(mId, mOverrideForPerfClass, &mDeviceInfo,
             mOverrideToPortrait);
     if (res != OK) {
         SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
         session->close();
         return res;
     }
-    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
-    mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId.string());
+    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId);
+    mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId);
 
     std::vector<std::string> physicalCameraIds;
-    bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+    bool isLogical = manager->isLogicalCamera(mId, &physicalCameraIds);
     if (isLogical) {
         for (auto& physicalId : physicalCameraIds) {
             // Do not override characteristics for physical cameras
@@ -299,10 +300,10 @@
     mInterface = new AidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
 
     std::string providerType;
-    mVendorTagId = manager->getProviderTagIdLocked(mId.string());
+    mVendorTagId = manager->getProviderTagIdLocked(mId);
     mTagMonitor.initialize(mVendorTagId);
-    if (!monitorTags.isEmpty()) {
-        mTagMonitor.parseTagsToMonitor(String8(monitorTags));
+    if (!monitorTags.empty()) {
+        mTagMonitor.parseTagsToMonitor(monitorTags);
     }
 
     for (size_t i = 0; i < capabilities.count; i++) {
@@ -922,7 +923,7 @@
         dst.colorSpace = src->color_space;
 
         dst.bufferSize = bufferSizes[i];
-        if (src->physical_camera_id != nullptr) {
+        if (!src->physical_camera_id.empty()) {
             dst.physicalCameraId = src->physical_camera_id;
         }
         dst.groupId = cam3stream->getHalStreamGroupId();
@@ -1100,7 +1101,7 @@
             mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
                     cam3stream->getOriginalDataSpace() : src->data_space);
         dst.bufferSize = bufferSizes[i];
-        if (src->physical_camera_id != nullptr) {
+        if (!src->physical_camera_id.empty()) {
             dst.physicalCameraId = src->physical_camera_id;
         }
         dst.groupId = cam3stream->getHalStreamGroupId();
@@ -1456,7 +1457,7 @@
 }
 
 status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::injectionInitialize(
-        const String8& injectedCamId, sp<CameraProviderManager> manager,
+        const std::string& injectedCamId, sp<CameraProviderManager> manager,
         const std::shared_ptr<camera::device::ICameraDeviceCallback>&callback) {
     ATRACE_CALL();
     Mutex::Autolock lock(mInjectionLock);
@@ -1480,7 +1481,7 @@
     mInjectedCamId = injectedCamId;
     std::shared_ptr<camera::device::ICameraInjectionSession> injectionSession;
     ATRACE_BEGIN("Injection CameraHal::openSession");
-    status_t res = manager->openAidlInjectionSession(injectedCamId.string(), callback,
+    status_t res = manager->openAidlInjectionSession(injectedCamId, callback,
                                           /*out*/ &injectionSession);
     ATRACE_END();
     if (res != OK) {
@@ -1579,7 +1580,7 @@
     return OK;
 }
 
-status_t AidlCamera3Device::injectionCameraInitialize(const String8 &injectedCamId,
+status_t AidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
             sp<CameraProviderManager> manager) {
         return (static_cast<AidlCamera3DeviceInjectionMethods *>
                     (mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
index 99a308b..e0be367 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
@@ -41,7 +41,7 @@
     friend class AidlCameraDeviceCallbacks;
     explicit AidlCamera3Device(
             std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
-            const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+            const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
             bool legacyClient = false);
 
     virtual ~AidlCamera3Device() { }
@@ -71,7 +71,7 @@
     virtual status_t switchToOffline(const std::vector<int32_t>& /*streamsToKeep*/,
             /*out*/ sp<CameraOfflineSessionBase>* /*session*/) override;
 
-    status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
+    status_t initialize(sp<CameraProviderManager> manager, const std::string& monitorTags) override;
     class AidlHalInterface : public Camera3Device::HalInterface {
      public:
         AidlHalInterface(std::shared_ptr<
@@ -196,7 +196,7 @@
      public:
         // Initialize the injection camera and generate an hal interface.
         status_t injectionInitialize(
-                const String8& injectedCamId, sp<CameraProviderManager> manager,
+                const std::string& injectedCamId, sp<CameraProviderManager> manager,
                 const std::shared_ptr<
                     aidl::android::hardware::camera::device::ICameraDeviceCallback>&
                     callback);
@@ -257,7 +257,7 @@
     };
 
   private:
-    virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+    virtual status_t injectionCameraInitialize(const std::string &injectCamId,
             sp<CameraProviderManager> manager) override;
 
     virtual sp<RequestThread> createNewRequestThread(wp<Camera3Device> parent,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
index 3c3db97..01c4e88 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
@@ -31,6 +31,7 @@
 
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
 #include <android/binder_ibinder_platform.h>
+#include <camera/StringUtils.h>
 
 #include "device3/aidl/AidlCamera3OfflineSession.h"
 #include "device3/Camera3OutputStream.h"
@@ -47,7 +48,7 @@
 
 AidlCamera3OfflineSession::~AidlCamera3OfflineSession() {
     ATRACE_CALL();
-    ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.c_str());
     Camera3OfflineSession::disconnectImpl();
 }
 
@@ -113,7 +114,7 @@
 
     std::string activePhysicalId(""); // Unused
     AidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mOfflineReqsLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -160,7 +161,7 @@
 
     std::string activePhysicalId(""); // Unused
     AidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mOfflineReqsLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
index b31ffb7..33b638c 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
@@ -20,7 +20,6 @@
 #include <memory>
 #include <mutex>
 
-#include <utils/String8.h>
 #include <utils/String16.h>
 
 #include "AidlCamera3OutputUtils.h"
@@ -106,7 +105,7 @@
     };
 
     // initialize by Camera3Device.
-    explicit AidlCamera3OfflineSession(const String8& id,
+    explicit AidlCamera3OfflineSession(const std::string& id,
             const sp<camera3::Camera3Stream>& inputStream,
             const camera3::StreamSet& offlineStreamSet,
             camera3::BufferRecords&& bufferRecords,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
index b2accc1..74d4230 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
@@ -145,7 +145,7 @@
     outBuffers->clear();
     if (!states.useHalBufManager) {
         ALOGE("%s: Camera %s does not support HAL buffer management",
-                __FUNCTION__, states.cameraId.string());
+                __FUNCTION__, states.cameraId.c_str());
         *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
         return;
     }
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 0d44dd5..06af5ff 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -26,7 +26,7 @@
 #endif
 
 // Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
             ##__VA_ARGS__)
 
 // Convenience macros for transitioning to the error state
@@ -46,6 +46,7 @@
 #include <utils/Trace.h>
 #include <utils/Timers.h>
 #include <cutils/properties.h>
+#include <camera/StringUtils.h>
 
 #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
 #include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -140,12 +141,12 @@
 }
 
 status_t HidlCamera3Device::initialize(sp<CameraProviderManager> manager,
-        const String8& monitorTags) {
+        const std::string& monitorTags) {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.c_str());
     if (mStatus != STATUS_UNINITIALIZED) {
         CLOGE("Already initialized!");
         return INVALID_OPERATION;
@@ -154,7 +155,7 @@
 
     sp<ICameraDeviceSession> session;
     ATRACE_BEGIN("CameraHal::openSession");
-    status_t res = manager->openHidlSession(mId.string(), this,
+    status_t res = manager->openHidlSession(mId, this,
             /*out*/ &session);
     ATRACE_END();
     if (res != OK) {
@@ -162,17 +163,17 @@
         return res;
     }
 
-    res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo,
+    res = manager->getCameraCharacteristics(mId, mOverrideForPerfClass, &mDeviceInfo,
             /*overrideToPortrait*/false);
     if (res != OK) {
         SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
         session->close();
         return res;
     }
-    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
+    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId);
 
     std::vector<std::string> physicalCameraIds;
-    bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+    bool isLogical = manager->isLogicalCamera(mId, &physicalCameraIds);
     if (isLogical) {
         for (auto& physicalId : physicalCameraIds) {
             // Do not override characteristics for physical cameras
@@ -271,17 +272,17 @@
     mInterface = new HidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
 
     std::string providerType;
-    mVendorTagId = manager->getProviderTagIdLocked(mId.string());
+    mVendorTagId = manager->getProviderTagIdLocked(mId);
     mTagMonitor.initialize(mVendorTagId);
-    if (!monitorTags.isEmpty()) {
-        mTagMonitor.parseTagsToMonitor(String8(monitorTags));
+    if (!monitorTags.empty()) {
+        mTagMonitor.parseTagsToMonitor(monitorTags);
     }
 
     // Metadata tags needs fixup for monochrome camera device version less
     // than 3.5.
     hardware::hidl_version maxVersion{0,0};
     IPCTransport transport = IPCTransport::HIDL;
-    res = manager->getHighestSupportedVersion(mId.string(), &maxVersion, &transport);
+    res = manager->getHighestSupportedVersion(mId, &maxVersion, &transport);
     if (res != OK) {
         ALOGE("%s: Error in getting camera device version id: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
@@ -416,7 +417,7 @@
     }
 
     HidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mInFlightLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mInFlightMap, mOutputLock,  mResultQueue, mResultSignal,
@@ -464,7 +465,7 @@
     }
 
     HidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mInFlightLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mInFlightMap, mOutputLock,  mResultQueue, mResultSignal,
@@ -715,7 +716,7 @@
     return new HidlCamera3DeviceInjectionMethods(parent);
 }
 
-status_t HidlCamera3Device::injectionCameraInitialize(const String8 &injectedCamId,
+status_t HidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
             sp<CameraProviderManager> manager) {
         return (static_cast<HidlCamera3DeviceInjectionMethods *>(
                 mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager, this);
@@ -941,7 +942,7 @@
         }
         dst3_4.v3_2 = dst3_2;
         dst3_4.bufferSize = bufferSizes[i];
-        if (src->physical_camera_id != nullptr) {
+        if (!src->physical_camera_id.empty()) {
             dst3_4.physicalCameraId = src->physical_camera_id;
         }
         dst3_7.v3_4 = dst3_4;
@@ -1259,7 +1260,7 @@
         }
         dst3_4.v3_2 = dst3_2;
         dst3_4.bufferSize = bufferSizes[i];
-        if (src->physical_camera_id != nullptr) {
+        if (!src->physical_camera_id.empty()) {
             dst3_4.physicalCameraId = src->physical_camera_id;
         }
         dst3_7.v3_4 = dst3_4;
@@ -1739,7 +1740,7 @@
 }
 
 status_t HidlCamera3Device::HidlCamera3DeviceInjectionMethods::injectionInitialize(
-        const String8& injectedCamId, sp<CameraProviderManager> manager,
+        const std::string& injectedCamId, sp<CameraProviderManager> manager,
         const sp<android::hardware::camera::device::V3_2::ICameraDeviceCallback>&
                 callback) {
     ATRACE_CALL();
@@ -1759,7 +1760,7 @@
     mInjectedCamId = injectedCamId;
     sp<ICameraDeviceSession> session;
     ATRACE_BEGIN("Injection CameraHal::openSession");
-    status_t res = manager->openHidlSession(injectedCamId.string(), callback,
+    status_t res = manager->openHidlSession(injectedCamId, callback,
                                           /*out*/ &session);
     ATRACE_END();
     if (res != OK) {
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
index 1e50844..2cfdf9d 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
@@ -31,8 +31,9 @@
             public Camera3Device {
   public:
 
-   explicit HidlCamera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
-        const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+    explicit HidlCamera3Device(
+        std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
+        const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
         bool legacyClient = false) :
         Camera3Device(cameraServiceProxyWrapper, id, overrideForPerfClass, overrideToPortrait,
                 legacyClient) { }
@@ -59,7 +60,7 @@
     static uint64_t mapProducerToFrameworkUsage(
             hardware::camera::device::V3_2::BufferUsageFlags usage);
 
-    status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
+    status_t initialize(sp<CameraProviderManager> manager, const std::string& monitorTags) override;
 
     /**
      * Implementation of android::hardware::camera::device::V3_5::ICameraDeviceCallback
@@ -191,7 +192,7 @@
      public:
         // Initialize the injection camera and generate an hal interface.
         status_t injectionInitialize(
-                const String8& injectedCamId, sp<CameraProviderManager> manager,
+                const std::string& injectedCamId, sp<CameraProviderManager> manager,
                 const sp<
                     android::hardware::camera::device::V3_2 ::ICameraDeviceCallback>&
                     callback);
@@ -217,7 +218,7 @@
     hardware::Return<void> notifyHelper(
             const hardware::hidl_vec<NotifyMsgType>& msgs);
 
-    virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+    virtual status_t injectionCameraInitialize(const std::string &injectCamId,
             sp<CameraProviderManager> manager) override;
 
     virtual sp<RequestThread> createNewRequestThread(wp<Camera3Device> parent,
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
index 28b2b47..e328ef6 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
@@ -23,6 +23,7 @@
 #include <utils/Trace.h>
 
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <camera/StringUtils.h>
 
 #include "device3/hidl/HidlCamera3OfflineSession.h"
 #include "device3/Camera3OutputStream.h"
@@ -38,7 +39,7 @@
 
 HidlCamera3OfflineSession::~HidlCamera3OfflineSession() {
     ATRACE_CALL();
-    ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.string());
+    ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.c_str());
     Camera3OfflineSession::disconnectImpl();
 }
 
@@ -94,7 +95,7 @@
 
     std::string activePhysicalId("");
     HidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mOfflineReqsLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -136,7 +137,7 @@
 
     std::string activePhysicalId("");
     HidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mOfflineReqsLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -173,7 +174,7 @@
 
     std::string activePhysicalId("");
     HidlCaptureOutputStates states {
-      {mId,
+      { mId,
         mOfflineReqsLock, mLastCompletedRegularFrameNumber,
         mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
         mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
index d22a447..df306b2 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
@@ -20,7 +20,6 @@
 #include <memory>
 #include <mutex>
 
-#include <utils/String8.h>
 #include <utils/String16.h>
 
 #include <android/hardware/camera/device/3.6/ICameraOfflineSession.h>
@@ -53,7 +52,7 @@
   public:
 
     // initialize by Camera3Device.
-    explicit HidlCamera3OfflineSession(const String8& id,
+    explicit HidlCamera3OfflineSession(const std::string& id,
             const sp<camera3::Camera3Stream>& inputStream,
             const camera3::StreamSet& offlineStreamSet,
             camera3::BufferRecords&& bufferRecords,
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index ee018c3..5dbfb36 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -23,12 +23,13 @@
 #include <utils/Log.h>
 
 #include <gui/RingBufferConsumer.h>
+#include <camera/StringUtils.h>
 
-#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 #undef assert
 #define assert(x) ALOG_ASSERT((x), #x)
@@ -53,10 +54,10 @@
 RingBufferConsumer::~RingBufferConsumer() {
 }
 
-void RingBufferConsumer::setName(const String8& name) {
+void RingBufferConsumer::setName(const std::string& name) {
     Mutex::Autolock _l(mMutex);
-    mName = name;
-    mConsumer->setConsumerName(name);
+    mName = toString8(name);
+    mConsumer->setConsumerName(mName);
 }
 
 sp<PinnedBufferItem> RingBufferConsumer::pinSelectedBuffer(
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h
index b737469..2e523d1 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.h
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h
@@ -27,8 +27,6 @@
 
 namespace android {
 
-class String8;
-
 /**
  * The RingBufferConsumer maintains a ring buffer of BufferItem objects,
  * (which are 'acquired' as long as they are part of the ring buffer, and
@@ -67,7 +65,7 @@
 
     // set the name of the RingBufferConsumer that will be used to identify it in
     // log messages.
-    void setName(const String8& name);
+    void setName(const std::string& name);
 
     // setDefaultBufferSize is used to set the size of buffers returned by
     // requestBuffers when a with and height of zero is requested.
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
index add9121..2b81224 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -16,6 +16,7 @@
 
 #include <hidl/AidlCameraServiceListener.h>
 #include <hidl/Utils.h>
+#include <camera/StringUtils.h>
 
 namespace android {
 namespace frameworks {
@@ -28,11 +29,11 @@
 typedef frameworks::cameraservice::service::V2_1::ICameraServiceListener HCameraServiceListener2_1;
 
 binder::Status H2BCameraServiceListener::onStatusChanged(
-    int32_t status, const ::android::String16& cameraId) {
+    int32_t status, const std::string& cameraId) {
   HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
   CameraStatusAndId cameraStatusAndId;
   cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
-  cameraStatusAndId.cameraId = String8(cameraId).string();
+  cameraStatusAndId.cameraId = cameraId;
   auto ret = mBase->onStatusChanged(cameraStatusAndId);
   if (!ret.isOk()) {
       ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
@@ -42,8 +43,8 @@
 }
 
 binder::Status H2BCameraServiceListener::onPhysicalCameraStatusChanged(
-    int32_t status, const ::android::String16& cameraId,
-    const ::android::String16& physicalCameraId) {
+    int32_t status, const std::string& cameraId,
+    const std::string& physicalCameraId) {
   auto cast2_1 = HCameraServiceListener2_1::castFrom(mBase);
   sp<HCameraServiceListener2_1> interface2_1 = nullptr;
   if (cast2_1.isOk()) {
@@ -52,8 +53,8 @@
       HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
       V2_1::PhysicalCameraStatusAndId cameraStatusAndId;
       cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
-      cameraStatusAndId.cameraId = String8(cameraId).string();
-      cameraStatusAndId.physicalCameraId = String8(physicalCameraId).string();
+      cameraStatusAndId.cameraId = cameraId;
+      cameraStatusAndId.physicalCameraId = physicalCameraId;
       auto ret = interface2_1->onPhysicalCameraStatusChanged(cameraStatusAndId);
       if (!ret.isOk()) {
         ALOGE("%s OnPhysicalCameraStatusChanged callback failed due to %s",__FUNCTION__,
@@ -65,13 +66,13 @@
 }
 
 ::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
-    int32_t, const ::android::String16&) {
+    int32_t, const std::string&) {
   // We don't implement onTorchStatusChanged
   return binder::Status::ok();
 }
 
 ::android::binder::Status H2BCameraServiceListener::onTorchStrengthLevelChanged(
-    const ::android::String16&, int32_t) {
+    const std::string&, int32_t) {
   return binder::Status::ok();
 }
 
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 7ef413f..91a4c16 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -47,25 +47,25 @@
     ~H2BCameraServiceListener() { }
 
     virtual ::android::binder::Status onStatusChanged(int32_t status,
-            const ::android::String16& cameraId) override;
+            const std::string& cameraId) override;
     virtual ::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
-            const ::android::String16& cameraId,
-            const ::android::String16& physicalCameraId) override;
+            const std::string& cameraId,
+            const std::string& physicalCameraId) override;
 
     virtual ::android::binder::Status onTorchStatusChanged(
-            int32_t status, const ::android::String16& cameraId) override;
+            int32_t status, const std::string& cameraId) override;
     virtual ::android::binder::Status onTorchStrengthLevelChanged(
-            const ::android::String16& cameraId, int32_t newStrengthLevel) override;
+            const std::string& cameraId, int32_t newStrengthLevel) override;
     virtual binder::Status onCameraAccessPrioritiesChanged() {
         // TODO: no implementation yet.
         return binder::Status::ok();
     }
-    virtual binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
-            const ::android::String16& /*clientPackageId*/) {
+    virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+            const std::string& /*clientPackageId*/) {
         // empty implementation
         return binder::Status::ok();
     }
-    virtual binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) {
+    virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
         // empty implementation
         return binder::Status::ok();
     }
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
index 0f7f127..59fc1cd 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -112,7 +112,7 @@
         physicalCameraSettings->emplace_back();
         CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
             physicalCameraSettings->back();
-        physicalCameraSetting.id = e.id.c_str();
+        physicalCameraSetting.id = e.id;
 
         // Read the settings either from the fmq or straightaway from the
         // request. We don't need any synchronization, since submitRequestList
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index d6910fe..94bf653 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -65,7 +65,7 @@
     android::CameraMetadata cameraMetadata;
     HStatus status = HStatus::NO_ERROR;
     binder::Status serviceRet =
-        mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
+        mAidlICameraService->getCameraCharacteristics(cameraId,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
                 &cameraMetadata);
     HCameraMetadata hidlMetadata;
@@ -78,7 +78,7 @@
                 break;
             default:
                 ALOGE("Get camera characteristics from camera service failed: %s",
-                      serviceRet.toString8().string());
+                      serviceRet.toString8().c_str());
                 status = B2HStatus(serviceRet);
           }
         _hidl_cb(status, hidlMetadata);
@@ -116,7 +116,7 @@
     }
     sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
     binder::Status serviceRet = mAidlICameraService->connectDevice(
-            callbacks, String16(cameraId.c_str()), String16(""), {},
+            callbacks, cameraId, std::string(), {},
             hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
             /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
             /*out*/&deviceRemote);
@@ -242,7 +242,7 @@
             [this](const hardware::CameraStatus& s) {
                 bool supportsHAL3 = false;
                 binder::Status sRet =
-                            mAidlICameraService->supportsCameraApi(String16(s.cameraId),
+                            mAidlICameraService->supportsCameraApi(s.cameraId,
                                     hardware::ICameraService::API_VERSION_2, &supportsHAL3);
                 return !sRet.isOk() || !supportsHAL3;
             }), cameraStatusAndIds->end());
@@ -307,7 +307,7 @@
         }
         hVendorTagSections.resize(numSections);
         for (size_t s = 0; s < numSections; s++) {
-            hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
+            hVendorTagSections[s].sectionName = (*sectionNames)[s].c_str();
             hVendorTagSections[s].tags = tagsBySection[s];
         }
         HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
diff --git a/services/camera/libcameraservice/hidl/Utils.cpp b/services/camera/libcameraservice/hidl/Utils.cpp
index 2a24a23..b5dddf7 100644
--- a/services/camera/libcameraservice/hidl/Utils.cpp
+++ b/services/camera/libcameraservice/hidl/Utils.cpp
@@ -18,6 +18,7 @@
 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
 #include <cutils/native_handle.h>
 #include <mediautils/AImageReaderUtils.h>
+#include <camera/StringUtils.h>
 
 namespace android {
 namespace hardware {
@@ -89,9 +90,9 @@
     for (auto &handle : windowHandles) {
         iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(handle)));
     }
-    String16 physicalCameraId16(hOutputConfiguration.physicalCameraId.c_str());
     hardware::camera2::params::OutputConfiguration outputConfiguration(
-        iGBPs, convertFromHidl(hOutputConfiguration.rotation), physicalCameraId16,
+        iGBPs, convertFromHidl(hOutputConfiguration.rotation),
+        hOutputConfiguration.physicalCameraId,
         hOutputConfiguration.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
         (windowHandles.size() > 1));
     return outputConfiguration;
@@ -157,8 +158,8 @@
     hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber;
     hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount;
     hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId;
-    hCaptureResultExtras.errorPhysicalCameraId = hidl_string(String8(
-            captureResultExtras.errorPhysicalCameraId).string());
+    hCaptureResultExtras.errorPhysicalCameraId = hidl_string(
+            captureResultExtras.errorPhysicalCameraId.c_str());
     return hCaptureResultExtras;
 }
 
@@ -191,7 +192,7 @@
     size_t i = 0;
     for (auto &statusAndId : src) {
         auto &a = (*dst)[i++];
-        a.cameraId = statusAndId.cameraId.c_str();
+        a.cameraId = statusAndId.cameraId;
         a.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
     }
     return;
@@ -203,12 +204,12 @@
     size_t i = 0;
     for (const auto &statusAndId : src) {
         auto &a = (*dst)[i++];
-        a.v2_0.cameraId = statusAndId.cameraId.c_str();
+        a.v2_0.cameraId = statusAndId.cameraId;
         a.v2_0.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
         size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
         a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
         for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
-            a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
+            a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
         }
     }
     return;
@@ -265,7 +266,7 @@
     std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
     HPhysicalCaptureResultInfo hPhysicalCaptureResultInfo;
     hPhysicalCaptureResultInfo.physicalCameraId =
-        String8(physicalCaptureResultInfo.mPhysicalCameraId).string();
+        toString8(physicalCaptureResultInfo.mPhysicalCameraId);
     const camera_metadata_t *rawMetadata =
         physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
     // Try using fmq at first.
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index b397573..854c342 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -219,13 +219,13 @@
 }
 
 void CameraFuzzer::getCameraInformation(int32_t cameraId) {
-    String16 cameraIdStr = String16(String8::format("%d", cameraId));
+    std::string cameraIdStr = std::to_string(cameraId);
     bool isSupported = false;
     mCameraService->supportsCameraApi(
         cameraIdStr, kCameraApiVersion[mFuzzedDataProvider->ConsumeBool()], &isSupported);
     mCameraService->isHiddenPhysicalCamera(cameraIdStr, &isSupported);
 
-    String16 parameters;
+    std::string parameters;
     mCameraService->getLegacyParameters(cameraId, &parameters);
 
     std::vector<hardware::camera2::utils::ConcurrentCameraIdCombination> concurrentCameraIds;
@@ -318,7 +318,7 @@
 }
 
 void CameraFuzzer::invokeTorchAPIs(int32_t cameraId) {
-    String16 cameraIdStr = String16(String8::format("%d", cameraId));
+    std::string cameraIdStr = std::to_string(cameraId);
     sp<IBinder> binder = new BBinder;
 
     mCameraService->setTorchMode(cameraIdStr, true, binder);
@@ -342,7 +342,7 @@
     ::android::binder::Status rc;
     sp<ICamera> cameraDevice;
 
-    rc = mCameraService->connect(this, cameraId, String16(),
+    rc = mCameraService->connect(this, cameraId, std::string(),
                                  android::CameraService::USE_CALLING_UID,
                                  android::CameraService::USE_CALLING_PID,
                                  /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
@@ -484,17 +484,18 @@
 public:
     virtual ~TestCameraServiceListener() {};
 
-    virtual binder::Status onStatusChanged(int32_t , const String16&) {
+    virtual binder::Status onStatusChanged(int32_t, const std::string&) {
         return binder::Status::ok();
     };
 
     virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
-            const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+            const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
         // No op
         return binder::Status::ok();
     };
 
-    virtual binder::Status onTorchStatusChanged(int32_t /*status*/, const String16& /*cameraId*/) {
+    virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
+            const std::string& /*cameraId*/) {
         return binder::Status::ok();
     };
 
@@ -503,18 +504,18 @@
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
-            const String16& /*clientPackageName*/) {
+    virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+            const std::string& /*clientPackageName*/) {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+    virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+    virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
             int32_t /*torchStrength*/) {
         // No op
         return binder::Status::ok();
@@ -579,7 +580,7 @@
     for (auto s : statuses) {
         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
         sp<hardware::camera2::ICameraDeviceUser> device;
-        mCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+        mCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/true,
                 &device);
@@ -600,7 +601,7 @@
 
         sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
 
-        String16 noPhysicalId;
+        std::string noPhysicalId;
         size_t rotations = sizeof(kRotations) / sizeof(int32_t) - 1;
         OutputConfiguration output(gbProducer,
                 kRotations[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, rotations)],
@@ -626,9 +627,9 @@
                     kSensorPixelModes[mFuzzedDataProvider->ConsumeBool() ? 1 : 0];
             requestTemplate.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1);
             request.mPhysicalCameraSettings.clear();
-            request.mPhysicalCameraSettings.push_back({s.cameraId.string(), requestTemplate});
+            request.mPhysicalCameraSettings.push_back({s.cameraId, requestTemplate});
             device->submitRequest(request, /*streaming*/false, /*out*/&info);
-            ALOGV("%s : camera id %s submit request id %d",__FUNCTION__, s.cameraId.string(),
+            ALOGV("%s : camera id %s submit request id %d",__FUNCTION__, s.cameraId.c_str(),
                     info.mRequestId);
         }
         device->disconnect();
diff --git a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
index 731eebf..db43a02 100644
--- a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
@@ -37,17 +37,18 @@
 public:
     virtual ~TestCameraServiceListener() {};
 
-    virtual binder::Status onStatusChanged(int32_t , const String16&) {
+    virtual binder::Status onStatusChanged(int32_t , const std::string&) {
         return binder::Status::ok();
     };
 
     virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
-            const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+            const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
         // No op
         return binder::Status::ok();
     };
 
-    virtual binder::Status onTorchStatusChanged(int32_t /*status*/, const String16& /*cameraId*/) {
+    virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
+            const std::string& /*cameraId*/) {
         return binder::Status::ok();
     };
 
@@ -56,18 +57,18 @@
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
-            const String16& /*clientPackageName*/) {
+    virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+            const std::string& /*clientPackageName*/) {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+    virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
         // No op
         return binder::Status::ok();
     }
 
-    virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+    virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
             int32_t /*torchStrength*/) {
         // No op
         return binder::Status::ok();
@@ -123,13 +124,13 @@
             mCameraDisabled(false), mOverrideCameraDisabled(false)
     { }
 
-    virtual binder::Status getRotateAndCropOverride(const String16& packageName, int lensFacing,
+    virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
             int userId, int *ret) override {
         return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
                 userId, ret);
     }
 
-    virtual binder::Status getAutoframingOverride(const String16& packageName, int *ret) override {
+    virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
         return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
     }
 
@@ -224,7 +225,7 @@
         sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
         sp<hardware::camera2::ICameraDeviceUser> device;
         binder::Status status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
         AutoDisconnectDevice autoDisconnect(device);
@@ -238,7 +239,7 @@
         sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
         sp<hardware::camera2::ICameraDeviceUser> device;
         binder::Status status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
         AutoDisconnectDevice autoDisconnect(device);
@@ -257,14 +258,14 @@
         sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
         sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
         binder::Status status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
         AutoDisconnectDevice autoDisconnectA(deviceA);
         ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
                 " service specific error code " << status.serviceSpecificErrorCode();
         status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
         AutoDisconnectDevice autoDisconnectB(deviceB);
@@ -285,14 +286,14 @@
         sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
         sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
         binder::Status status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
         AutoDisconnectDevice autoDisconnectA(deviceA);
         ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
                 " service specific error code " << status.serviceSpecificErrorCode();
         status =
-                sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+                sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
                 android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
         AutoDisconnectDevice autoDisconnectB(deviceB);
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index 1a6b2e0..c0cd1a9 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -302,15 +302,15 @@
 
     ~TestStatusListener() {}
 
-    void onDeviceStatusChanged(const String8 &,
+    void onDeviceStatusChanged(const std::string &,
             CameraDeviceStatus) override {}
-    void onDeviceStatusChanged(const String8 &, const String8 &,
+    void onDeviceStatusChanged(const std::string &, const std::string &,
             CameraDeviceStatus) override {
         mPhysicalCameraStatusChangeCount++;
     }
-    void onTorchStatusChanged(const String8 &,
+    void onTorchStatusChanged(const std::string &,
             TorchModeStatus) override {}
-    void onTorchStatusChanged(const String8 &,
+    void onTorchStatusChanged(const std::string &,
             TorchModeStatus, SystemCameraKind) override {}
     void onNewProviderRegistered() override {}
 };
diff --git a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
index b367571..33cc61a 100644
--- a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
+++ b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
@@ -19,8 +19,8 @@
 
 #include <random>
 
+#include <fmt/printf.h>
 #include <gtest/gtest.h>
-#include <android-base/stringprintf.h>
 #include <android-base/chrono_utils.h>
 
 #include "../device3/DistortionMapper.h"
@@ -260,9 +260,9 @@
                 rawToCorrectedDurationMs) / (randCoords.size() / 2) ).count();
 
     test->RecordProperty("CorrectedToRawDurationPerCoordUs",
-            base::StringPrintf("%f", correctedToRawDurationPerCoordUs));
+            fmt::sprintf("%f", correctedToRawDurationPerCoordUs));
     test->RecordProperty("RawToCorrectedDurationPerCoordUs",
-            base::StringPrintf("%f", rawToCorrectedDurationPerCoordUs));
+            fmt::sprintf("%f", rawToCorrectedDurationPerCoordUs));
 
     // Calculate mapping errors after round trip
     float totalErrorSq = 0;
@@ -296,9 +296,9 @@
     }
 
     float rmsError = std::sqrt(totalErrorSq / randCoords.size());
-    test->RecordProperty("RmsError", base::StringPrintf("%f", rmsError));
+    test->RecordProperty("RmsError", fmt::sprintf("%f", rmsError));
     for (size_t i = 0; i < histogram.size(); i++) {
-        std::string label = base::StringPrintf("HistogramBin[%f,%f)",
+        std::string label = fmt::sprintf("HistogramBin[%f,%f)",
                 (float)i/bucketsPerPixel, (float)(i + 1)/bucketsPerPixel);
         test->RecordProperty(label, histogram[i]);
     }
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index b58975f..d07bf6d 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -20,6 +20,8 @@
 
 #include <inttypes.h>
 #include <utils/Log.h>
+#include <utils/String16.h>
+#include <camera/StringUtils.h>
 #include <binder/IServiceManager.h>
 
 #include "CameraServiceProxyWrapper.h"
@@ -32,7 +34,7 @@
 
 namespace {
 // Sentinel value to be returned when extension session with a stale or invalid key is reported.
-const String16 POISON_EXT_STATS_KEY("poisoned_stats");
+const std::string POISON_EXT_STATS_KEY("poisoned_stats");
 } // anonymous namespace
 
 /**
@@ -100,7 +102,7 @@
     mSessionStats.mRequestCount = requestCount;
     mSessionStats.mResultErrorCount = resultErrorCount;
     mSessionStats.mDeviceError = deviceError;
-    mSessionStats.mUserTag = String16(userTag.c_str());
+    mSessionStats.mUserTag = userTag;
     mSessionStats.mVideoStabilizationMode = videoStabilizationMode;
     mSessionStats.mStreamStats = streamStats;
 
@@ -116,14 +118,14 @@
     return mSessionStats.mLogId;
 }
 
-String16 CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateExtensionSessionStats(
+std::string CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateExtensionSessionStats(
         const hardware::CameraExtensionSessionStats& extStats) {
     Mutex::Autolock l(mLock);
     CameraExtensionSessionStats& currStats = mSessionStats.mCameraExtensionSessionStats;
     if (currStats.key != extStats.key) {
         // Mismatched keys. Extensions stats likely reported for a closed session
         ALOGW("%s: mismatched extensions stats key: current='%s' reported='%s'. Dropping stats.",
-              __FUNCTION__, String8(currStats.key).c_str(), String8(extStats.key).c_str());
+              __FUNCTION__, toStdString(currStats.key).c_str(), toStdString(extStats.key).c_str());
         return POISON_EXT_STATS_KEY; // return poisoned key to so future calls are
                                      // definitely dropped.
     }
@@ -134,15 +136,15 @@
         ALOGV("%s: Overwriting extension session stats: %s", __FUNCTION__,
               extStats.toString().c_str());
         currStats = extStats;
-        return currStats.key;
+        return toStdString(currStats.key);
     }
 
     // Matching empty keys...
-    if (mSessionStats.mClientName != extStats.clientName) {
+    if (mSessionStats.mClientName != toStdString(extStats.clientName)) {
         ALOGW("%s: extension stats reported for unexpected package: current='%s' reported='%s'. "
               "Dropping stats.", __FUNCTION__,
-              String8(mSessionStats.mClientName).c_str(),
-              String8(extStats.clientName).c_str());
+              mSessionStats.mClientName.c_str(),
+              toStdString(extStats.clientName).c_str());
         return POISON_EXT_STATS_KEY;
     }
 
@@ -166,12 +168,12 @@
         key << mSessionStats.mSessionIndex << '/' << mSessionStats.mLogId;
         currStats.key = String16(key.str().c_str());
         ALOGV("%s: New extension session stats: %s", __FUNCTION__, currStats.toString().c_str());
-        return currStats.key;
+        return toStdString(currStats.key);
     }
 
     // Camera is closed. Probably a stale call.
     ALOGW("%s: extension stats reported for closed camera id '%s'. Dropping stats.",
-          __FUNCTION__, String8(mSessionStats.mCameraId).c_str());
+          __FUNCTION__, mSessionStats.mCameraId.c_str());
     return {};
 }
 
@@ -209,12 +211,13 @@
     proxyBinder->pingForUserUpdate();
 }
 
-int CameraServiceProxyWrapper::getRotateAndCropOverride(String16 packageName, int lensFacing,
-        int userId) {
+int CameraServiceProxyWrapper::getRotateAndCropOverride(const std::string &packageName,
+        int lensFacing, int userId) {
     sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
     if (proxyBinder == nullptr) return true;
     int ret = 0;
-    auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing, userId, &ret);
+    auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing,
+            userId, &ret);
     if (!status.isOk()) {
         ALOGE("%s: Failed during top activity orientation query: %s", __FUNCTION__,
                 status.exceptionMessage().c_str());
@@ -223,7 +226,7 @@
     return ret;
 }
 
-int CameraServiceProxyWrapper::getAutoframingOverride(const String16& packageName) {
+int CameraServiceProxyWrapper::getAutoframingOverride(const std::string& packageName) {
     sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
     if (proxyBinder == nullptr) {
         return ANDROID_CONTROL_AUTOFRAMING_OFF;
@@ -238,7 +241,7 @@
     return ret;
 }
 
-void CameraServiceProxyWrapper::logStreamConfigured(const String8& id,
+void CameraServiceProxyWrapper::logStreamConfigured(const std::string& id,
         int operatingMode, bool internalConfig, int32_t latencyMs) {
     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
     {
@@ -256,7 +259,7 @@
     sessionStats->onStreamConfigured(operatingMode, internalConfig, latencyMs);
 }
 
-void CameraServiceProxyWrapper::logActive(const String8& id, float maxPreviewFps) {
+void CameraServiceProxyWrapper::logActive(const std::string& id, float maxPreviewFps) {
     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
     {
         Mutex::Autolock l(mLock);
@@ -273,7 +276,7 @@
     sessionStats->onActive(proxyBinder, maxPreviewFps);
 }
 
-void CameraServiceProxyWrapper::logIdle(const String8& id,
+void CameraServiceProxyWrapper::logIdle(const std::string& id,
         int64_t requestCount, int64_t resultErrorCount, bool deviceError,
         const std::string& userTag, int32_t videoStabilizationMode,
         const std::vector<hardware::CameraStreamStats>& streamStats) {
@@ -304,8 +307,8 @@
             videoStabilizationMode, streamStats);
 }
 
-void CameraServiceProxyWrapper::logOpen(const String8& id, int facing,
-            const String16& clientPackageName, int effectiveApiLevel, bool isNdk,
+void CameraServiceProxyWrapper::logOpen(const std::string& id, int facing,
+            const std::string& clientPackageName, int effectiveApiLevel, bool isNdk,
             int32_t latencyMs) {
     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
     {
@@ -325,7 +328,7 @@
         int64_t logId = generateLogId(mRandomDevice);
 
         sessionStats = std::make_shared<CameraSessionStatsWrapper>(
-                String16(id), facing, CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
+                id, facing, CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
                 apiLevel, isNdk, latencyMs, logId);
         mSessionStatsMap.emplace(id, sessionStats);
         ALOGV("%s: Adding id %s", __FUNCTION__, id.c_str());
@@ -337,7 +340,8 @@
     sessionStats->onOpen(proxyBinder);
 }
 
-void CameraServiceProxyWrapper::logClose(const String8& id, int32_t latencyMs, bool deviceError) {
+void CameraServiceProxyWrapper::logClose(const std::string& id, int32_t latencyMs,
+        bool deviceError) {
     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
     {
         Mutex::Autolock l(mLock);
@@ -376,7 +380,7 @@
     return ret;
 }
 
-int64_t CameraServiceProxyWrapper::getCurrentLogIdForCamera(const String8& cameraId) {
+int64_t CameraServiceProxyWrapper::getCurrentLogIdForCamera(const std::string& cameraId) {
     std::shared_ptr<CameraSessionStatsWrapper> stats;
     {
         Mutex::Autolock _l(mLock);
@@ -403,10 +407,10 @@
     return ret;
 }
 
-String16 CameraServiceProxyWrapper::updateExtensionStats(
+std::string CameraServiceProxyWrapper::updateExtensionStats(
         const hardware::CameraExtensionSessionStats& extStats) {
     std::shared_ptr<CameraSessionStatsWrapper> stats;
-    String8 cameraId = String8(extStats.cameraId);
+    std::string cameraId = toStdString(extStats.cameraId);
     {
         Mutex::Autolock _l(mLock);
         if (mSessionStatsMap.count(cameraId) == 0) {
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index e32580c..1afe5b3 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -20,11 +20,10 @@
 #include <android/hardware/ICameraServiceProxy.h>
 
 #include <utils/Mutex.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
 #include <random>
+#include <string>
 
 #include <camera/CameraSessionStats.h>
 
@@ -49,8 +48,8 @@
         void updateProxyDeviceState(sp<hardware::ICameraServiceProxy>& proxyBinder);
 
       public:
-        CameraSessionStatsWrapper(const String16& cameraId, int facing, int newCameraState,
-                                  const String16& clientName, int apiLevel, bool isNdk,
+        CameraSessionStatsWrapper(const std::string& cameraId, int facing, int newCameraState,
+                                  const std::string& clientName, int apiLevel, bool isNdk,
                                   int32_t latencyMs, int64_t logId)
             : mSessionStats(cameraId, facing, newCameraState, clientName, apiLevel, isNdk,
                             latencyMs, logId) {}
@@ -65,7 +64,8 @@
                 const std::string& userTag, int32_t videoStabilizationMode,
                 const std::vector<hardware::CameraStreamStats>& streamStats);
 
-        String16 updateExtensionSessionStats(const hardware::CameraExtensionSessionStats& extStats);
+        std::string updateExtensionSessionStats(
+                const hardware::CameraExtensionSessionStats& extStats);
 
         // Returns the logId associated with this event.
         int64_t getLogId();
@@ -74,7 +74,7 @@
     // Lock for camera session stats map
     Mutex mLock;
     // Map from camera id to the camera's session statistics
-    std::map<String8, std::shared_ptr<CameraSessionStatsWrapper>> mSessionStatsMap;
+    std::map<std::string, std::shared_ptr<CameraSessionStatsWrapper>> mSessionStatsMap;
 
     std::random_device mRandomDevice;  // pulls 32-bit random numbers from /dev/urandom
 
@@ -93,22 +93,22 @@
     static sp<hardware::ICameraServiceProxy> getDefaultCameraServiceProxy();
 
     // Open
-    void logOpen(const String8& id, int facing,
-            const String16& clientPackageName, int apiLevel, bool isNdk,
+    void logOpen(const std::string& id, int facing,
+            const std::string& clientPackageName, int apiLevel, bool isNdk,
             int32_t latencyMs);
 
     // Close
-    void logClose(const String8& id, int32_t latencyMs, bool deviceError);
+    void logClose(const std::string& id, int32_t latencyMs, bool deviceError);
 
     // Stream configuration
-    void logStreamConfigured(const String8& id, int operatingMode, bool internalReconfig,
+    void logStreamConfigured(const std::string& id, int operatingMode, bool internalReconfig,
             int32_t latencyMs);
 
     // Session state becomes active
-    void logActive(const String8& id, float maxPreviewFps);
+    void logActive(const std::string& id, float maxPreviewFps);
 
     // Session state becomes idle
-    void logIdle(const String8& id,
+    void logIdle(const std::string& id,
             int64_t requestCount, int64_t resultErrorCount, bool deviceError,
             const std::string& userTag, int32_t videoStabilizationMode,
             const std::vector<hardware::CameraStreamStats>& streamStats);
@@ -117,10 +117,10 @@
     void pingCameraServiceProxy();
 
     // Return the current top activity rotate and crop override.
-    int getRotateAndCropOverride(String16 packageName, int lensFacing, int userId);
+    int getRotateAndCropOverride(const std::string &packageName, int lensFacing, int userId);
 
     // Return the current top activity autoframing.
-    int getAutoframingOverride(const String16& packageName);
+    int getAutoframingOverride(const std::string& packageName);
 
     // Detect if the camera is disabled by device policy.
     bool isCameraDisabled(int userId);
@@ -128,10 +128,10 @@
     // Returns the logId currently associated with the given cameraId. See 'mLogId' in
     // frameworks/av/camera/include/camera/CameraSessionStats.h for more details about this
     // identifier. Returns a non-0 value on success.
-    int64_t getCurrentLogIdForCamera(const String8& cameraId);
+    int64_t getCurrentLogIdForCamera(const std::string& cameraId);
 
     // Update the stored extension stats to the latest values
-    String16 updateExtensionStats(const hardware::CameraExtensionSessionStats& extStats);
+    std::string updateExtensionStats(const hardware::CameraExtensionSessionStats& extStats);
 };
 
 } // android
diff --git a/services/camera/libcameraservice/utils/CameraTraces.h b/services/camera/libcameraservice/utils/CameraTraces.h
index 71fa334..be8d393 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.h
+++ b/services/camera/libcameraservice/utils/CameraTraces.h
@@ -18,7 +18,6 @@
 #define ANDROID_SERVERS_CAMERA_TRACES_H_
 
 #include <utils/Errors.h>
-#include <utils/String16.h>
 #include <utils/Vector.h>
 
 namespace android {
diff --git a/services/camera/libcameraservice/utils/LatencyHistogram.cpp b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
index e2bdc43..a167068 100644
--- a/services/camera/libcameraservice/utils/LatencyHistogram.cpp
+++ b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
@@ -16,8 +16,9 @@
 
 #define LOG_TAG "CameraLatencyHistogram"
 #include <inttypes.h>
+#include <android-base/stringprintf.h>
 #include <utils/Log.h>
-#include <utils/String8.h>
+#include <camera/StringUtils.h>
 
 #include "LatencyHistogram.h"
 
@@ -55,18 +56,18 @@
         return;
     }
 
-    String8 lines;
-    lines.appendFormat("%s (%" PRId64 ") samples\n", name, mTotalCount);
+    std::string lines;
+    lines += fmt::sprintf("%s (%" PRId64 ") samples\n", name, mTotalCount);
 
-    String8 lineBins, lineBinCounts;
+    std::string lineBins, lineBinCounts;
     formatHistogramText(lineBins, lineBinCounts);
 
-    lineBins.append("\n");
-    lineBinCounts.append("\n");
-    lines.append(lineBins);
-    lines.append(lineBinCounts);
+    lineBins += ("\n");
+    lineBinCounts += ("\n");
+    lines += lineBins;
+    lines += lineBinCounts;
 
-    write(fd, lines.string(), lines.size());
+    write(fd, lines.c_str(), lines.size());
 }
 
 void CameraLatencyHistogram::log(const char* fmt, ...) {
@@ -76,11 +77,12 @@
 
     va_list args;
     va_start(args, fmt);
-    String8 histogramName = String8::formatV(fmt, args);
-    ALOGI("%s (%" PRId64 ") samples:", histogramName.string(), mTotalCount);
+    std::string histogramName;
+    base::StringAppendV(&histogramName, fmt, args);
+    ALOGI("%s (%" PRId64 ") samples:", histogramName.c_str(), mTotalCount);
     va_end(args);
 
-    String8 lineBins, lineBinCounts;
+    std::string lineBins, lineBinCounts;
     formatHistogramText(lineBins, lineBinCounts);
 
     ALOGI("%s", lineBins.c_str());
@@ -88,19 +90,19 @@
 }
 
 void CameraLatencyHistogram::formatHistogramText(
-        String8& lineBins, String8& lineBinCounts) const {
+        std::string& lineBins, std::string& lineBinCounts) const {
     lineBins = "  ";
     lineBinCounts = "  ";
 
     for (int32_t i = 0; i < mBinCount; i++) {
         if (i == mBinCount - 1) {
-            lineBins.append("    inf (max ms)");
+            lineBins += "    inf (max ms)";
         } else {
-            lineBins.appendFormat("%7d", mBinSizeMs*(i+1));
+            lineBins += fmt::sprintf("%7d", mBinSizeMs*(i+1));
         }
-        lineBinCounts.appendFormat("   %02.2f", 100.0*mBins[i]/mTotalCount);
+        lineBinCounts += fmt::sprintf("   %02.2f", 100.0*mBins[i]/mTotalCount);
     }
-    lineBinCounts.append(" (%)");
+    lineBinCounts += " (%)";
 }
 
 }; //namespace android
diff --git a/services/camera/libcameraservice/utils/LatencyHistogram.h b/services/camera/libcameraservice/utils/LatencyHistogram.h
index bfd9b1b..89a9cc1 100644
--- a/services/camera/libcameraservice/utils/LatencyHistogram.h
+++ b/services/camera/libcameraservice/utils/LatencyHistogram.h
@@ -40,7 +40,7 @@
     std::vector<int64_t> mBins;
     uint64_t mTotalCount;
 
-    void formatHistogramText(String8& lineBins, String8& lineBinCounts) const;
+    void formatHistogramText(std::string& lineBins, std::string& lineBinCounts) const;
 }; // class CameraLatencyHistogram
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 89e75b3..f7257e3 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -28,6 +28,7 @@
 #include "device3/hidl/HidlCamera3Device.h"
 #include "device3/Camera3OutputStream.h"
 #include "system/graphics-base-v1.1.h"
+#include <camera/StringUtils.h>
 #include <ui/PublicFormat.h>
 
 using android::camera3::OutputStreamInfo;
@@ -427,15 +428,15 @@
 binder::Status createSurfaceFromGbp(
         OutputStreamInfo& streamInfo, bool isStreamInfoValid,
         sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
-        const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
+        const std::string &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
         const std::vector<int32_t> &sensorPixelModesUsed, int64_t dynamicRangeProfile,
         int64_t streamUseCase, int timestampBase, int mirrorMode,
         int32_t colorSpace) {
     // bufferProducer must be non-null
     if (gbp == nullptr) {
-        String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
-        ALOGW("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Surface is NULL", logicalCameraId.c_str());
+        ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     // HACK b/10949105
     // Query consumer usage bits to set async operation mode for
@@ -444,14 +445,14 @@
     uint64_t consumerUsage = 0;
     status_t err;
     if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
-        String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
-                logicalCameraId.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Failed to query Surface consumer usage: %s (%d)",
+                logicalCameraId.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
     if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
         ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
-                "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
+                "stream", __FUNCTION__, logicalCameraId.c_str(), consumerUsage);
         useAsync = true;
     }
 
@@ -469,38 +470,38 @@
     int width, height, format;
     android_dataspace dataSpace;
     if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
-        String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
-                 logicalCameraId.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Failed to query Surface width: %s (%d)",
+                 logicalCameraId.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
     if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
-        String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
-                logicalCameraId.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Failed to query Surface height: %s (%d)",
+                logicalCameraId.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
     if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
-        String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
-                logicalCameraId.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Failed to query Surface format: %s (%d)",
+                logicalCameraId.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
     if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
             reinterpret_cast<int*>(&dataSpace))) != OK) {
-        String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
-                logicalCameraId.string(), strerror(-err), err);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: Failed to query Surface dataspace: %s (%d)",
+                logicalCameraId.c_str(), strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
     }
 
     if (colorSpace != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED &&
             format != HAL_PIXEL_FORMAT_BLOB) {
         if (!dataSpaceFromColorSpace(&dataSpace, colorSpace)) {
-            String8 msg = String8::format("Camera %s: color space %d not supported, failed to "
-                    "convert to data space", logicalCameraId.string(), colorSpace);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            std::string msg = fmt::sprintf("Camera %s: color space %d not supported, failed to "
+                    "convert to data space", logicalCameraId.c_str(), colorSpace);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
     }
 
@@ -510,16 +511,16 @@
             ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
              ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
         ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
-                __FUNCTION__, logicalCameraId.string(), format);
+                __FUNCTION__, logicalCameraId.c_str(), format);
         format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
     }
     std::unordered_set<int32_t> overriddenSensorPixelModes;
     if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
             physicalCameraMetadata, &overriddenSensorPixelModes) != OK) {
-        String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
-                "format %#x are not valid",logicalCameraId.string(), format);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: sensor pixel modes for stream with "
+                "format %#x are not valid",logicalCameraId.c_str(), format);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     bool foundInMaxRes = false;
     if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -532,58 +533,58 @@
             !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
             format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
             /*out*/&height)) {
-        String8 msg = String8::format("Camera %s: No supported stream configurations with "
+        std::string msg = fmt::sprintf("Camera %s: No supported stream configurations with "
                 "format %#x defined, failed to create output stream",
-                logicalCameraId.string(), format);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                logicalCameraId.c_str(), format);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
                 physicalCameraMetadata)) {
-        String8 msg = String8::format("Camera %s: Dynamic range profile 0x%" PRIx64
-                " not supported,failed to create output stream", logicalCameraId.string(),
+        std::string msg = fmt::sprintf("Camera %s: Dynamic range profile 0x%" PRIx64
+                " not supported,failed to create output stream", logicalCameraId.c_str(),
                 dynamicRangeProfile);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
             !SessionConfigurationUtils::is10bitCompatibleFormat(format, dataSpace)) {
-        String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
+        std::string msg = fmt::sprintf("Camera %s: No 10-bit supported stream configurations with "
                 "format %#x defined and profile %" PRIx64 ", failed to create output stream",
-                logicalCameraId.string(), format, dynamicRangeProfile);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                logicalCameraId.c_str(), format, dynamicRangeProfile);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (colorSpace != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED &&
             SessionConfigurationUtils::deviceReportsColorSpaces(physicalCameraMetadata) &&
             !SessionConfigurationUtils::isColorSpaceSupported(colorSpace, format, dataSpace,
                     dynamicRangeProfile, physicalCameraMetadata)) {
-        String8 msg = String8::format("Camera %s: Color space %d not supported, failed to "
+        std::string msg = fmt::sprintf("Camera %s: Color space %d not supported, failed to "
                 "create output stream (pixel format %d dynamic range profile %" PRId64 ")",
-                logicalCameraId.string(), colorSpace, format, dynamicRangeProfile);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                logicalCameraId.c_str(), colorSpace, format, dynamicRangeProfile);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
             physicalCameraMetadata)) {
-        String8 msg = String8::format("Camera %s: stream use case %" PRId64 " not supported,"
-                " failed to create output stream", logicalCameraId.string(), streamUseCase);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: stream use case %" PRId64 " not supported,"
+                " failed to create output stream", logicalCameraId.c_str(), streamUseCase);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
             timestampBase > OutputConfiguration::TIMESTAMP_BASE_MAX) {
-        String8 msg = String8::format("Camera %s: invalid timestamp base %d",
-                logicalCameraId.string(), timestampBase);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: invalid timestamp base %d",
+                logicalCameraId.c_str(), timestampBase);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (mirrorMode < OutputConfiguration::MIRROR_MODE_AUTO ||
             mirrorMode > OutputConfiguration::MIRROR_MODE_V) {
-        String8 msg = String8::format("Camera %s: invalid mirroring mode %d",
-                logicalCameraId.string(), mirrorMode);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s: invalid mirroring mode %d",
+                logicalCameraId.c_str(), mirrorMode);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
 
     if (!isStreamInfoValid) {
@@ -601,45 +602,45 @@
         return binder::Status::ok();
     }
     if (width != streamInfo.width) {
-        String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
-                logicalCameraId.string(), width, streamInfo.width);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s:Surface width doesn't match: %d vs %d",
+                logicalCameraId.c_str(), width, streamInfo.width);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (height != streamInfo.height) {
-        String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
-                 logicalCameraId.string(), height, streamInfo.height);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s:Surface height doesn't match: %d vs %d",
+                 logicalCameraId.c_str(), height, streamInfo.height);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (format != streamInfo.format) {
-        String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
-                 logicalCameraId.string(), format, streamInfo.format);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg = fmt::sprintf("Camera %s:Surface format doesn't match: %d vs %d",
+                 logicalCameraId.c_str(), format, streamInfo.format);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
         if (dataSpace != streamInfo.dataSpace) {
-            String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
-                    logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            std::string msg = fmt::sprintf("Camera %s:Surface dataSpace doesn't match: %d vs %d",
+                    logicalCameraId.c_str(), dataSpace, streamInfo.dataSpace);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
         //At the native side, there isn't a way to check whether 2 surfaces come from the same
         //surface class type. Use usage flag to approximate the comparison.
         if (consumerUsage != streamInfo.consumerUsage) {
-            String8 msg = String8::format(
+            std::string msg = fmt::sprintf(
                     "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
-                    logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                    logicalCameraId.c_str(), consumerUsage, streamInfo.consumerUsage);
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
         }
     }
     return binder::Status::ok();
 }
 
 void mapStreamInfo(const OutputStreamInfo &streamInfo,
-            camera3::camera_stream_rotation_t rotation, String8 physicalId,
+            camera3::camera_stream_rotation_t rotation, const std::string &physicalId,
             int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
     if (stream == nullptr) {
         return;
@@ -656,7 +657,7 @@
     stream->colorSpace = streamInfo.colorSpace;
     stream->rotation = AidlCamera3Device::mapToAidlStreamRotation(rotation);
     stream->id = -1; // Invalid stream id
-    stream->physicalCameraId = std::string(physicalId.string());
+    stream->physicalCameraId = physicalId;
     stream->bufferSize = 0;
     stream->groupId = groupId;
     stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
@@ -677,34 +678,35 @@
 binder::Status
 convertToHALStreamCombination(
         const SessionConfiguration& sessionConfiguration,
-        const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+        const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
         bool isCompositeJpegRDisabled,
         metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
         aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
         bool overrideForPerfClass, bool *earlyExit) {
     using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
     auto operatingMode = sessionConfiguration.getOperatingMode();
-    binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
+    binder::Status res = checkOperatingMode(operatingMode, deviceInfo,
+            logicalCameraId);
     if (!res.isOk()) {
         return res;
     }
 
     if (earlyExit == nullptr) {
-        String8 msg("earlyExit nullptr");
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        std::string msg("earlyExit nullptr");
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     *earlyExit = false;
     auto ret = AidlCamera3Device::mapToAidlStreamConfigurationMode(
             static_cast<camera_stream_configuration_mode_t> (operatingMode),
             /*out*/ &streamConfiguration.operationMode);
     if (ret != OK) {
-        String8 msg = String8::format(
+        std::string msg = fmt::sprintf(
             "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
-            logicalCameraId.string(), operatingMode, strerror(-ret), ret);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+            logicalCameraId.c_str(), operatingMode, strerror(-ret), ret);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                msg.string());
+                msg.c_str());
     }
 
     bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
@@ -749,7 +751,7 @@
         const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
             it.getGraphicBufferProducers();
         bool deferredConsumer = it.isDeferred();
-        String8 physicalCameraId = String8(it.getPhysicalCameraId());
+        const std::string &physicalCameraId = it.getPhysicalCameraId();
 
         int64_t dynamicRangeProfile = it.getDynamicRangeProfile();
         int32_t colorSpace = it.getColorSpace();
@@ -841,11 +843,11 @@
                     }
 
                     if (ret != OK) {
-                        String8 msg = String8::format(
+                        std::string msg = fmt::sprintf(
                                 "Camera %s: Failed adding composite streams: %s (%d)",
-                                logicalCameraId.string(), strerror(-ret), ret);
-                        ALOGE("%s: %s", __FUNCTION__, msg.string());
-                        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+                                logicalCameraId.c_str(), strerror(-ret), ret);
+                        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+                        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
                     }
 
                     if (compositeStreams.size() == 0) {
@@ -877,17 +879,17 @@
 }
 
 binder::Status checkPhysicalCameraId(
-        const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
-        const String8 &logicalCameraId) {
+        const std::vector<std::string> &physicalCameraIds, const std::string &physicalCameraId,
+        const std::string &logicalCameraId) {
     if (physicalCameraId.size() == 0) {
         return binder::Status::ok();
     }
     if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
-        physicalCameraId.string()) == physicalCameraIds.end()) {
-        String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
-                logicalCameraId.string(), physicalCameraId.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+        physicalCameraId) == physicalCameraIds.end()) {
+        std::string msg = fmt::sprintf("Camera %s: Camera doesn't support physicalCameraId %s.",
+                logicalCameraId.c_str(), physicalCameraId.c_str());
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
     return binder::Status::ok();
 }
@@ -915,13 +917,13 @@
 }
 
 binder::Status checkOperatingMode(int operatingMode,
-        const CameraMetadata &staticInfo, const String8 &cameraId) {
+        const CameraMetadata &staticInfo, const std::string &cameraId) {
     if (operatingMode < 0) {
-        String8 msg = String8::format(
-            "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        std::string msg = fmt::sprintf(
+            "Camera %s: Invalid operating mode %d requested", cameraId.c_str(), operatingMode);
+        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                msg.string());
+                msg.c_str());
     }
 
     bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
@@ -936,12 +938,12 @@
             }
         }
         if (!isConstrainedHighSpeedSupported) {
-            String8 msg = String8::format(
+            std::string msg = fmt::sprintf(
                 "Camera %s: Try to create a constrained high speed configuration on a device"
-                " that doesn't support it.", cameraId.string());
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
+                " that doesn't support it.", cameraId.c_str());
+            ALOGE("%s: %s", __FUNCTION__, msg.c_str());
             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                    msg.string());
+                    msg.c_str());
         }
     }
 
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index dc143da..79d80ea 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -21,6 +21,7 @@
 #include <camera/camera2/OutputConfiguration.h>
 #include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/SubmitInfo.h>
+#include <camera/StringUtils.h>
 #include <aidl/android/hardware/camera/device/ICameraDevice.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
@@ -37,17 +38,18 @@
 
 #define STATUS_ERROR(errorCode, errorString) \
     binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
+            fmt::sprintf("%s:%d: %s", __FUNCTION__, __LINE__, errorString).c_str())
 
 #define STATUS_ERROR_FMT(errorCode, errorString, ...) \
     binder::Status::fromServiceSpecificError(errorCode, \
-            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
-                    __VA_ARGS__))
+            fmt::sprintf("%s:%d: " errorString, __FUNCTION__, __LINE__, \
+                    __VA_ARGS__).c_str())
 
 namespace android {
 namespace camera3 {
 
-typedef std::function<CameraMetadata (const String8 &, bool overrideForPerfClass)> metadataGetter;
+typedef std::function<CameraMetadata (const std::string &, bool overrideForPerfClass)>
+        metadataGetter;
 
 class StreamConfiguration {
 public:
@@ -96,7 +98,7 @@
 binder::Status createSurfaceFromGbp(
         camera3::OutputStreamInfo& streamInfo, bool isStreamInfoValid,
         sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
-        const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
+        const std::string &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
         const std::vector<int32_t> &sensorPixelModesUsed,  int64_t dynamicRangeProfile,
         int64_t streamUseCase, int timestampBase, int mirrorMode,
         int32_t colorSpace);
@@ -120,26 +122,27 @@
 bool isStreamUseCaseSupported(int64_t streamUseCase, const CameraMetadata &deviceInfo);
 
 void mapStreamInfo(const OutputStreamInfo &streamInfo,
-        camera3::camera_stream_rotation_t rotation, String8 physicalId,
+        camera3::camera_stream_rotation_t rotation, const std::string &physicalId,
         int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/);
 
 // Check that the physicalCameraId passed in is spported by the camera
 // device.
 binder::Status checkPhysicalCameraId(
-const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
-const String8 &logicalCameraId);
+const std::vector<std::string> &physicalCameraIds, const std::string &physicalCameraId,
+const std::string &logicalCameraId);
 
 binder::Status checkSurfaceType(size_t numBufferProducers,
 bool deferredConsumer, int surfaceType);
 
 binder::Status checkOperatingMode(int operatingMode,
-const CameraMetadata &staticInfo, const String8 &cameraId);
+const CameraMetadata &staticInfo, const std::string &cameraId);
 
 binder::Status
 convertToHALStreamCombination(
     const SessionConfiguration& sessionConfiguration,
-    const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool isCompositeJpegRDisabled,
-    metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+    const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
+    bool isCompositeJpegRDisabled, metadataGetter getMetadata,
+    const std::vector<std::string> &physicalCameraIds,
     aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
     bool overrideForPerfClass, bool *earlyExit);
 
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index 111c1bf..cf93d3b 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -105,7 +105,7 @@
 binder::Status
 convertToHALStreamCombination(
         const SessionConfiguration& sessionConfiguration,
-        const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+        const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
         metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
         hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
         bool overrideForPerfClass, bool *earlyExit) {
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
index c47abe0..eae2e30 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
@@ -34,7 +34,7 @@
 // isn't valid.
 binder::Status
 convertToHALStreamCombination(const SessionConfiguration& sessionConfiguration,
-        const String8 &cameraId, const CameraMetadata &deviceInfo,
+        const std::string &cameraId, const CameraMetadata &deviceInfo,
         metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
         hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
         bool overrideForPerfClass, bool *earlyExit);
diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp
index d1e54ab..38de93a 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.cpp
+++ b/services/camera/libcameraservice/utils/TagMonitor.cpp
@@ -18,11 +18,15 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <iostream>
+#include <sstream>
+
 #include "TagMonitor.h"
 
 #include <inttypes.h>
 #include <utils/Log.h>
 #include <camera/VendorTagDescriptor.h>
+#include <camera/StringUtils.h>
 #include <camera_metadata_hidden.h>
 #include <device3/Camera3Stream.h>
 
@@ -44,7 +48,7 @@
         mMonitoringEvents(other.mMonitoringEvents),
         mVendorTagId(other.mVendorTagId) {}
 
-const String16 TagMonitor::kMonitorOption = String16("-m");
+const std::string TagMonitor::kMonitorOption("-m");
 
 const char* TagMonitor::k3aTags =
         "android.control.aeMode, android.control.afMode, android.control.awbMode,"
@@ -56,17 +60,17 @@
         "android.control.effectMode, android.control.mode, android.control.sceneMode,"
         "android.control.videoStabilizationMode";
 
-void TagMonitor::parseTagsToMonitor(String8 tagNames) {
+void TagMonitor::parseTagsToMonitor(std::string tagNames) {
     std::lock_guard<std::mutex> lock(mMonitorMutex);
 
     // Expand shorthands
     ssize_t idx = tagNames.find("3a");
     if (idx != -1) {
         ssize_t end = tagNames.find(",", idx);
-        char* start = tagNames.lockBuffer(tagNames.size());
-        start[idx] = '\0';
-        char* rest = (end != -1) ? (start + end) : (start + tagNames.size());
-        tagNames = String8::format("%s%s%s", start, k3aTags, rest);
+        tagNames = tagNames.substr(0, idx) + k3aTags;
+        if (end != -1) {
+            tagNames += tagNames.substr(end);
+        }
     }
 
     sp<VendorTagDescriptor> vTags =
@@ -81,14 +85,13 @@
 
     bool gotTag = false;
 
-    char *tokenized = tagNames.lockBuffer(tagNames.size());
-    char *savePtr;
-    char *nextTagName = strtok_r(tokenized, ", ", &savePtr);
-    while (nextTagName != nullptr) {
+    std::istringstream iss(tagNames);
+    std::string nextTagName;
+    while (std::getline(iss, nextTagName, ',')) {
         uint32_t tag;
-        status_t res = CameraMetadata::getTagFromName(nextTagName, vTags.get(), &tag);
+        status_t res = CameraMetadata::getTagFromName(nextTagName.c_str(), vTags.get(), &tag);
         if (res != OK) {
-            ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName);
+            ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName.c_str());
         } else {
             if (!gotTag) {
                 mMonitoredTagList.clear();
@@ -96,11 +99,9 @@
             }
             mMonitoredTagList.push_back(tag);
         }
-        nextTagName = strtok_r(nullptr, ", ", &savePtr);
+        iss >> std::ws;
     }
 
-    tagNames.unlockBuffer();
-
     if (gotTag) {
         // Got at least one new tag
         mMonitoringEnabled = true;
@@ -269,7 +270,7 @@
 
     for (const auto& event : mMonitoringEvents) {
         int indentation = (event.source == REQUEST) ? 15 : 30;
-        String8 eventString = String8::format("f%d:%" PRId64 "ns:%*s%*s",
+        std::string eventString = fmt::sprintf("f%d:%" PRId64 "ns:%*s%*s",
                 event.frameNumber, event.timestamp,
                 2, event.cameraId.c_str(),
                 indentation,
@@ -278,20 +279,20 @@
         if (!event.outputStreamIds.empty()) {
             eventString += " output stream ids:";
             for (const auto& id : event.outputStreamIds) {
-                eventString.appendFormat(" %d", id);
+                eventString += fmt::sprintf(" %d", id);
             }
             eventString += "\n";
-            vec.emplace_back(eventString.string());
+            vec.emplace_back(eventString);
             continue;
         }
 
         if (event.inputStreamId != -1) {
-            eventString.appendFormat(" input stream id: %d\n", event.inputStreamId);
-            vec.emplace_back(eventString.string());
+            eventString += fmt::sprintf(" input stream id: %d\n", event.inputStreamId);
+            vec.emplace_back(eventString);
             continue;
         }
 
-        eventString += String8::format(
+        eventString += fmt::sprintf(
                 "%s.%s: ",
                 get_local_camera_metadata_section_name_vendor_id(event.tag, mVendorTagId),
                 get_local_camera_metadata_tag_name_vendor_id(event.tag, mVendorTagId));
@@ -303,14 +304,14 @@
                     event.newData.data(), event.tag, event.type,
                     event.newData.size() / camera_metadata_type_size[event.type], indentation + 18);
         }
-        vec.emplace_back(eventString.string());
+        vec.emplace_back(eventString);
     }
 }
 
 #define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29
 
-String8 TagMonitor::getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type, int count,
-                                       int indentation) {
+std::string TagMonitor::getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type,
+        int count, int indentation) {
     static int values_per_line[NUM_TYPES] = {
         [TYPE_BYTE]     = 16,
         [TYPE_INT32]    = 8,
@@ -327,11 +328,11 @@
     int lines = count / values_per_line[type];
     if (count % values_per_line[type] != 0) lines++;
 
-    String8 returnStr = String8();
+    std::ostringstream returnStr;
     int index = 0;
     int j, k;
     for (j = 0; j < lines; j++) {
-        returnStr.appendFormat("%*s[", (j != 0) ? indentation + 4 : 0, "");
+        returnStr << fmt::sprintf("%*s[", (j != 0) ? indentation + 4 : 0, "");
         for (k = 0;
              k < values_per_line[type] && count > 0;
              k++, count--, index += type_size) {
@@ -344,9 +345,9 @@
                                                      value_string_tmp,
                                                      sizeof(value_string_tmp))
                         == OK) {
-                        returnStr += value_string_tmp;
+                        returnStr << value_string_tmp;
                     } else {
-                        returnStr.appendFormat("%hhu ", *(data_ptr + index));
+                        returnStr << fmt::sprintf("%hhu ", *(data_ptr + index));
                     }
                     break;
                 case TYPE_INT32:
@@ -357,33 +358,33 @@
                                                      value_string_tmp,
                                                      sizeof(value_string_tmp))
                         == OK) {
-                        returnStr += value_string_tmp;
+                        returnStr << value_string_tmp;
                     } else {
-                        returnStr.appendFormat("%" PRId32 " ", *(int32_t*)(data_ptr + index));
+                        returnStr << fmt::sprintf("%" PRId32 " ", *(int32_t*)(data_ptr + index));
                     }
                     break;
                 case TYPE_FLOAT:
-                    returnStr.appendFormat("%0.8f ", *(float*)(data_ptr + index));
+                    returnStr << fmt::sprintf("%0.8f ", *(float*)(data_ptr + index));
                     break;
                 case TYPE_INT64:
-                    returnStr.appendFormat("%" PRId64 " ", *(int64_t*)(data_ptr + index));
+                    returnStr << fmt::sprintf("%" PRId64 " ", *(int64_t*)(data_ptr + index));
                     break;
                 case TYPE_DOUBLE:
-                    returnStr.appendFormat("%0.8f ", *(double*)(data_ptr + index));
+                    returnStr << fmt::sprintf("%0.8f ", *(double*)(data_ptr + index));
                     break;
                 case TYPE_RATIONAL: {
                     int32_t numerator = *(int32_t*)(data_ptr + index);
                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
-                    returnStr.appendFormat("(%d / %d) ", numerator, denominator);
+                    returnStr << fmt::sprintf("(%d / %d) ", numerator, denominator);
                     break;
                 }
                 default:
-                    returnStr += "??? ";
+                    returnStr << "??? ";
             }
         }
-        returnStr += "]\n";
+        returnStr << "]\n";
     }
-    return returnStr;
+    return std::move(returnStr.str());
 }
 
 template<typename T>
diff --git a/services/camera/libcameraservice/utils/TagMonitor.h b/services/camera/libcameraservice/utils/TagMonitor.h
index 9ded15d..bff4de0 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.h
+++ b/services/camera/libcameraservice/utils/TagMonitor.h
@@ -21,9 +21,9 @@
 #include <atomic>
 #include <mutex>
 #include <unordered_map>
+#include <string>
 
 #include <utils/RefBase.h>
-#include <utils/String8.h>
 #include <utils/Timers.h>
 
 #include <media/RingBuffer.h>
@@ -42,7 +42,7 @@
   public:
 
     // Monitor argument
-    static const String16 kMonitorOption;
+    static const std::string kMonitorOption;
 
     enum eventSource {
         REQUEST,
@@ -59,7 +59,7 @@
     // If invalid, do nothing.
     // Recognizes "3a" as a shortcut for enabling tracking 3A state, mode, and
     // triggers
-    void parseTagsToMonitor(String8 tagNames);
+    void parseTagsToMonitor(std::string tagNames);
 
     // Disable monitoring; does not clear the event log
     void disableMonitoring();
@@ -85,8 +85,8 @@
     // function.
     void dumpMonitoredTagEventsToVectorLocked(std::vector<std::string> &out);
 
-    static String8 getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type, int count,
-                                      int indentation);
+    static std::string getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type,
+            int count, int indentation);
 
     void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber,
             nsecs_t timestamp, const std::string& cameraId, uint32_t tag,
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index 902af66..abe5f16 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -107,7 +107,7 @@
 
     if (args.size() > 0) {
         const String8 arg0(args[0]);
-        if (!strcmp(arg0.string(), "-r")) {
+        if (!strcmp(arg0.c_str(), "-r")) {
             // needed because mReaders is protected by mLock
             bool locked = dumpTryLock(mLock);
 
@@ -115,9 +115,9 @@
             if (!locked) {
                 String8 result(kDeadlockedString);
                 if (fd >= 0) {
-                    write(fd, result.string(), result.size());
+                    write(fd, result.c_str(), result.size());
                 } else {
-                    ALOGW("%s:", result.string());
+                    ALOGW("%s:", result.c_str());
                 }
                 return NO_ERROR;
             }
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index af1372b..1b5255a 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -278,14 +278,14 @@
         } else if (args[i] == prefixOption) {
             ++i;
             if (i < n) {
-                prefix = String8(args[i]).string();
+                prefix = String8(args[i]).c_str();
             }
         } else if (args[i] == sinceOption) {
             ++i;
             if (i < n) {
                 String8 value(args[i]);
                 char *endp;
-                const char *p = value.string();
+                const char *p = value.c_str();
                 const auto sec = (int64_t)strtoll(p, &endp, 10);
                 if (endp == p || *endp != '\0' || sec == 0) {
                     sinceNs = 0;
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index f8cdb80..e26fd28 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -434,7 +434,7 @@
 
 void ResourceManagerMetrics::pushReclaimAtom(const ClientInfoParcel& clientInfo,
                         const std::vector<int>& priorities,
-                        const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+                        const std::vector<std::shared_ptr<IResourceManagerClient>>& clients,
                         const PidUidVector& idList, bool reclaimed) {
     // Construct the metrics for codec reclaim as a pushed atom.
     // 1. Information about the requester.
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.h b/services/mediaresourcemanager/ResourceManagerMetrics.h
index 3124aa2..d99c5b1 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.h
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.h
@@ -135,7 +135,7 @@
     // To be called when after a reclaim event.
     void pushReclaimAtom(const ClientInfoParcel& clientInfo,
                          const std::vector<int>& priorities,
-                         const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+                         const std::vector<std::shared_ptr<IResourceManagerClient>>& clients,
                          const PidUidVector& idList, bool reclaimed);
 
     // Add this pid/uid set to monitor for the process termination state.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 53cc431..5d1ba2b 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -44,47 +44,82 @@
 
 namespace android {
 
-//static
-std::mutex ResourceManagerService::sCookieLock;
-//static
-uintptr_t ResourceManagerService::sCookieCounter = 0;
-//static
-std::map<uintptr_t, sp<DeathNotifier> > ResourceManagerService::sCookieToDeathNotifierMap;
+class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
 
-class DeathNotifier : public RefBase {
+    // 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 DeathNotifier, before deferencing it upon the binder death.
+    struct BinderDiedContext {
+        std::weak_ptr<DeathNotifier> mDeathNotifier;
+    };
 public:
-    DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
-                  const ClientInfoParcel& clientInfo);
+    DeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
+                  const std::shared_ptr<ResourceManagerService>& service,
+                  const ClientInfoParcel& clientInfo,
+                  AIBinder_DeathRecipient* recipient);
 
-    virtual ~DeathNotifier() {}
+    virtual ~DeathNotifier() {
+        unlink();
+    }
+
+    void unlink() {
+        if (mClient != nullptr) {
+            // Register for the callbacks by linking to death notification.
+            AIBinder_unlinkToDeath(mClient->asBinder().get(), mRecipient, mCookie);
+            mClient = nullptr;
+        }
+    }
 
     // Implement death recipient
     static void BinderDiedCallback(void* cookie);
+    static void BinderUnlinkedCallback(void* cookie);
     virtual void binderDied();
 
+private:
+    void link() {
+        // Create the context that is passed as cookie to the binder death notification.
+        // The context gets deleted at BinderUnlinkedCallback.
+        mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
+        // Register for the callbacks by linking to death notification.
+        AIBinder_linkToDeath(mClient->asBinder().get(), mRecipient, mCookie);
+    }
+
 protected:
+    std::shared_ptr<IResourceManagerClient> mClient;
     std::weak_ptr<ResourceManagerService> mService;
     const ClientInfoParcel mClientInfo;
+    AIBinder_DeathRecipient* mRecipient;
+    BinderDiedContext* mCookie;
 };
 
-DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
-                             const ClientInfoParcel& clientInfo)
-    : mService(service), mClientInfo(clientInfo) {}
+DeathNotifier::DeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
+                             const std::shared_ptr<ResourceManagerService>& service,
+                             const ClientInfoParcel& clientInfo,
+                             AIBinder_DeathRecipient* recipient)
+    : mClient(client), mService(service), mClientInfo(clientInfo),
+      mRecipient(recipient), mCookie(nullptr) {
+    link();
+}
+
+//static
+void DeathNotifier::BinderUnlinkedCallback(void* cookie) {
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+    // Since we don't need the context anymore, we are deleting it now.
+    delete context;
+}
 
 //static
 void DeathNotifier::BinderDiedCallback(void* cookie) {
-    sp<DeathNotifier> notifier;
-    {
-        std::scoped_lock lock{ResourceManagerService::sCookieLock};
-        auto it = ResourceManagerService::sCookieToDeathNotifierMap.find(
-                reinterpret_cast<uintptr_t>(cookie));
-        if (it == ResourceManagerService::sCookieToDeathNotifierMap.end()) {
-            return;
+    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+
+    // Validate the context and check if the DeathNotifier object is still in scope.
+    if (context != nullptr) {
+        std::shared_ptr<DeathNotifier> thiz = context->mDeathNotifier.lock();
+        if (thiz != nullptr) {
+            thiz->binderDied();
+        } else {
+            ALOGI("DeathNotifier is out of scope already");
         }
-        notifier = it->second;
-    }
-    if (notifier.get() != nullptr) {
-        notifier->binderDied();
     }
 }
 
@@ -103,9 +138,11 @@
 
 class OverrideProcessInfoDeathNotifier : public DeathNotifier {
 public:
-    OverrideProcessInfoDeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
-                                     const ClientInfoParcel& clientInfo)
-            : DeathNotifier(service, clientInfo) {}
+    OverrideProcessInfoDeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
+                                     const std::shared_ptr<ResourceManagerService>& service,
+                                     const ClientInfoParcel& clientInfo,
+                                     AIBinder_DeathRecipient* recipient)
+            : DeathNotifier(client, service, clientInfo, recipient) {}
 
     virtual ~OverrideProcessInfoDeathNotifier() {}
 
@@ -124,16 +161,16 @@
 }
 
 template <typename T>
-static String8 getString(const std::vector<T> &items) {
+static String8 getString(const std::vector<T>& items) {
     String8 itemsStr;
     for (size_t i = 0; i < items.size(); ++i) {
-        itemsStr.appendFormat("%s ", toString(items[i]).string());
+        itemsStr.appendFormat("%s ", toString(items[i]).c_str());
     }
     return itemsStr;
 }
 
 static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
-        MediaResourceParcel resource) {
+        const MediaResourceParcel& resource) {
     if (type != resource.type) {
       return false;
     }
@@ -165,8 +202,8 @@
 
 static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
         const ResourceInfos& infos) {
-    for (size_t i = 0; i < infos.size(); ++i) {
-        if (hasResourceType(type, subType, infos[i].resources)) {
+    for (const auto& [id, info] : infos) {
+        if (hasResourceType(type, subType, info.resources)) {
             return true;
         }
     }
@@ -174,41 +211,37 @@
 }
 
 static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
-    ssize_t index = map.indexOfKey(pid);
-    if (index < 0) {
+    PidResourceInfosMap::iterator found = map.find(pid);
+    if (found == map.end()) {
         // new pid
         ResourceInfos infosForPid;
-        map.add(pid, infosForPid);
+        auto [it, inserted] = map.emplace(pid, infosForPid);
+        found = it;
     }
 
-    return map.editValueFor(pid);
+    return found->second;
 }
 
 static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
                                             const std::string& name,
         const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
-    ssize_t index = infos.indexOfKey(clientId);
+    ResourceInfos::iterator found = infos.find(clientId);
 
-    if (index < 0) {
-        ResourceInfo info;
-        info.uid = uid;
-        info.clientId = clientId;
-        if (name.empty()) {
-            info.name = "<unknown client>";
-        } else {
-            info.name = name;
-        }
-        info.client = client;
-        info.cookie = 0;
-        info.pendingRemoval = false;
-
-        index = infos.add(clientId, info);
+    if (found == infos.end()) {
+        ResourceInfo info{.uid = uid,
+                          .clientId = clientId,
+                          .name = name.empty()? "<unknown client>" : name,
+                          .client = client,
+                          .deathNotifier = nullptr,
+                          .pendingRemoval = false};
+        auto [it, inserted] = infos.emplace(clientId, info);
+        found = it;
     }
 
-    return infos.editValueAt(index);
+    return found->second;
 }
 
-static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel> &resources) {
+static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel>& resources) {
     static const char* const kServiceName = "media_resource_monitor";
     sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
     if (binder != NULL) {
@@ -239,7 +272,7 @@
                 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
                 AIBinder_getCallingPid(),
                 AIBinder_getCallingUid());
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         return PERMISSION_DENIED;
     }
 
@@ -249,7 +282,7 @@
     std::map<int, int> overridePidMapCopy;
     String8 serviceLog;
     {
-        Mutex::Autolock lock(mLock);
+        std::scoped_lock lock{mLock};
         mapCopy = mMap;  // Shadow copy, real copy will happen on write.
         supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
         supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
@@ -269,8 +302,7 @@
     result.append(buffer);
 
     result.append("  Processes:\n");
-    for (size_t i = 0; i < mapCopy.size(); ++i) {
-        int pid = mapCopy.keyAt(i);
+    for (const auto& [pid, infos] : mapCopy) {
         snprintf(buffer, SIZE, "    Pid: %d\n", pid);
         result.append(buffer);
         int priority = 0;
@@ -281,20 +313,19 @@
         }
         result.append(buffer);
 
-        const ResourceInfos &infos = mapCopy.valueAt(i);
-        for (size_t j = 0; j < infos.size(); ++j) {
+        for (const auto& [infoKey, info] : infos) {
             result.append("      Client:\n");
-            snprintf(buffer, SIZE, "        Id: %lld\n", (long long)infos[j].clientId);
+            snprintf(buffer, SIZE, "        Id: %lld\n", (long long)info.clientId);
             result.append(buffer);
 
-            std::string clientName = infos[j].name;
+            std::string clientName = info.name;
             snprintf(buffer, SIZE, "        Name: %s\n", clientName.c_str());
             result.append(buffer);
 
-            const ResourceList &resources = infos[j].resources;
+            const ResourceList& resources = info.resources;
             result.append("        Resources:\n");
             for (auto it = resources.begin(); it != resources.end(); it++) {
-                snprintf(buffer, SIZE, "          %s\n", toString(it->second).string());
+                snprintf(buffer, SIZE, "          %s\n", toString(it->second).c_str());
                 result.append(buffer);
             }
         }
@@ -308,7 +339,7 @@
     result.append("  Events logs (most recent at top):\n");
     result.append(serviceLog);
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return OK;
 }
 
@@ -347,7 +378,8 @@
       mSupportsMultipleSecureCodecs(true),
       mSupportsSecureWithNonSecureCodec(true),
       mCpuBoostCount(0),
-      mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
+      mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
+                      AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback))) {
     mSystemCB->noteResetVideo();
     // Create ResourceManagerMetrics that handles all the metrics.
     mResourceManagerMetrics = std::make_unique<ResourceManagerMetrics>(mProcessInfo);
@@ -385,10 +417,10 @@
 }
 
 Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
-    String8 log = String8::format("config(%s)", getString(policies).string());
+    String8 log = String8::format("config(%s)", getString(policies).c_str());
     mServiceLog->add(log);
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     for (size_t i = 0; i < policies.size(); ++i) {
         const std::string &type = policies[i].type;
         const std::string &value = policies[i].value;
@@ -458,10 +490,10 @@
     int64_t clientId = clientInfo.id;
     const std::string& name = clientInfo.name;
     String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
-            pid, uid, (long long) clientId, getString(resources).string());
+            pid, uid, (long long) clientId, getString(resources).c_str());
     mServiceLog->add(log);
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     if (!mProcessInfo->isPidUidTrusted(pid, uid)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -502,9 +534,9 @@
             mergeResources(it->second, res);
         }
     }
-    if (info.cookie == 0 && client != nullptr) {
-        info.cookie = addCookieAndLink_l(client,
-                new DeathNotifier(ref<ResourceManagerService>(), clientInfo));
+    if (info.deathNotifier == nullptr && client != nullptr) {
+        info.deathNotifier = std::make_shared<DeathNotifier>(
+            client, ref<ResourceManagerService>(), clientInfo, mDeathRecipient.get());
     }
     if (mObserverService != nullptr && !resourceAdded.empty()) {
         mObserverService->onResourceAdded(uid, pid, resourceAdded);
@@ -520,30 +552,30 @@
     int32_t uid = clientInfo.uid;
     int64_t clientId = clientInfo.id;
     String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
-            pid, uid, (long long) clientId, getString(resources).string());
+            pid, uid, (long long) clientId, getString(resources).c_str());
     mServiceLog->add(log);
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     if (!mProcessInfo->isPidTrusted(pid)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
                 pid, callingPid);
         pid = callingPid;
     }
-    ssize_t index = mMap.indexOfKey(pid);
-    if (index < 0) {
+    PidResourceInfosMap::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
         ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
         return Status::ok();
     }
-    ResourceInfos &infos = mMap.editValueAt(index);
+    ResourceInfos& infos = found->second;
 
-    index = infos.indexOfKey(clientId);
-    if (index < 0) {
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
         ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
         return Status::ok();
     }
 
-    ResourceInfo &info = infos.editValueAt(index);
+    ResourceInfo& info = foundClient->second;
     ResourceList resourceRemoved;
     for (size_t i = 0; i < resources.size(); ++i) {
         const auto &res = resources[i];
@@ -593,27 +625,27 @@
             pid, uid, (long long) clientId);
     mServiceLog->add(log);
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     if (checkValid && !mProcessInfo->isPidTrusted(pid)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
                 pid, callingPid);
         pid = callingPid;
     }
-    ssize_t index = mMap.indexOfKey(pid);
-    if (index < 0) {
+    PidResourceInfosMap::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
         ALOGV("removeResource: didn't find pid %d for clientId %lld", pid, (long long) clientId);
         return Status::ok();
     }
-    ResourceInfos &infos = mMap.editValueAt(index);
+    ResourceInfos& infos = found->second;
 
-    index = infos.indexOfKey(clientId);
-    if (index < 0) {
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
         ALOGV("removeResource: didn't find clientId %lld", (long long) clientId);
         return Status::ok();
     }
 
-    const ResourceInfo &info = infos[index];
+    const ResourceInfo& info = foundClient->second;
     for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
         onLastRemoved(it->second, info);
     }
@@ -621,20 +653,18 @@
     // Since this client has been removed, update the metrics collector.
     mResourceManagerMetrics->notifyClientReleased(clientInfo);
 
-    removeCookieAndUnlink_l(info.client, info.cookie);
-
     if (mObserverService != nullptr && !info.resources.empty()) {
         mObserverService->onResourceRemoved(info.uid, pid, info.resources);
     }
 
-    infos.removeItemsAt(index);
+    infos.erase(foundClient);
     return Status::ok();
 }
 
 void ResourceManagerService::getClientForResource_l(int callingPid,
         const MediaResourceParcel *res,
         PidUidVector* idVector,
-        Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
+        std::vector<std::shared_ptr<IResourceManagerClient>>* clients) {
     if (res == NULL) {
         return;
     }
@@ -649,14 +679,14 @@
     int32_t callingPid = clientInfo.pid;
     std::string clientName = clientInfo.name;
     String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
-            callingPid, clientInfo.uid, getString(resources).string());
+            callingPid, clientInfo.uid, getString(resources).c_str());
     mServiceLog->add(log);
     *_aidl_return = false;
 
-    Vector<std::shared_ptr<IResourceManagerClient>> clients;
+    std::vector<std::shared_ptr<IResourceManagerClient>> clients;
     PidUidVector idVector;
     {
-        Mutex::Autolock lock(mLock);
+        std::scoped_lock lock{mLock};
         if (!mProcessInfo->isPidTrusted(callingPid)) {
             pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
             ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
@@ -749,7 +779,7 @@
 }
 
 void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
-                        const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+                        const std::vector<std::shared_ptr<IResourceManagerClient>>& clients,
                         const PidUidVector& idVector, bool reclaimed) {
     int32_t callingPid = clientInfo.pid;
     int requesterPriority = -1;
@@ -767,7 +797,7 @@
 }
 
 bool ResourceManagerService::reclaimUnconditionallyFrom(
-        const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
+        const std::vector<std::shared_ptr<IResourceManagerClient>>& clients) {
     if (clients.size() == 0) {
         return false;
     }
@@ -790,20 +820,18 @@
 
     int failedClientPid = -1;
     {
-        Mutex::Autolock lock(mLock);
+        std::scoped_lock lock{mLock};
         bool found = false;
-        for (size_t i = 0; i < mMap.size(); ++i) {
-            ResourceInfos &infos = mMap.editValueAt(i);
-            for (size_t j = 0; j < infos.size();) {
-                if (infos[j].client == failedClient) {
-                    j = infos.removeItemsAt(j);
+        for (auto& [pid, infos] : mMap) {
+            for (const auto& [id, info] : infos) {
+                if (info.client == failedClient) {
+                    infos.erase(id);
                     found = true;
-                } else {
-                    ++j;
+                    break;
                 }
             }
             if (found) {
-                failedClientPid = mMap.keyAt(i);
+                failedClientPid = pid;
                 break;
             }
         }
@@ -835,7 +863,7 @@
     }
 
     {
-        Mutex::Autolock lock(mLock);
+        std::scoped_lock lock{mLock};
         mOverridePidMap.erase(originalPid);
         if (newPid != -1) {
             mOverridePidMap.emplace(originalPid, newPid);
@@ -865,7 +893,7 @@
         return Status::fromServiceSpecificError(BAD_VALUE);
     }
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     removeProcessInfoOverride_l(pid);
 
     if (!mProcessInfo->overrideProcessInfo(pid, procState, oomScore)) {
@@ -877,42 +905,16 @@
                                 .uid = 0,
                                 .id = 0,
                                 .name = "<unknown client>"};
-    uintptr_t cookie = addCookieAndLink_l(client,
-            new OverrideProcessInfoDeathNotifier(ref<ResourceManagerService>(), clientInfo));
+    auto deathNotifier = std::make_shared<OverrideProcessInfoDeathNotifier>(
+            client, ref<ResourceManagerService>(), clientInfo, mDeathRecipient.get());
 
-    mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{cookie, client});
+    mProcessInfoOverrideMap.emplace(pid, ProcessInfoOverride{deathNotifier, client});
 
     return Status::ok();
 }
 
-uintptr_t ResourceManagerService::addCookieAndLink_l(
-        const std::shared_ptr<IResourceManagerClient>& client, const sp<DeathNotifier>& notifier) {
-    if (client == nullptr) {
-        return 0;
-    }
-    std::scoped_lock lock{sCookieLock};
-
-    uintptr_t cookie;
-    // Need to skip cookie 0 (if it wraps around). ResourceInfo has cookie initialized to 0
-    // indicating the death notifier is not created yet.
-    while ((cookie = ++sCookieCounter) == 0);
-    AIBinder_linkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
-    sCookieToDeathNotifierMap.emplace(cookie, notifier);
-
-    return cookie;
-}
-
-void ResourceManagerService::removeCookieAndUnlink_l(
-         const std::shared_ptr<IResourceManagerClient>& client, uintptr_t cookie) {
-    std::scoped_lock lock{sCookieLock};
-    if (client != nullptr) {
-        AIBinder_unlinkToDeath(client->asBinder().get(), mDeathRecipient.get(), (void*)cookie);
-    }
-    sCookieToDeathNotifierMap.erase(cookie);
-}
-
 void ResourceManagerService::removeProcessInfoOverride(int pid) {
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
 
     removeProcessInfoOverride_l(pid);
 }
@@ -924,9 +926,6 @@
     }
 
     mProcessInfo->removeProcessInfoOverride(pid);
-
-    removeCookieAndUnlink_l(it->second.client, it->second.cookie);
-
     mProcessInfoOverrideMap.erase(pid);
 }
 
@@ -938,28 +937,28 @@
             pid, (long long) clientId);
     mServiceLog->add(log);
 
-    Mutex::Autolock lock(mLock);
+    std::scoped_lock lock{mLock};
     if (!mProcessInfo->isPidTrusted(pid)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
                 pid, callingPid);
         pid = callingPid;
     }
-    ssize_t index = mMap.indexOfKey(pid);
-    if (index < 0) {
+    PidResourceInfosMap::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
         ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld",
               pid, (long long)clientId);
         return Status::ok();
     }
-    ResourceInfos &infos = mMap.editValueAt(index);
+    ResourceInfos& infos = found->second;
 
-    index = infos.indexOfKey(clientId);
-    if (index < 0) {
+    ResourceInfos::iterator foundClient = infos.find(clientId);
+    if (foundClient == infos.end()) {
         ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId);
         return Status::ok();
     }
 
-    ResourceInfo &info = infos.editValueAt(index);
+    ResourceInfo& info = foundClient->second;
     info.pendingRemoval = true;
     return Status::ok();
 }
@@ -968,9 +967,9 @@
     String8 log = String8::format("reclaimResourcesFromClientsPendingRemoval(pid %d)", pid);
     mServiceLog->add(log);
 
-    Vector<std::shared_ptr<IResourceManagerClient>> clients;
+    std::vector<std::shared_ptr<IResourceManagerClient>> clients;
     {
-        Mutex::Autolock lock(mLock);
+        std::scoped_lock lock{mLock};
         if (!mProcessInfo->isPidTrusted(pid)) {
             pid_t callingPid = IPCThreadState::self()->getCallingPid();
             ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
@@ -992,7 +991,7 @@
                         std::shared_ptr<IResourceManagerClient> client;
                         uid_t uid = 0;
                         if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
-                            clients.add(client);
+                            clients.push_back(client);
                             continue;
                         }
                     }
@@ -1003,7 +1002,7 @@
                     uid_t uid = 0;
                     if (getBiggestClientPendingRemoval_l(pid, type,
                             MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
-                        clients.add(client);
+                        clients.push_back(client);
                     }
                     break;
             }
@@ -1031,23 +1030,22 @@
 bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
         MediaResource::SubType subType,
         PidUidVector* idVector,
-        Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
-    Vector<std::shared_ptr<IResourceManagerClient>> temp;
+        std::vector<std::shared_ptr<IResourceManagerClient>>* clients) {
+    std::vector<std::shared_ptr<IResourceManagerClient>> temp;
     PidUidVector tempIdList;
 
-    for (size_t i = 0; i < mMap.size(); ++i) {
-        ResourceInfos &infos = mMap.editValueAt(i);
-        for (size_t j = 0; j < infos.size(); ++j) {
-            if (hasResourceType(type, subType, infos[j].resources)) {
-                if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
+    for (auto& [pid, infos] : mMap) {
+        for (const auto& [id, info] : infos) {
+            if (hasResourceType(type, subType, info.resources)) {
+                if (!isCallingPriorityHigher_l(callingPid, pid)) {
                     // some higher/equal priority process owns the resource,
                     // this request can't be fulfilled.
                     ALOGE("getAllClients_l: can't reclaim resource %s from pid %d",
-                            asString(type), mMap.keyAt(i));
+                            asString(type), pid);
                     return false;
                 }
-                temp.push_back(infos[j].client);
-                tempIdList.emplace_back(mMap.keyAt(i), infos[j].uid);
+                temp.push_back(info.client);
+                tempIdList.emplace_back(pid, info.uid);
             }
         }
     }
@@ -1055,7 +1053,8 @@
         ALOGV("getAllClients_l: didn't find any resource %s", asString(type));
         return true;
     }
-    clients->appendVector(temp);
+
+    clients->insert(std::end(*clients), std::begin(temp), std::end(temp));
     idVector->insert(std::end(*idVector), std::begin(tempIdList), std::end(tempIdList));
     return true;
 }
@@ -1102,17 +1101,16 @@
         MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) {
     int pid = -1;
     int priority = -1;
-    for (size_t i = 0; i < mMap.size(); ++i) {
-        if (mMap.valueAt(i).size() == 0) {
+    for (auto& [tempPid, infos] : mMap) {
+        if (infos.size() == 0) {
             // no client on this process.
             continue;
         }
-        if (!hasResourceType(type, subType, mMap.valueAt(i))) {
+        if (!hasResourceType(type, subType, infos)) {
             // doesn't have the requested resource type
             continue;
         }
-        int tempPid = mMap.keyAt(i);
-        int tempPriority;
+        int tempPriority = -1;
         if (!getPriority_l(tempPid, &tempPriority)) {
             ALOGV("getLowestPriorityPid_l: can't get priority of pid %d, skipped", tempPid);
             // TODO: remove this pid from mMap?
@@ -1155,8 +1153,8 @@
         MediaResource::SubType subType, uid_t& uid,
         std::shared_ptr<IResourceManagerClient> *client,
         bool pendingRemovalOnly) {
-    ssize_t index = mMap.indexOfKey(pid);
-    if (index < 0) {
+    PidResourceInfosMap::iterator found = mMap.find(pid);
+    if (found == mMap.end()) {
         ALOGE_IF(!pendingRemovalOnly,
                  "getBiggestClient_l: can't find resource info for pid %d", pid);
         return false;
@@ -1164,10 +1162,10 @@
 
     std::shared_ptr<IResourceManagerClient> clientTemp;
     uint64_t largestValue = 0;
-    const ResourceInfos &infos = mMap.valueAt(index);
-    for (size_t i = 0; i < infos.size(); ++i) {
-        const ResourceList &resources = infos[i].resources;
-        if (pendingRemovalOnly && !infos[i].pendingRemoval) {
+    const ResourceInfos& infos = found->second;
+    for (const auto& [id, info] : infos) {
+        const ResourceList& resources = info.resources;
+        if (pendingRemovalOnly && !info.pendingRemoval) {
             continue;
         }
         for (auto it = resources.begin(); it != resources.end(); it++) {
@@ -1175,8 +1173,8 @@
             if (hasResourceType(type, subType, resource)) {
                 if (resource.value > largestValue) {
                     largestValue = resource.value;
-                    clientTemp = infos[i].client;
-                    uid = infos[i].uid;
+                    clientTemp = info.client;
+                    uid = info.uid;
                 }
             }
         }
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 1519e0e..aa88ac6 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -22,15 +22,13 @@
 #include <set>
 #include <mutex>
 #include <string>
+#include <vector>
 
 #include <aidl/android/media/BnResourceManagerService.h>
-#include <arpa/inet.h>
 #include <media/MediaResource.h>
 #include <utils/Errors.h>
-#include <utils/KeyedVector.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
-#include <utils/Vector.h>
 
 namespace android {
 
@@ -58,7 +56,7 @@
     int64_t clientId;
     std::string name;
     std::shared_ptr<IResourceManagerClient> client;
-    uintptr_t cookie{0};
+    std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
     ResourceList resources;
     bool pendingRemoval{false};
 };
@@ -66,9 +64,8 @@
 // vector of <PID, UID>
 typedef std::vector<std::pair<int32_t, uid_t>> PidUidVector;
 
-// TODO: convert these to std::map
-typedef KeyedVector<int64_t, ResourceInfo> ResourceInfos;
-typedef KeyedVector<int, ResourceInfos> PidResourceInfosMap;
+typedef std::map<int64_t, ResourceInfo> ResourceInfos;
+typedef std::map<int, ResourceInfos> PidResourceInfosMap;
 
 class ResourceManagerService : public BnResourceManagerService {
 public:
@@ -136,14 +133,15 @@
 
     // Reclaims resources from |clients|. Returns true if reclaim succeeded
     // for all clients.
-    bool reclaimUnconditionallyFrom(const Vector<std::shared_ptr<IResourceManagerClient>> &clients);
+    bool reclaimUnconditionallyFrom(
+        const std::vector<std::shared_ptr<IResourceManagerClient>>& clients);
 
     // Gets the list of all the clients who own the specified resource type.
     // Returns false if any client belongs to a process with higher priority than the
     // calling process. The clients will remain unchanged if returns false.
     bool getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType,
             PidUidVector* idList,
-            Vector<std::shared_ptr<IResourceManagerClient>> *clients);
+            std::vector<std::shared_ptr<IResourceManagerClient>>* clients);
 
     // Gets the client who owns specified resource type from lowest possible priority process.
     // Returns false if the calling process priority is not higher than the lowest process
@@ -174,7 +172,7 @@
     // the result client to the given Vector.
     void getClientForResource_l(int callingPid, const MediaResourceParcel *res,
             PidUidVector* idList,
-            Vector<std::shared_ptr<IResourceManagerClient>> *clients);
+            std::vector<std::shared_ptr<IResourceManagerClient>>* clients);
 
     void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
     void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
@@ -188,13 +186,9 @@
     void removeProcessInfoOverride(int pid);
 
     void removeProcessInfoOverride_l(int pid);
-    uintptr_t addCookieAndLink_l(const std::shared_ptr<IResourceManagerClient>& client,
-                                 const sp<DeathNotifier>& notifier);
-    void removeCookieAndUnlink_l(const std::shared_ptr<IResourceManagerClient>& client,
-                                 uintptr_t cookie);
 
     void pushReclaimAtom(const ClientInfoParcel& clientInfo,
-                         const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+                         const std::vector<std::shared_ptr<IResourceManagerClient>>& clients,
                          const PidUidVector& idList, bool reclaimed);
 
     // Get the peak concurrent pixel count (associated with the video codecs) for the process.
@@ -202,7 +196,7 @@
     // Get the current concurrent pixel count (associated with the video codecs) for the process.
     long getCurrentConcurrentPixelCount(int pid) const;
 
-    mutable Mutex mLock;
+    mutable std::mutex mLock;
     sp<ProcessInfoInterface> mProcessInfo;
     sp<SystemCallbackInterface> mSystemCB;
     sp<ServiceLog> mServiceLog;
@@ -212,15 +206,11 @@
     int32_t mCpuBoostCount;
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
     struct ProcessInfoOverride {
-        uintptr_t cookie;
+        std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
         std::shared_ptr<IResourceManagerClient> client;
     };
     std::map<int, int> mOverridePidMap;
     std::map<pid_t, ProcessInfoOverride> mProcessInfoOverrideMap;
-    static std::mutex sCookieLock;
-    static uintptr_t sCookieCounter GUARDED_BY(sCookieLock);
-    static std::map<uintptr_t, sp<DeathNotifier> > sCookieToDeathNotifierMap
-            GUARDED_BY(sCookieLock);
     std::shared_ptr<ResourceObserverService> mObserverService;
     std::unique_ptr<ResourceManagerMetrics> mResourceManagerMetrics;
 };
diff --git a/services/mediaresourcemanager/ResourceObserverService.cpp b/services/mediaresourcemanager/ResourceObserverService.cpp
index ebe3903..33525fd 100644
--- a/services/mediaresourcemanager/ResourceObserverService.cpp
+++ b/services/mediaresourcemanager/ResourceObserverService.cpp
@@ -122,7 +122,7 @@
                 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
                 AIBinder_getCallingPid(),
                 AIBinder_getCallingUid());
-        write(fd, result.string(), result.size());
+        write(fd, result.c_str(), result.size());
         return PERMISSION_DENIED;
     }
 
@@ -150,7 +150,7 @@
         }
     }
 
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return OK;
 }
 
diff --git a/services/mediaresourcemanager/ServiceLog.cpp b/services/mediaresourcemanager/ServiceLog.cpp
index 791e797..132ed33 100644
--- a/services/mediaresourcemanager/ServiceLog.cpp
+++ b/services/mediaresourcemanager/ServiceLog.cpp
@@ -35,14 +35,14 @@
     time_t now = time(0);
     char buf[64];
     strftime(buf, sizeof(buf), "%m-%d %T", localtime(&now));
-    mLogs.add(String8::format("%s %s", buf, log.string()));
+    mLogs.add(String8::format("%s %s", buf, log.c_str()));
 }
 
 String8 ServiceLog::toString(const char *linePrefix) const {
     Mutex::Autolock lock(mLock);
     String8 result;
     for (const auto& log : mLogs) {
-        addLine(log.string(), linePrefix, &result);
+        addLine(log.c_str(), linePrefix, &result);
     }
     if (mLogs.size() == mMaxNum) {
         addLine("...", linePrefix, &result);
diff --git a/services/mediaresourcemanager/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index d98974f..a46d87a 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -52,5 +52,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 155276,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of libresourcemanagerservice",
+        vector: "remote",
+        service_privilege: "constrained",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index f903c62..de24e1e 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -20,6 +20,7 @@
         "libmedia",
         "libmediautils",
         "libutils",
+        "libmediautils",
         "libstats_media_metrics",
         "libstatspull",
         "libstatssocket",
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 4e575f0..ae3faea 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -131,18 +131,18 @@
 
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(2u, map.size());
-        ssize_t index1 = map.indexOfKey(kTestPid1);
-        ASSERT_GE(index1, 0);
-        const ResourceInfos &infos1 = map[index1];
+        const auto& mapIndex1 = map.find(kTestPid1);
+        EXPECT_TRUE(mapIndex1 != map.end());
+        const ResourceInfos &infos1 = mapIndex1->second;
         EXPECT_EQ(1u, infos1.size());
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, resources1);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, resources1);
 
-        ssize_t index2 = map.indexOfKey(kTestPid2);
-        ASSERT_GE(index2, 0);
-        const ResourceInfos &infos2 = map[index2];
+        const auto& mapIndex2 = map.find(kTestPid2);
+        EXPECT_TRUE(mapIndex2 != map.end());
+        const ResourceInfos &infos2 = mapIndex2->second;
         EXPECT_EQ(2u, infos2.size());
-        expectEqResourceInfo(infos2.valueFor(getId(mTestClient2)), kTestUid2, mTestClient2, resources2);
-        expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
+        expectEqResourceInfo(infos2.at(getId(mTestClient2)), kTestUid2, mTestClient2, resources2);
+        expectEqResourceInfo(infos2.at(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
     }
 
     void testCombineResourceWithNegativeValues() {
@@ -161,12 +161,12 @@
         // 2) both resource entries should have been rejected, resource list should be empty.
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(1u, map.size());
-        ssize_t index1 = map.indexOfKey(kTestPid1);
-        ASSERT_GE(index1, 0);
-        const ResourceInfos &infos1 = map[index1];
+        const auto& mapIndex1 = map.find(kTestPid1);
+        EXPECT_TRUE(mapIndex1 != map.end());
+        const ResourceInfos &infos1 = mapIndex1->second;
         EXPECT_EQ(1u, infos1.size());
         std::vector<MediaResourceParcel> expected;
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         resources1.clear();
         resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
@@ -181,7 +181,7 @@
         // Both values should saturate to INT64_MAX
         expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
         expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         resources1.clear();
         resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10));
@@ -193,7 +193,7 @@
         // 2) Non-drm session resource should ignore negative value addition.
         expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX - 10));
         expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         resources1.clear();
         resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN));
@@ -206,7 +206,7 @@
         expected.clear();
         expected.push_back(MediaResource(MediaResource::Type::kDrmSession, 0));
         expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
     }
 
     void testConfig() {
@@ -256,9 +256,9 @@
 
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(1u, map.size());
-        ssize_t index1 = map.indexOfKey(kTestPid1);
-        ASSERT_GE(index1, 0);
-        const ResourceInfos &infos1 = map[index1];
+        const auto& mapIndex1 = map.find(kTestPid1);
+        EXPECT_TRUE(mapIndex1 != map.end());
+        const ResourceInfos &infos1 = mapIndex1->second;
         EXPECT_EQ(1u, infos1.size());
 
         // test adding existing types to combine values
@@ -268,7 +268,7 @@
         std::vector<MediaResourceParcel> expected;
         expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
         expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         // test adding new types (including types that differs only in subType)
         resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
@@ -280,7 +280,7 @@
         expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
         expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
         expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
     }
 
     void testRemoveResource() {
@@ -299,9 +299,9 @@
 
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(1u, map.size());
-        ssize_t index1 = map.indexOfKey(kTestPid1);
-        ASSERT_GE(index1, 0);
-        const ResourceInfos &infos1 = map[index1];
+        const auto& mapIndex1 = map.find(kTestPid1);
+        EXPECT_TRUE(mapIndex1 != map.end());
+        const ResourceInfos &infos1 = mapIndex1->second;
         EXPECT_EQ(1u, infos1.size());
 
         // test partial removal
@@ -311,13 +311,13 @@
         std::vector<MediaResourceParcel> expected;
         expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
         expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         // test removal request with negative value, should be ignored
         resources11[0].value = -10000;
         mService->removeResource(client1Info, resources11);
 
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
 
         // test complete removal with overshoot value
         resources11[0].value = 1000;
@@ -325,7 +325,7 @@
 
         expected.clear();
         expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
-        expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
+        expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
     }
 
     void testOverridePid() {
@@ -466,13 +466,12 @@
 
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(2u, map.size());
-        const ResourceInfos &infos1 = map.valueFor(kTestPid1);
-        const ResourceInfos &infos2 = map.valueFor(kTestPid2);
+        const ResourceInfos &infos1 = map.at(kTestPid1);
+        const ResourceInfos &infos2 = map.at(kTestPid2);
         EXPECT_EQ(1u, infos1.size());
         EXPECT_EQ(1u, infos2.size());
         // mTestClient2 has been removed.
-        // (OK to use infos2[0] as there is only 1 entry)
-        EXPECT_EQ(mTestClient3, infos2[0].client);
+        EXPECT_EQ(mTestClient3, infos2.at(getId(mTestClient3)).client);
     }
 
     void testGetAllClients() {
@@ -480,7 +479,7 @@
         MediaResource::Type type = MediaResource::Type::kSecureCodec;
         MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
 
-        Vector<std::shared_ptr<IResourceManagerClient> > clients;
+        std::vector<std::shared_ptr<IResourceManagerClient> > clients;
         PidUidVector idList;
         EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, subType, &idList, &clients));
         // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
diff --git a/services/mediaresourcemanager/test/ServiceLog_test.cpp b/services/mediaresourcemanager/test/ServiceLog_test.cpp
index 9172499..8556f2a 100644
--- a/services/mediaresourcemanager/test/ServiceLog_test.cpp
+++ b/services/mediaresourcemanager/test/ServiceLog_test.cpp
@@ -39,26 +39,26 @@
     mServiceLog->add(String8("log1"));
     logString = mServiceLog->toString();
     EXPECT_TRUE(logString.contains("log1"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 
     static const char kTestLogPrefix[] = "testlogprefix: ";
     logString = mServiceLog->toString(kTestLogPrefix);
     EXPECT_TRUE(logString.contains(kTestLogPrefix));
     EXPECT_TRUE(logString.contains("log1"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 
     mServiceLog->add(String8("log2"));
     logString = mServiceLog->toString();
     EXPECT_TRUE(logString.contains("log1"));
     EXPECT_TRUE(logString.contains("log2"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 
     mServiceLog->add(String8("log3"));
     logString = mServiceLog->toString();
     EXPECT_TRUE(logString.contains("log1"));
     EXPECT_TRUE(logString.contains("log2"));
     EXPECT_TRUE(logString.contains("log3"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 
     mServiceLog->add(String8("log4"));
     logString = mServiceLog->toString();
@@ -66,7 +66,7 @@
     EXPECT_TRUE(logString.contains("log2"));
     EXPECT_TRUE(logString.contains("log3"));
     EXPECT_TRUE(logString.contains("log4"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 
     mServiceLog->add(String8("log5"));
     logString = mServiceLog->toString();
@@ -75,7 +75,7 @@
     EXPECT_TRUE(logString.contains("log3"));
     EXPECT_TRUE(logString.contains("log4"));
     EXPECT_TRUE(logString.contains("log5"));
-    ALOGV("toString:\n%s", logString.string());
+    ALOGV("toString:\n%s", logString.c_str());
 }
 
 } // namespace android