Merge "surfaceflinger_fuzzer: Bug Fix" into main
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index b302f52..e2a2927 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <fts.h>
 #include <inttypes.h>
+#include <linux/fsverity.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,6 +52,7 @@
 #include <android-base/unique_fd.h>
 #include <cutils/ashmem.h>
 #include <cutils/fs.h>
+#include <cutils/misc.h>
 #include <cutils/properties.h>
 #include <cutils/sched_policy.h>
 #include <linux/quota.h>
@@ -84,6 +86,8 @@
 using android::base::ParseUint;
 using android::base::Split;
 using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::os::ParcelFileDescriptor;
 using std::endl;
 
 namespace android {
@@ -229,6 +233,14 @@
     return ok();
 }
 
+binder::Status checkUidInAppRange(int32_t appUid) {
+    if (FIRST_APPLICATION_UID <= appUid && appUid <= LAST_APPLICATION_UID) {
+        return ok();
+    }
+    return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
+                     StringPrintf("UID %d is outside of the range", appUid));
+}
+
 #define ENFORCE_UID(uid) {                                  \
     binder::Status status = checkUid((uid));                \
     if (!status.isOk()) {                                   \
@@ -283,6 +295,14 @@
         }                                                      \
     }
 
+#define CHECK_ARGUMENT_UID_IN_APP_RANGE(uid)               \
+    {                                                      \
+        binder::Status status = checkUidInAppRange((uid)); \
+        if (!status.isOk()) {                              \
+            return status;                                 \
+        }                                                  \
+    }
+
 #ifdef GRANULAR_LOCKS
 
 /**
@@ -383,6 +403,33 @@
 
 }  // namespace
 
+binder::Status InstalldNativeService::FsveritySetupAuthToken::authenticate(
+        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId) {
+    int open_flags = fcntl(authFd.get(), F_GETFL);
+    if (open_flags < 0) {
+        return exception(binder::Status::EX_SERVICE_SPECIFIC, "fcntl failed");
+    }
+    if ((open_flags & O_ACCMODE) != O_WRONLY && (open_flags & O_ACCMODE) != O_RDWR) {
+        return exception(binder::Status::EX_SECURITY, "Received FD with unexpected open flag");
+    }
+    if (fstat(authFd.get(), &this->mStatFromAuthFd) < 0) {
+        return exception(binder::Status::EX_SERVICE_SPECIFIC, "fstat failed");
+    }
+    if (!S_ISREG(this->mStatFromAuthFd.st_mode)) {
+        return exception(binder::Status::EX_SECURITY, "Not a regular file");
+    }
+    // Don't accept a file owned by a different app.
+    uid_t uid = multiuser_get_uid(userId, appUid);
+    if (this->mStatFromAuthFd.st_uid != uid) {
+        return exception(binder::Status::EX_SERVICE_SPECIFIC, "File not owned by appUid");
+    }
+    return ok();
+}
+
+bool InstalldNativeService::FsveritySetupAuthToken::isSameStat(const struct stat& st) const {
+    return memcmp(&st, &mStatFromAuthFd, sizeof(st)) == 0;
+}
+
 status_t InstalldNativeService::start() {
     IPCThreadState::self()->disableBackgroundScheduling(true);
     status_t ret = BinderService<InstalldNativeService>::publish();
@@ -3857,5 +3904,84 @@
     return *_aidl_return == -1 ? error() : ok();
 }
 
+// Creates an auth token to be used in enableFsverity. This token is really to store a proof that
+// the caller can write to a file, represented by the authFd. Effectively, system_server as the
+// attacker-in-the-middle cannot enable fs-verity on arbitrary app files. If the FD is not writable,
+// return null.
+//
+// appUid and userId are passed for additional ownership check, such that one app can not be
+// authenticated for another app's file. These parameters are assumed trusted for this purpose of
+// consistency check.
+//
+// Notably, creating the token allows us to manage the writable FD easily during enableFsverity.
+// Since enabling fs-verity to a file requires no outstanding writable FD, passing the authFd to the
+// server allows the server to hold the only reference (as long as the client app doesn't).
+binder::Status InstalldNativeService::createFsveritySetupAuthToken(
+        const ParcelFileDescriptor& authFd, int32_t appUid, int32_t userId,
+        sp<IFsveritySetupAuthToken>* _aidl_return) {
+    CHECK_ARGUMENT_UID_IN_APP_RANGE(appUid);
+    ENFORCE_VALID_USER(userId);
+
+    auto token = sp<FsveritySetupAuthToken>::make();
+    binder::Status status = token->authenticate(authFd, appUid, userId);
+    if (!status.isOk()) {
+        return status;
+    }
+    *_aidl_return = token;
+    return ok();
+}
+
+// Enables fs-verity for filePath, which must be an absolute path and the same inode as in the auth
+// token previously returned from createFsveritySetupAuthToken, and owned by the app uid. As
+// installd is more privileged than its client / system server, we attempt to limit what a
+// (compromised) client can do.
+//
+// The reason for this app request to go through installd is to avoid exposing a risky area (PKCS#7
+// signature verification) in the kernel to the app as an attack surface (it can't be system server
+// because it can't override DAC and manipulate app files). Note that we should be able to drop
+// these hops and simply the app calls the ioctl, once all upgrading devices run with a kernel
+// without fs-verity built-in signature (https://r.android.com/2650402).
+binder::Status InstalldNativeService::enableFsverity(const sp<IFsveritySetupAuthToken>& authToken,
+                                                     const std::string& filePath,
+                                                     const std::string& packageName,
+                                                     int32_t* _aidl_return) {
+    ENFORCE_UID(AID_SYSTEM);
+    CHECK_ARGUMENT_PATH(filePath);
+    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+    LOCK_PACKAGE();
+    if (authToken == nullptr) {
+        return exception(binder::Status::EX_ILLEGAL_ARGUMENT, "Received a null auth token");
+    }
+
+    // Authenticate to check the targeting file is the same inode as the authFd.
+    sp<IBinder> authTokenBinder = IInterface::asBinder(authToken)->localBinder();
+    if (authTokenBinder == nullptr) {
+        return exception(binder::Status::EX_SECURITY, "Received a non-local auth token");
+    }
+    auto authTokenInstance = sp<FsveritySetupAuthToken>::cast(authTokenBinder);
+    unique_fd rfd(open(filePath.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
+    struct stat stFromPath;
+    if (fstat(rfd.get(), &stFromPath) < 0) {
+        *_aidl_return = errno;
+        return ok();
+    }
+    if (!authTokenInstance->isSameStat(stFromPath)) {
+        LOG(DEBUG) << "FD authentication failed";
+        *_aidl_return = EPERM;
+        return ok();
+    }
+
+    fsverity_enable_arg arg = {};
+    arg.version = 1;
+    arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
+    arg.block_size = 4096;
+    if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) {
+        *_aidl_return = errno;
+    } else {
+        *_aidl_return = 0;
+    }
+    return ok();
+}
+
 }  // namespace installd
 }  // namespace android
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 521afc3..0f28234 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -19,6 +19,7 @@
 #define COMMANDS_H_
 
 #include <inttypes.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <shared_mutex>
@@ -35,8 +36,26 @@
 namespace android {
 namespace installd {
 
+using IFsveritySetupAuthToken = android::os::IInstalld::IFsveritySetupAuthToken;
+
 class InstalldNativeService : public BinderService<InstalldNativeService>, public os::BnInstalld {
 public:
+    class FsveritySetupAuthToken : public os::IInstalld::BnFsveritySetupAuthToken {
+    public:
+        FsveritySetupAuthToken() : mStatFromAuthFd() {}
+
+        binder::Status authenticate(const android::os::ParcelFileDescriptor& authFd, int32_t appUid,
+                                    int32_t userId);
+        bool isSameStat(const struct stat& st) const;
+
+    private:
+        // Not copyable or movable
+        FsveritySetupAuthToken(const FsveritySetupAuthToken&) = delete;
+        FsveritySetupAuthToken& operator=(const FsveritySetupAuthToken&) = delete;
+
+        struct stat mStatFromAuthFd;
+    };
+
     static status_t start();
     static char const* getServiceName() { return "installd"; }
     virtual status_t dump(int fd, const Vector<String16> &args) override;
@@ -192,6 +211,13 @@
                                      const std::optional<std::string>& outputPath,
                                      int32_t* _aidl_return);
 
+    binder::Status createFsveritySetupAuthToken(const android::os::ParcelFileDescriptor& authFd,
+                                                int32_t appUid, int32_t userId,
+                                                android::sp<IFsveritySetupAuthToken>* _aidl_return);
+    binder::Status enableFsverity(const android::sp<IFsveritySetupAuthToken>& authToken,
+                                  const std::string& filePath, const std::string& packageName,
+                                  int32_t* _aidl_return);
+
 private:
     std::recursive_mutex mLock;
     std::unordered_map<userid_t, std::weak_ptr<std::shared_mutex>> mUserIdLock;
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 9ad853b..8893e38 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -134,6 +134,22 @@
     int getOdexVisibility(@utf8InCpp String packageName, @utf8InCpp String apkPath,
             @utf8InCpp String instructionSet, @nullable @utf8InCpp String outputPath);
 
+    interface IFsveritySetupAuthToken {
+        // Using an interface here is an easy way to create and maintain an IBinder object across
+        // the processes. When installd creates this binder object, it stores the file stat
+        // privately for later authentication, and only returns the reference to the caller process.
+        // Once the binder object has no reference count, it gets destructed automatically
+        // (alternatively, installd can maintain an internal mapping, but it is more error prone
+        // because the app may crash and not finish the fs-verity setup, keeping the memory unused
+        // forever).
+        //
+        // We don't necessarily need a method here, so it's left blank intentionally.
+    }
+    IFsveritySetupAuthToken createFsveritySetupAuthToken(in ParcelFileDescriptor authFd, int appUid,
+            int userId);
+    int enableFsverity(in IFsveritySetupAuthToken authToken, @utf8InCpp String filePath,
+            @utf8InCpp String packageName);
+
     const int FLAG_STORAGE_DE = 0x1;
     const int FLAG_STORAGE_CE = 0x2;
     const int FLAG_STORAGE_EXTERNAL = 0x4;
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 818fd80..27ae8f6 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -560,61 +560,6 @@
         return Dexopt();
     }
 
-    ////////////////////////////////////
-    // Helpers, mostly taken from ART //
-    ////////////////////////////////////
-
-    // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc.
-    static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
-        constexpr size_t kPageSize = PAGE_SIZE;
-        static_assert(IsPowerOfTwo(kPageSize), "page size must be power of two");
-        CHECK_EQ(min_delta % kPageSize, 0u);
-        CHECK_EQ(max_delta % kPageSize, 0u);
-        CHECK_LT(min_delta, max_delta);
-
-        std::default_random_engine generator;
-        generator.seed(GetSeed());
-        std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
-        int32_t r = distribution(generator);
-        if (r % 2 == 0) {
-            r = RoundUp(r, kPageSize);
-        } else {
-            r = RoundDown(r, kPageSize);
-        }
-        CHECK_LE(min_delta, r);
-        CHECK_GE(max_delta, r);
-        CHECK_EQ(r % kPageSize, 0u);
-        return r;
-    }
-
-    static uint64_t GetSeed() {
-#ifdef __BIONIC__
-        // Bionic exposes arc4random, use it.
-        uint64_t random_data;
-        arc4random_buf(&random_data, sizeof(random_data));
-        return random_data;
-#else
-#error "This is only supposed to run with bionic. Otherwise, implement..."
-#endif
-    }
-
-    void AddCompilerOptionFromSystemProperty(const char* system_property,
-            const char* prefix,
-            bool runtime,
-            std::vector<std::string>& out) const {
-        const std::string* value = system_properties_.GetProperty(system_property);
-        if (value != nullptr) {
-            if (runtime) {
-                out.push_back("--runtime-arg");
-            }
-            if (prefix != nullptr) {
-                out.push_back(StringPrintf("%s%s", prefix, value->c_str()));
-            } else {
-                out.push_back(*value);
-            }
-        }
-    }
-
     static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH";
     static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT";
     static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA";
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index c86993c..c40caf5 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -19,9 +19,12 @@
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
+#include <algorithm>
 #include <array>
 #include <fstream>
+#include <iostream>
 #include <sstream>
 
 #include <android-base/file.h>
@@ -29,6 +32,7 @@
 #include <android-base/macros.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <libdm/dm.h>
 #include <selinux/android.h>
@@ -37,7 +41,7 @@
 #include "otapreopt_utils.h"
 
 #ifndef LOG_TAG
-#define LOG_TAG "otapreopt"
+#define LOG_TAG "otapreopt_chroot"
 #endif
 
 using android::base::StringPrintf;
@@ -49,20 +53,22 @@
 // so just try the possibilities one by one.
 static constexpr std::array kTryMountFsTypes = {"ext4", "erofs"};
 
-static void CloseDescriptor(int fd) {
-    if (fd >= 0) {
-        int result = close(fd);
-        UNUSED(result);  // Ignore result. Printing to logcat will open a new descriptor
-                         // that we do *not* want.
-    }
-}
-
 static void CloseDescriptor(const char* descriptor_string) {
     int fd = -1;
     std::istringstream stream(descriptor_string);
     stream >> fd;
     if (!stream.fail()) {
-        CloseDescriptor(fd);
+        if (fd >= 0) {
+            if (close(fd) < 0) {
+                PLOG(ERROR) << "Failed to close " << fd;
+            }
+        }
+    }
+}
+
+static void SetCloseOnExec(int fd) {
+    if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
+        PLOG(ERROR) << "Failed to set FD_CLOEXEC on " << fd;
     }
 }
 
@@ -129,24 +135,39 @@
 }
 
 // Entry for otapreopt_chroot. Expected parameters are:
-//   [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
-// The file descriptor denoted by status-fd will be closed. The rest of the parameters will
-// be passed on to otapreopt in the chroot.
+//
+//   [cmd] [status-fd] [target-slot-suffix]
+//
+// The file descriptor denoted by status-fd will be closed. Dexopt commands on
+// the form
+//
+//   "dexopt" [dexopt-params]
+//
+// are then read from stdin until EOF and passed on to /system/bin/otapreopt one
+// by one. After each call a line with the current command count is written to
+// stdout and flushed.
 static int otapreopt_chroot(const int argc, char **arg) {
     // Validate arguments
-    // We need the command, status channel and target slot, at a minimum.
-    if(argc < 3) {
-        PLOG(ERROR) << "Not enough arguments.";
+    if (argc == 2 && std::string_view(arg[1]) == "--version") {
+        // Accept a single --version flag, to allow the script to tell this binary
+        // from the earlier one.
+        std::cout << "2" << std::endl;
+        return 0;
+    }
+    if (argc != 3) {
+        LOG(ERROR) << "Wrong number of arguments: " << argc;
         exit(208);
     }
-    // Close all file descriptors. They are coming from the caller, we do not want to pass them
-    // on across our fork/exec into a different domain.
-    // 1) Default descriptors.
-    CloseDescriptor(STDIN_FILENO);
-    CloseDescriptor(STDOUT_FILENO);
-    CloseDescriptor(STDERR_FILENO);
-    // 2) The status channel.
-    CloseDescriptor(arg[1]);
+    const char* status_fd = arg[1];
+    const char* slot_suffix = arg[2];
+
+    // Set O_CLOEXEC on standard fds. They are coming from the caller, we do not
+    // want to pass them on across our fork/exec into a different domain.
+    SetCloseOnExec(STDIN_FILENO);
+    SetCloseOnExec(STDOUT_FILENO);
+    SetCloseOnExec(STDERR_FILENO);
+    // Close the status channel.
+    CloseDescriptor(status_fd);
 
     // We need to run the otapreopt tool from the postinstall partition. As such, set up a
     // mount namespace and change root.
@@ -185,20 +206,20 @@
     //  2) We're in a mount namespace here, so when we die, this will be cleaned up.
     //  3) Ignore errors. Printing anything at this stage will open a file descriptor
     //     for logging.
-    if (!ValidateTargetSlotSuffix(arg[2])) {
-        LOG(ERROR) << "Target slot suffix not legal: " << arg[2];
+    if (!ValidateTargetSlotSuffix(slot_suffix)) {
+        LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix;
         exit(207);
     }
-    TryExtraMount("vendor", arg[2], "/postinstall/vendor");
+    TryExtraMount("vendor", slot_suffix, "/postinstall/vendor");
 
     // Try to mount the product partition. update_engine doesn't do this for us, but we
     // want it for product APKs. Same notes as vendor above.
-    TryExtraMount("product", arg[2], "/postinstall/product");
+    TryExtraMount("product", slot_suffix, "/postinstall/product");
 
     // Try to mount the system_ext partition. update_engine doesn't do this for
     // us, but we want it for system_ext APKs. Same notes as vendor and product
     // above.
-    TryExtraMount("system_ext", arg[2], "/postinstall/system_ext");
+    TryExtraMount("system_ext", slot_suffix, "/postinstall/system_ext");
 
     constexpr const char* kPostInstallLinkerconfig = "/postinstall/linkerconfig";
     // Try to mount /postinstall/linkerconfig. we will set it up after performing the chroot
@@ -329,30 +350,37 @@
         exit(218);
     }
 
-    // Now go on and run otapreopt.
+    // Now go on and read dexopt lines from stdin and pass them on to otapreopt.
 
-    // Incoming:  cmd + status-fd + target-slot + cmd...      | Incoming | = argc
-    // Outgoing:  cmd             + target-slot + cmd...      | Outgoing | = argc - 1
-    std::vector<std::string> cmd;
-    cmd.reserve(argc);
-    cmd.push_back("/system/bin/otapreopt");
+    int count = 1;
+    for (std::array<char, 1000> linebuf;
+         std::cin.clear(), std::cin.getline(&linebuf[0], linebuf.size()); ++count) {
+        // Subtract one from gcount() since getline() counts the newline.
+        std::string line(&linebuf[0], std::cin.gcount() - 1);
 
-    // The first parameter is the status file descriptor, skip.
-    for (size_t i = 2; i < static_cast<size_t>(argc); ++i) {
-        cmd.push_back(arg[i]);
+        if (std::cin.fail()) {
+            LOG(ERROR) << "Command exceeds max length " << linebuf.size() << " - skipped: " << line;
+            continue;
+        }
+
+        std::vector<std::string> tokenized_line = android::base::Tokenize(line, " ");
+        std::vector<std::string> cmd{"/system/bin/otapreopt", slot_suffix};
+        std::move(tokenized_line.begin(), tokenized_line.end(), std::back_inserter(cmd));
+
+        LOG(INFO) << "Command " << count << ": " << android::base::Join(cmd, " ");
+
+        // Fork and execute otapreopt in its own process.
+        std::string error_msg;
+        bool exec_result = Exec(cmd, &error_msg);
+        if (!exec_result) {
+            LOG(ERROR) << "Running otapreopt failed: " << error_msg;
+        }
+
+        // Print the count to stdout and flush to indicate progress.
+        std::cout << count << std::endl;
     }
 
-    // Fork and execute otapreopt in its own process.
-    std::string error_msg;
-    bool exec_result = Exec(cmd, &error_msg);
-    if (!exec_result) {
-        LOG(ERROR) << "Running otapreopt failed: " << error_msg;
-    }
-
-    if (!exec_result) {
-        exit(213);
-    }
-
+    LOG(INFO) << "No more dexopt commands";
     return 0;
 }
 
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index e483d54..28bd793 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -16,7 +16,9 @@
 # limitations under the License.
 #
 
-# This script will run as a postinstall step to drive otapreopt.
+# This script runs as a postinstall step to drive otapreopt. It comes with the
+# OTA package, but runs /system/bin/otapreopt_chroot in the (old) active system
+# image. See system/extras/postinst/postinst.sh for some docs.
 
 TARGET_SLOT="$1"
 STATUS_FD="$2"
@@ -31,12 +33,11 @@
 
 BOOT_COMPLETE=$(getprop $BOOT_PROPERTY_NAME)
 if [ "$BOOT_COMPLETE" != "1" ] ; then
-  echo "Error: boot-complete not detected."
+  echo "$0: Error: boot-complete not detected."
   # We must return 0 to not block sideload.
   exit 0
 fi
 
-
 # Compute target slot suffix.
 # TODO: Once bootctl is not restricted, we should query from there. Or get this from
 #       update_engine as a parameter.
@@ -45,44 +46,63 @@
 elif [ "$TARGET_SLOT" = "1" ] ; then
   TARGET_SLOT_SUFFIX="_b"
 else
-  echo "Unknown target slot $TARGET_SLOT"
+  echo "$0: Unknown target slot $TARGET_SLOT"
   exit 1
 fi
 
+if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
+  # We require an updated chroot wrapper that reads dexopt commands from stdin.
+  # Even if we kept compat with the old binary, the OTA preopt wouldn't work due
+  # to missing sepolicy rules, so there's no use spending time trying to dexopt
+  # (b/291974157).
+  echo "$0: Current system image is too old to work with OTA preopt - skipping."
+  exit 0
+fi
 
 PREPARE=$(cmd otadexopt prepare)
 # Note: Ignore preparation failures. Step and done will fail and exit this.
 #       This is necessary to support suspends - the OTA service will keep
 #       the state around for us.
 
-PROGRESS=$(cmd otadexopt progress)
-print -u${STATUS_FD} "global_progress $PROGRESS"
-
-i=0
-while ((i<MAXIMUM_PACKAGES)) ; do
+# Create an array with all dexopt commands in advance, to know how many there are.
+otadexopt_cmds=()
+while (( ${#otadexopt_cmds[@]} < MAXIMUM_PACKAGES )) ; do
   DONE=$(cmd otadexopt done)
   if [ "$DONE" = "OTA complete." ] ; then
     break
   fi
-
-  DEXOPT_PARAMS=$(cmd otadexopt next)
-
-  /system/bin/otapreopt_chroot $STATUS_FD $TARGET_SLOT_SUFFIX $DEXOPT_PARAMS >&- 2>&-
-
-  PROGRESS=$(cmd otadexopt progress)
-  print -u${STATUS_FD} "global_progress $PROGRESS"
-
-  i=$((i+1))
+  otadexopt_cmds+=("$(cmd otadexopt next)")
 done
 
 DONE=$(cmd otadexopt done)
+cmd otadexopt cleanup
+
+echo "$0: Using streaming otapreopt_chroot on ${#otadexopt_cmds[@]} packages"
+
+function print_otadexopt_cmds {
+  for cmd in "${otadexopt_cmds[@]}" ; do
+    print "$cmd"
+  done
+}
+
+function report_progress {
+  while read count ; do
+    # mksh can't do floating point arithmetic, so emulate a fixed point calculation.
+    (( permilles = 1000 * count / ${#otadexopt_cmds[@]} ))
+    printf 'global_progress %d.%03d\n' $((permilles / 1000)) $((permilles % 1000)) >&${STATUS_FD}
+  done
+}
+
+print_otadexopt_cmds | \
+  /system/bin/otapreopt_chroot $STATUS_FD $TARGET_SLOT_SUFFIX | \
+  report_progress
+
 if [ "$DONE" = "OTA incomplete." ] ; then
-  echo "Incomplete."
+  echo "$0: Incomplete."
 else
-  echo "Complete or error."
+  echo "$0: Complete or error."
 fi
 
 print -u${STATUS_FD} "global_progress 1.0"
-cmd otadexopt cleanup
 
 exit 0
diff --git a/cmds/installd/run_dex2oat.cpp b/cmds/installd/run_dex2oat.cpp
index 4221a3a..7648265 100644
--- a/cmds/installd/run_dex2oat.cpp
+++ b/cmds/installd/run_dex2oat.cpp
@@ -208,36 +208,13 @@
     }
 
     // Compute compiler filter.
-    {
-        std::string dex2oat_compiler_filter_arg;
-        {
-            // If we are booting without the real /data, don't spend time compiling.
-            std::string vold_decrypt = GetProperty("vold.decrypt", "");
-            bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
-                    vold_decrypt == "1";
-
-            bool have_dex2oat_relocation_skip_flag = false;
-            if (skip_compilation) {
-                dex2oat_compiler_filter_arg = "--compiler-filter=extract";
-                have_dex2oat_relocation_skip_flag = true;
-            } else if (compiler_filter != nullptr) {
-                dex2oat_compiler_filter_arg = StringPrintf("--compiler-filter=%s",
-                                                           compiler_filter);
-            }
-            if (have_dex2oat_relocation_skip_flag) {
-                AddRuntimeArg("-Xnorelocate");
-            }
-        }
-
-        if (dex2oat_compiler_filter_arg.empty()) {
-            dex2oat_compiler_filter_arg = MapPropertyToArg("dalvik.vm.dex2oat-filter",
-                                                           "--compiler-filter=%s");
-        }
-        AddArg(dex2oat_compiler_filter_arg);
-
-        if (compilation_reason != nullptr) {
-            AddArg(std::string("--compilation-reason=") + compilation_reason);
-        }
+    if (compiler_filter != nullptr) {
+        AddArg(StringPrintf("--compiler-filter=%s", compiler_filter));
+    } else {
+        AddArg(MapPropertyToArg("dalvik.vm.dex2oat-filter", "--compiler-filter=%s"));
+    }
+    if (compilation_reason != nullptr) {
+        AddArg(std::string("--compilation-reason=") + compilation_reason);
     }
 
     AddArg(MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size",
diff --git a/cmds/installd/run_dex2oat_test.cpp b/cmds/installd/run_dex2oat_test.cpp
index 304ba7b..56f84a5 100644
--- a/cmds/installd/run_dex2oat_test.cpp
+++ b/cmds/installd/run_dex2oat_test.cpp
@@ -441,24 +441,6 @@
     VerifyExpectedFlags();
 }
 
-TEST_F(RunDex2OatTest, SkipRelocationInMinFramework) {
-    setSystemProperty("vold.decrypt", "trigger_restart_min_framework");
-    CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
-
-    SetExpectedFlagUsed("--compiler-filter", "=extract");
-    SetExpectedFlagUsed("-Xnorelocate", "");
-    VerifyExpectedFlags();
-}
-
-TEST_F(RunDex2OatTest, SkipRelocationIfDecryptedWithFullDiskEncryption) {
-    setSystemProperty("vold.decrypt", "1");
-    CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
-
-    SetExpectedFlagUsed("--compiler-filter", "=extract");
-    SetExpectedFlagUsed("-Xnorelocate", "");
-    VerifyExpectedFlags();
-}
-
 TEST_F(RunDex2OatTest, DalvikVmDex2oatFilter) {
     setSystemProperty("dalvik.vm.dex2oat-filter", "speed");
     auto args = RunDex2OatArgs::MakeDefaultTestArgs();
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 858a92c..4bc92af 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -42,9 +42,12 @@
 #include "binder_test_utils.h"
 #include "dexopt.h"
 #include "globals.h"
+#include "unique_file.h"
 #include "utils.h"
 
 using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::os::ParcelFileDescriptor;
 using std::filesystem::is_empty;
 
 namespace android {
@@ -136,6 +139,16 @@
     return fd;
 }
 
+static void create_with_content(const std::string& path, uid_t owner, gid_t group, mode_t mode,
+                                const std::string& content) {
+    int fd = ::open(path.c_str(), O_RDWR | O_CREAT, mode);
+    EXPECT_NE(fd, -1);
+    EXPECT_TRUE(android::base::WriteStringToFd(content, fd));
+    EXPECT_EQ(::fchown(fd, owner, group), 0);
+    EXPECT_EQ(::fchmod(fd, mode), 0);
+    close(fd);
+}
+
 static void touch(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
     EXPECT_EQ(::close(create(path.c_str(), owner, group, mode)), 0);
 }
@@ -527,6 +540,94 @@
                                            externalStorageAppId, ceDataInodes, codePaths,
                                            &externalStorageSize));
 }
+
+class FsverityTest : public ServiceTest {
+protected:
+    binder::Status createFsveritySetupAuthToken(const std::string& path, int open_mode,
+                                                sp<IFsveritySetupAuthToken>* _aidl_return) {
+        unique_fd ufd(open(path.c_str(), open_mode));
+        EXPECT_GE(ufd.get(), 0) << "open failed: " << strerror(errno);
+        ParcelFileDescriptor rfd(std::move(ufd));
+        return service->createFsveritySetupAuthToken(std::move(rfd), kTestAppId, kTestUserId,
+                                                     _aidl_return);
+    }
+};
+
+TEST_F(FsverityTest, enableFsverity) {
+    const std::string path = kTestPath + "/foo";
+    create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
+    UniqueFile raii(/*fd=*/-1, path, [](const std::string& path) { unlink(path.c_str()); });
+
+    // Expect to fs-verity setup to succeed
+    sp<IFsveritySetupAuthToken> authToken;
+    binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(authToken != nullptr);
+
+    // Verity auth token works to enable fs-verity
+    int32_t errno_local;
+    status = service->enableFsverity(authToken, path, "fake.package.name", &errno_local);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(errno_local, 0);
+}
+
+TEST_F(FsverityTest, enableFsverity_nullAuthToken) {
+    const std::string path = kTestPath + "/foo";
+    create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
+    UniqueFile raii(/*fd=*/-1, path, [](const std::string& path) { unlink(path.c_str()); });
+
+    // Verity null auth token fails
+    sp<IFsveritySetupAuthToken> authToken;
+    int32_t errno_local;
+    binder::Status status =
+            service->enableFsverity(authToken, path, "fake.package.name", &errno_local);
+    EXPECT_FALSE(status.isOk());
+}
+
+TEST_F(FsverityTest, enableFsverity_differentFile) {
+    const std::string path = kTestPath + "/foo";
+    create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
+    UniqueFile raii(/*fd=*/-1, path, [](const std::string& path) { unlink(path.c_str()); });
+
+    // Expect to fs-verity setup to succeed
+    sp<IFsveritySetupAuthToken> authToken;
+    binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(authToken != nullptr);
+
+    // Verity auth token does not work for a different file
+    const std::string anotherPath = kTestPath + "/bar";
+    ASSERT_TRUE(android::base::WriteStringToFile("content", anotherPath));
+    UniqueFile raii2(/*fd=*/-1, anotherPath, [](const std::string& path) { unlink(path.c_str()); });
+    int32_t errno_local;
+    status = service->enableFsverity(authToken, anotherPath, "fake.package.name", &errno_local);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_NE(errno_local, 0);
+}
+
+TEST_F(FsverityTest, createFsveritySetupAuthToken_ReadonlyFdDoesNotAuthenticate) {
+    const std::string path = kTestPath + "/foo";
+    create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
+    UniqueFile raii(/*fd=*/-1, path, [](const std::string& path) { unlink(path.c_str()); });
+
+    // Expect the fs-verity setup to fail
+    sp<IFsveritySetupAuthToken> authToken;
+    binder::Status status = createFsveritySetupAuthToken(path, O_RDONLY, &authToken);
+    EXPECT_FALSE(status.isOk());
+}
+
+TEST_F(FsverityTest, createFsveritySetupAuthToken_UnownedFile) {
+    const std::string path = kTestPath + "/foo";
+    // Simulate world-writable file owned by another app
+    create_with_content(path, kTestAppUid + 1, kTestAppUid + 1, 0666, "content");
+    UniqueFile raii(/*fd=*/-1, path, [](const std::string& path) { unlink(path.c_str()); });
+
+    // Expect the fs-verity setup to fail
+    sp<IFsveritySetupAuthToken> authToken;
+    binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
+    EXPECT_FALSE(status.isOk());
+}
+
 static bool mkdirs(const std::string& path, mode_t mode) {
     struct stat sb;
     if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 92dc46e..ba6f671 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -101,6 +101,12 @@
 }
 
 prebuilt_etc {
+    name: "android.hardware.nfc.prebuilt.xml",
+    src: "android.hardware.nfc.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
     name: "android.hardware.reboot_escrow.prebuilt.xml",
     src: "android.hardware.reboot_escrow.xml",
     defaults: ["frameworks_native_data_etc_defaults"],
@@ -173,8 +179,8 @@
 }
 
 prebuilt_etc {
-    name: "android.hardware.threadnetwork.prebuilt.xml",
-    src: "android.hardware.threadnetwork.xml",
+    name: "android.hardware.thread_network.prebuilt.xml",
+    src: "android.hardware.thread_network.xml",
     defaults: ["frameworks_native_data_etc_defaults"],
 }
 
diff --git a/data/etc/android.hardware.threadnetwork.xml b/data/etc/android.hardware.thread_network.xml
similarity index 83%
rename from data/etc/android.hardware.threadnetwork.xml
rename to data/etc/android.hardware.thread_network.xml
index 9cbdc90..b116ed6 100644
--- a/data/etc/android.hardware.threadnetwork.xml
+++ b/data/etc/android.hardware.thread_network.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<!-- Adds the feature indicating support for the ThreadNetwork API -->
+<!-- Adds the feature indicating support for the Thread networking protocol -->
 <permissions>
-    <feature name="android.hardware.threadnetwork" />
+    <feature name="android.hardware.thread_network" />
 </permissions>
diff --git a/headers/media_plugin/media/openmax/OMX_AsString.h b/headers/media_plugin/media/openmax/OMX_AsString.h
index ce30b41..165a868 100644
--- a/headers/media_plugin/media/openmax/OMX_AsString.h
+++ b/headers/media_plugin/media/openmax/OMX_AsString.h
@@ -561,6 +561,7 @@
         case OMX_IndexConfigPriority:                   return "ConfigPriority";
         case OMX_IndexConfigOperatingRate:              return "ConfigOperatingRate";
         case OMX_IndexParamConsumerUsageBits:           return "ParamConsumerUsageBits";
+        case OMX_IndexParamConsumerUsageBits64:         return "ParamConsumerUsageBits64";
         case OMX_IndexConfigLatency:                    return "ConfigLatency";
         default:                                        return asString((OMX_INDEXTYPE)i, def);
     }
diff --git a/headers/media_plugin/media/openmax/OMX_IndexExt.h b/headers/media_plugin/media/openmax/OMX_IndexExt.h
index 0af40dd..5ddd719 100644
--- a/headers/media_plugin/media/openmax/OMX_IndexExt.h
+++ b/headers/media_plugin/media/openmax/OMX_IndexExt.h
@@ -105,6 +105,7 @@
     OMX_IndexConfigLowLatency,                      /**< reference: OMX_CONFIG_BOOLEANTYPE */
     OMX_IndexConfigAndroidTunnelPeek,               /**< reference: OMX_CONFIG_BOOLEANTYPE */
     OMX_IndexConfigAndroidTunnelPeekLegacyMode,     /**< reference: OMX_CONFIG_BOOLEANTYPE */
+    OMX_IndexParamConsumerUsageBits64,              /**< reference: OMX_PARAM_U64TYPE */
     OMX_IndexExtOtherEndUnused,
 
     /* Time configurations */
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 8d9955d..589df9a 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -261,7 +261,7 @@
 
 bool BpBinder::isDescriptorCached() const {
     Mutex::Autolock _l(mLock);
-    return mDescriptorCache.string() != kDescriptorUninit.string();
+    return mDescriptorCache.c_str() != kDescriptorUninit.c_str();
 }
 
 const String16& BpBinder::getInterfaceDescriptor() const
@@ -279,7 +279,7 @@
             Mutex::Autolock _l(mLock);
             // mDescriptorCache could have been assigned while the lock was
             // released.
-            if (mDescriptorCache.string() == kDescriptorUninit.string()) mDescriptorCache = res;
+            if (mDescriptorCache.c_str() == kDescriptorUninit.c_str()) mDescriptorCache = res;
         }
     }
 
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 08169f5..5ec4e8b 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -52,8 +52,8 @@
                 }
             } else {
                 // An exception was thrown back; fall through to return failure
-                ALOGD("openContentUri(%s) caught exception %d\n",
-                        String8(stringUri).string(), exceptionCode);
+                ALOGD("openContentUri(%s) caught exception %d\n", String8(stringUri).c_str(),
+                      exceptionCode);
             }
         }
         return fd;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 2408307..6034f2b 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -216,8 +216,8 @@
             if (res) {
                 if (startTime != 0) {
                     ALOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
-                            (int)((uptimeMillis()-startTime)/1000),
-                            String8(permission).string(), uid, pid);
+                          (int)((uptimeMillis() - startTime) / 1000), String8(permission).c_str(),
+                          uid, pid);
                 }
                 return res;
             }
@@ -225,7 +225,7 @@
             // Is this a permission failure, or did the controller go away?
             if (IInterface::asBinder(pc)->isBinderAlive()) {
                 if (logPermissionFailure) {
-                    ALOGW("Permission failure: %s from uid=%d pid=%d", String8(permission).string(),
+                    ALOGW("Permission failure: %s from uid=%d pid=%d", String8(permission).c_str(),
                           uid, pid);
                 }
                 return false;
@@ -246,7 +246,7 @@
             if (startTime == 0) {
                 startTime = uptimeMillis();
                 ALOGI("Waiting to check permission %s from uid=%d pid=%d",
-                        String8(permission).string(), uid, pid);
+                      String8(permission).c_str(), uid, pid);
             }
             sleep(1);
         } else {
@@ -295,7 +295,7 @@
     // retry interval in millisecond; note that vendor services stay at 100ms
     const useconds_t sleepTime = gSystemBootCompleted ? 1000 : 100;
 
-    ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
+    ALOGI("Waiting for service '%s' on '%s'...", String8(name).c_str(),
           ProcessState::self()->getDriverName().c_str());
 
     int n = 0;
@@ -306,12 +306,12 @@
         sp<IBinder> svc = checkService(name);
         if (svc != nullptr) {
             ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIi64 "ms",
-                  String8(name).string(), ProcessState::self()->getDriverName().c_str(),
+                  String8(name).c_str(), ProcessState::self()->getDriverName().c_str(),
                   uptimeMillis() - startTime);
             return svc;
         }
     }
-    ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
+    ALOGW("Service %s didn't start. Returning NULL", String8(name).c_str());
     return nullptr;
 }
 
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index 03553f3..5b1cb7e 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -428,7 +428,7 @@
 {
     String8 result;
     dump_l(result, what);
-    ALOGD("%s", result.string());
+    ALOGD("%s", result.c_str());
 }
 
 void SimpleBestFitAllocator::dump(String8& result,
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 9b685f9..5b34efc 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -854,7 +854,7 @@
 // Write RPC headers.  (previously just the interface token)
 status_t Parcel::writeInterfaceToken(const String16& interface)
 {
-    return writeInterfaceToken(interface.string(), interface.size());
+    return writeInterfaceToken(interface.c_str(), interface.size());
 }
 
 status_t Parcel::writeInterfaceToken(const char16_t* str, size_t len) {
@@ -918,7 +918,7 @@
 bool Parcel::enforceInterface(const String16& interface,
                               IPCThreadState* threadState) const
 {
-    return enforceInterface(interface.string(), interface.size(), threadState);
+    return enforceInterface(interface.c_str(), interface.size(), threadState);
 }
 
 bool Parcel::enforceInterface(const char16_t* interface,
@@ -977,8 +977,8 @@
             return true;
         } else {
             ALOGW("**** enforceInterface() expected '%s' but read '%s'",
-                  String8(interface, len).string(),
-                  String8(parcel_interface, parcel_interface_len).string());
+                  String8(interface, len).c_str(),
+                  String8(parcel_interface, parcel_interface_len).c_str());
             return false;
         }
     }
@@ -1376,7 +1376,7 @@
 
 status_t Parcel::writeString8(const String8& str)
 {
-    return writeString8(str.string(), str.size());
+    return writeString8(str.c_str(), str.size());
 }
 
 status_t Parcel::writeString8(const char* str, size_t len)
@@ -1399,7 +1399,7 @@
 
 status_t Parcel::writeString16(const String16& str)
 {
-    return writeString16(str.string(), str.size());
+    return writeString16(str.c_str(), str.size());
 }
 
 status_t Parcel::writeString16(const char16_t* str, size_t len)
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
index 670fd55..658686d 100644
--- a/libs/binder/PermissionCache.cpp
+++ b/libs/binder/PermissionCache.cpp
@@ -101,9 +101,8 @@
         nsecs_t t = -systemTime();
         granted = android::checkPermission(permission, pid, uid);
         t += systemTime();
-        ALOGD("checking %s for uid=%d => %s (%d us)",
-                String8(permission).string(), uid,
-                granted?"granted":"denied", (int)ns2us(t));
+        ALOGD("checking %s for uid=%d => %s (%d us)", String8(permission).c_str(), uid,
+              granted ? "granted" : "denied", (int)ns2us(t));
         pc.cache(permission, uid, granted);
     }
     return granted;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 02b0447..8ec4af9 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -401,9 +401,9 @@
 {
     if (mThreadPoolStarted) {
         String8 name = makeBinderThreadName();
-        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
+        ALOGV("Spawning new pooled thread, name=%s\n", name.c_str());
         sp<Thread> t = sp<PoolThread>::make(isMain);
-        t->run(name.string());
+        t->run(name.c_str());
         pthread_mutex_lock(&mThreadCountLock);
         mKernelStartedThreads++;
         pthread_mutex_unlock(&mThreadCountLock);
@@ -505,7 +505,7 @@
 }
 
 void ProcessState::giveThreadPoolName() {
-    androidSetThreadName( makeBinderThreadName().string() );
+    androidSetThreadName(makeBinderThreadName().c_str());
 }
 
 String8 ProcessState::getDriverName() {
diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp
index 44a9e3b..3246706 100644
--- a/libs/binder/RecordedTransaction.cpp
+++ b/libs/binder/RecordedTransaction.cpp
@@ -124,7 +124,7 @@
                        static_cast<int32_t>(timestamp.tv_nsec),
                        0};
 
-    t.mData.mInterfaceName = std::string(String8(interfaceName).string());
+    t.mData.mInterfaceName = std::string(String8(interfaceName).c_str());
     if (interfaceName.size() != t.mData.mInterfaceName.size()) {
         LOG(ERROR) << "Interface Name is not valid. Contains characters that aren't single byte "
                       "utf-8.";
diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h
index eb98042..50158c3 100644
--- a/libs/binder/include/binder/TextOutput.h
+++ b/libs/binder/include/binder/TextOutput.h
@@ -147,7 +147,7 @@
 
 inline TextOutput& operator<<(TextOutput& to, const String16& val)
 {
-    to << String8(val).string();
+    to << String8(val).c_str();
     return to;
 }
 
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 672d6cf..57a38dc 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -11,9 +11,6 @@
     name: "libbinder_rs",
     crate_name: "binder",
     srcs: ["src/lib.rs"],
-    shared_libs: [
-        "libutils",
-    ],
     rustlibs: [
         "libbinder_ndk_sys",
         "libdowncast_rs",
diff --git a/libs/binder/rust/sys/lib.rs b/libs/binder/rust/sys/lib.rs
index 1d1a295..c5c847b 100644
--- a/libs/binder/rust/sys/lib.rs
+++ b/libs/binder/rust/sys/lib.rs
@@ -19,7 +19,20 @@
 use std::error::Error;
 use std::fmt;
 
-include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+#[cfg(not(target_os = "trusty"))]
+mod bindings {
+    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+}
+
+// Trusty puts the full path to the auto-generated file in BINDGEN_INC_FILE
+// and builds it with warnings-as-errors, so we need to use #[allow(bad_style)]
+#[cfg(target_os = "trusty")]
+#[allow(bad_style)]
+mod bindings {
+    include!(env!("BINDGEN_INC_FILE"));
+}
+
+pub use bindings::*;
 
 impl Error for android_c_interface_StatusCode {}
 
diff --git a/libs/binder/rust/tests/parcel_fuzzer/Android.bp b/libs/binder/rust/tests/parcel_fuzzer/Android.bp
index ac96823..6eb707b 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/rust/tests/parcel_fuzzer/Android.bp
@@ -3,19 +3,12 @@
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
-rust_fuzz {
-    name: "parcel_fuzzer_rs",
-    srcs: [
-        "parcel_fuzzer.rs",
-    ],
+rust_defaults {
+    name: "service_fuzzer_defaults_rs",
     rustlibs: [
-        "libarbitrary",
-        "libnum_traits",
         "libbinder_rs",
         "libbinder_random_parcel_rs",
-        "binderReadParcelIface-rust",
     ],
-
     fuzz_config: {
         cc: [
             "waghpawan@google.com",
@@ -26,3 +19,18 @@
         hotlists: ["4637097"],
     },
 }
+
+rust_fuzz {
+    name: "parcel_fuzzer_rs",
+    srcs: [
+        "parcel_fuzzer.rs",
+    ],
+    defaults: [
+        "service_fuzzer_defaults_rs",
+    ],
+    rustlibs: [
+        "libarbitrary",
+        "libnum_traits",
+        "binderReadParcelIface-rust",
+    ],
+}
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp
index 2537ce0..84130c1 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp
@@ -19,18 +19,10 @@
     srcs: [
         "service_fuzzer.rs",
     ],
+    defaults: [
+        "service_fuzzer_defaults_rs",
+    ],
     rustlibs: [
-        "libbinder_rs",
-        "libbinder_random_parcel_rs",
         "testServiceInterface-rust",
     ],
-    fuzz_config: {
-        cc: [
-            "waghpawan@google.com",
-            "smoreland@google.com",
-        ],
-        triage_assignee: "waghpawan@google.com",
-        // hotlist "AIDL fuzzers bugs" on buganizer
-        hotlists: ["4637097"],
-    },
 }
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 0d1503e..383795e 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -129,3 +129,18 @@
     ],
     export_include_dirs: ["include_random_parcel_seeds"],
 }
+
+cc_binary_host {
+    name: "binder2corpus",
+    static_libs: [
+        "libbinder_random_parcel_seeds",
+    ],
+    srcs: [
+        "binder2corpus/binder2corpus.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libutils",
+    ],
+}
diff --git a/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md b/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md
new file mode 100644
index 0000000..59bf9f3
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md
@@ -0,0 +1,31 @@
+# binder2corpus
+
+This tool converts recordings generated by record_binder tool to fuzzer seeds for fuzzService.
+
+# Steps to add corpus:
+
+## Start recording the service binder
+ex. record_binder start manager
+
+## Run test on device or keep device idle
+ex. atest servicemanager_test
+
+## Stop the recording
+record_binder stop manager
+
+## Pull the recording on host
+Recordings are present on device at /data/local/recordings/<service_name>. Use adb pull.
+Use inspect command of record_binder to check if there are some transactions captured.
+ex. record_binder inspect manager
+
+## run corpus generator tool
+binder2corpus <recording_path> <dir_to_write_corpus>
+
+## Build fuzzer and sync data directory
+ex. m servicemanager_fuzzer && adb sync data
+
+## Push corpus on device
+ex. adb push servicemanager_fuzzer_corpus/ /data/fuzz/x86_64/servicemanager_fuzzer/
+
+## Run fuzzer with corpus directory as argument
+ex. adb shell /data/fuzz/x86_64/servicemanager_fuzzer/servicemanager_fuzzer /data/fuzz/x86_64/servicemanager_fuzzer/servicemanager_fuzzer_corpus
\ No newline at end of file
diff --git a/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp
new file mode 100644
index 0000000..c0fdaea
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <binder/RecordedTransaction.h>
+
+#include <fuzzseeds/random_parcel_seeds.h>
+
+#include <sys/prctl.h>
+
+using android::generateSeedsFromRecording;
+using android::status_t;
+using android::base::unique_fd;
+using android::binder::debug::RecordedTransaction;
+
+status_t generateCorpus(const char* recordingPath, const char* corpusDir) {
+    unique_fd fd(open(recordingPath, O_RDONLY));
+    if (!fd.ok()) {
+        std::cerr << "Failed to open recording file at path " << recordingPath
+                  << " with error: " << strerror(errno) << '\n';
+        return android::BAD_VALUE;
+    }
+
+    if (auto res = mkdir(corpusDir, 0766); res != 0) {
+        std::cerr
+                << "Failed to create corpus directory at path. Delete directory if already exists: "
+                << corpusDir << std::endl;
+        return android::BAD_VALUE;
+    }
+
+    int transactionNumber = 0;
+    while (auto transaction = RecordedTransaction::fromFile(fd)) {
+        ++transactionNumber;
+        std::string filePath = std::string(corpusDir) + std::string("transaction_") +
+                std::to_string(transactionNumber);
+        constexpr int openFlags = O_WRONLY | O_CREAT | O_BINARY | O_CLOEXEC;
+        android::base::unique_fd corpusFd(open(filePath.c_str(), openFlags, 0666));
+        if (!corpusFd.ok()) {
+            std::cerr << "Failed to open fd. Path " << filePath
+                      << " with error: " << strerror(errno) << std::endl;
+            return android::UNKNOWN_ERROR;
+        }
+        generateSeedsFromRecording(corpusFd, transaction.value());
+    }
+
+    if (transactionNumber == 0) {
+        std::cerr << "No valid transaction has been found in recording file:  " << recordingPath
+                  << std::endl;
+        return android::BAD_VALUE;
+    }
+
+    return android::NO_ERROR;
+}
+
+void printHelp(const char* toolName) {
+    std::cout << "Usage: \n\n"
+              << toolName
+              << " <recording_path> <destination_directory> \n\n*Use "
+                 "record_binder tool for recording binder transactions."
+              << std::endl;
+}
+
+int main(int argc, char** argv) {
+    if (argc != 3) {
+        printHelp(argv[0]);
+        return 1;
+    }
+    const char* sourcePath = argv[1];
+    const char* corpusDir = argv[2];
+    if (android::NO_ERROR != generateCorpus(sourcePath, corpusDir)) {
+        std::cerr << "Failed to generate fuzzer corpus." << std::endl;
+        return 1;
+    }
+    return 0;
+}
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index 47d2a0a..93ac116 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -60,8 +60,15 @@
 
     while (provider.remaining_bytes() > 0) {
         // Most of the AIDL services will have small set of transaction codes.
-        uint32_t code = provider.ConsumeBool() ? provider.ConsumeIntegral<uint32_t>()
-                                               : provider.ConsumeIntegralInRange<uint32_t>(0, 100);
+        // TODO(b/295942369) : Add remaining transact codes from IBinder.h
+        uint32_t code = provider.ConsumeBool()
+                ? provider.ConsumeIntegral<uint32_t>()
+                : provider.PickValueInArray<int64_t>(
+                          {provider.ConsumeIntegralInRange<uint32_t>(0, 100),
+                           IBinder::DUMP_TRANSACTION, IBinder::PING_TRANSACTION,
+                           IBinder::SHELL_COMMAND_TRANSACTION, IBinder::INTERFACE_TRANSACTION,
+                           IBinder::SYSPROPS_TRANSACTION, IBinder::EXTENSION_TRANSACTION,
+                           IBinder::TWEET_TRANSACTION, IBinder::LIKE_TRANSACTION});
         uint32_t flags = provider.ConsumeIntegral<uint32_t>();
         Parcel data;
         // for increased fuzz coverage
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
index 96092b1..690c39a 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/Android.bp
@@ -36,8 +36,8 @@
         triage_assignee: "waghpawan@google.com",
 
         // This fuzzer should be used only test fuzzService locally
-        fuzz_on_haiku_host: true,
-        fuzz_on_haiku_device: true,
+        fuzz_on_haiku_host: false,
+        fuzz_on_haiku_device: false,
     },
 }
 
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
index 46205d7..d2fa581 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
@@ -33,6 +33,9 @@
     ON_KNOWN_UID,
     ON_SYSTEM_AID,
     ON_ROOT_AID,
+    ON_DUMP_TRANSACT,
+    ON_SHELL_CMD_TRANSACT,
+    CRASH_ALWAYS,
 };
 
 // This service is to verify that fuzzService is functioning properly
@@ -92,6 +95,16 @@
         return Status::ok();
     }
 
+    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override {
+        if (mCrash == CrashType::ON_DUMP_TRANSACT && code == DUMP_TRANSACTION) {
+            LOG_ALWAYS_FATAL("Expected crash, DUMP.");
+        } else if (mCrash == CrashType::ON_SHELL_CMD_TRANSACT &&
+                   code == SHELL_COMMAND_TRANSACTION) {
+            LOG_ALWAYS_FATAL("Expected crash, SHELL_CMD.");
+        }
+        return BnTestService::onTransact(code, data, reply, flags);
+    }
+
 private:
     CrashType mCrash;
 };
@@ -100,8 +113,10 @@
 
 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
     if (*argc < 2) {
-        printf("You must specify at least one argument\n");
-        exit(0); // success because this is a crash test
+        // This fuzzer is also used as test fuzzer to check infra pipeline.
+        // It should always run and find a crash in TestService.
+        gCrashType = CrashType::CRASH_ALWAYS;
+        return 0;
     }
 
     std::string arg = std::string((*argv)[1]);
@@ -121,6 +136,10 @@
         gCrashType = CrashType::ON_ROOT_AID;
     } else if (arg == "BINDER") {
         gCrashType = CrashType::ON_BINDER;
+    } else if (arg == "DUMP") {
+        gCrashType = CrashType::ON_DUMP_TRANSACT;
+    } else if (arg == "SHELL_CMD") {
+        gCrashType = CrashType::ON_SHELL_CMD_TRANSACT;
     } else {
         printf("INVALID ARG\n");
         exit(0); // success because this is a crash test
@@ -130,6 +149,9 @@
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (gCrashType == CrashType::CRASH_ALWAYS) {
+        LOG_ALWAYS_FATAL("Expected crash, This fuzzer will always crash.");
+    }
     auto service = sp<TestService>::make(gCrashType);
     fuzzService(service, FuzzedDataProvider(data, size));
     return 0;
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh b/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
index 25906d8..c447bff 100755
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
@@ -27,7 +27,7 @@
     exit 1
 fi
 
-for CRASH_TYPE in PLAIN KNOWN_UID AID_SYSTEM AID_ROOT BINDER; do
+for CRASH_TYPE in PLAIN KNOWN_UID AID_SYSTEM AID_ROOT BINDER DUMP SHELL_CMD; do
     echo "INFO: Running fuzzer : test_service_fuzzer_should_crash $CRASH_TYPE"
 
     ./test_service_fuzzer_should_crash "$CRASH_TYPE" -max_total_time=30 &>"$FUZZER_OUT"
diff --git a/libs/binder/trusty/rust/binder_ndk_sys/rules.mk b/libs/binder/trusty/rust/binder_ndk_sys/rules.mk
new file mode 100644
index 0000000..672d9b7
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_ndk_sys/rules.mk
@@ -0,0 +1,38 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_DIR := $(LOCAL_DIR)/../../..
+LIBBINDER_NDK_BINDGEN_FLAG_FILE := \
+	$(LIBBINDER_DIR)/rust/libbinder_ndk_bindgen_flags.txt
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LIBBINDER_DIR)/rust/sys/lib.rs
+
+MODULE_CRATE_NAME := binder_ndk_sys
+
+MODULE_LIBRARY_DEPS += \
+	$(LIBBINDER_DIR)/trusty \
+	$(LIBBINDER_DIR)/trusty/ndk \
+	trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_SRC_HEADER := $(LIBBINDER_DIR)/rust/sys/BinderBindings.hpp
+
+# Add the flags from the flag file
+MODULE_BINDGEN_FLAGS += $(shell cat $(LIBBINDER_NDK_BINDGEN_FLAG_FILE))
+MODULE_SRCDEPS += $(LIBBINDER_NDK_BINDGEN_FLAG_FILE)
+
+include make/library.mk
diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp
index 96dcce1..3823393 100644
--- a/libs/fakeservicemanager/Android.bp
+++ b/libs/fakeservicemanager/Android.bp
@@ -17,6 +17,7 @@
     shared_libs: [
         "libbinder",
         "libutils",
+        "liblog",
     ],
     target: {
         darwin: {
@@ -40,3 +41,41 @@
     static_libs: ["libgmock"],
     local_include_dirs: ["include"],
 }
+
+rust_bindgen {
+    name: "libfakeservicemanager_bindgen",
+    crate_name: "fakeservicemanager_bindgen",
+    host_supported: true,
+    wrapper_src: "rust/wrappers/FakeServiceManagerWrapper.hpp",
+    source_stem: "bindings",
+    visibility: [":__subpackages__"],
+    bindgen_flags: [
+        "--allowlist-function",
+        "setupFakeServiceManager",
+        "--allowlist-function",
+        "clearFakeServiceManager",
+    ],
+    shared_libs: [
+        "libc++",
+        "libbinder",
+        "libfakeservicemanager",
+    ],
+}
+
+rust_library {
+    name: "libfakeservicemanager_rs",
+    crate_name: "fakeservicemanager_rs",
+    host_supported: true,
+    srcs: [
+        "rust/src/lib.rs",
+    ],
+    shared_libs: [
+        "libc++",
+        "libfakeservicemanager",
+    ],
+    rustlibs: [
+        "libfakeservicemanager_bindgen",
+    ],
+    lints: "none",
+    clippy_lints: "none",
+}
diff --git a/libs/fakeservicemanager/FakeServiceManager.cpp b/libs/fakeservicemanager/FakeServiceManager.cpp
index 80661c1..ae242f3 100644
--- a/libs/fakeservicemanager/FakeServiceManager.cpp
+++ b/libs/fakeservicemanager/FakeServiceManager.cpp
@@ -16,6 +16,10 @@
 
 #include "fakeservicemanager/FakeServiceManager.h"
 
+using android::sp;
+using android::FakeServiceManager;
+using android::setDefaultServiceManager;
+
 namespace android {
 
 FakeServiceManager::FakeServiceManager() {}
@@ -80,7 +84,7 @@
     for (const auto& [registeredName, service] : mNameToService) {
         (void) service;
         if (registeredName.startsWith(prefix)) {
-            out.add(String16(registeredName.string() + prefix.size()));
+            out.add(String16(registeredName.c_str() + prefix.size()));
         }
     }
     return out;
@@ -123,3 +127,24 @@
     mNameToService.clear();
 }
 }  // namespace android
+
+[[clang::no_destroy]] static sp<FakeServiceManager> gFakeServiceManager;
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+
+extern "C" {
+
+// Setup FakeServiceManager to mock dependencies in test using this API for rust backend
+void setupFakeServiceManager() {
+    /* Create a FakeServiceManager instance and add required services */
+    std::call_once(gSmOnce, [&]() {
+        gFakeServiceManager = new FakeServiceManager();
+        android::setDefaultServiceManager(gFakeServiceManager);
+    });
+}
+
+// Clear existing services from Fake SM for rust backend
+void clearFakeServiceManager() {
+    LOG_ALWAYS_FATAL_IF(gFakeServiceManager == nullptr, "Fake Service Manager is not available. Forgot to call setupFakeServiceManager?");
+    gFakeServiceManager->clear();
+}
+} //extern "C"
\ No newline at end of file
diff --git a/libs/fakeservicemanager/rust/src/lib.rs b/libs/fakeservicemanager/rust/src/lib.rs
new file mode 100644
index 0000000..5b7e756
--- /dev/null
+++ b/libs/fakeservicemanager/rust/src/lib.rs
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+use fakeservicemanager_bindgen::{clearFakeServiceManager, setupFakeServiceManager};
+// Setup FakeServiceManager for testing and fuzzing purposes
+pub fn setup_fake_service_manager() {
+    unsafe {
+        // Safety: This API creates a new FakeSm object which will be always valid and sets up
+        // defaultServiceManager
+        setupFakeServiceManager();
+    }
+}
+
+// Setup FakeServiceManager for testing and fuzzing purposes
+pub fn clear_fake_service_manager() {
+    unsafe {
+        // Safety: This API clears all registered services with Fake SM. This should be only used
+        // setupFakeServiceManager is already called.
+        clearFakeServiceManager();
+    }
+}
diff --git a/libs/fakeservicemanager/rust/wrappers/FakeServiceManagerWrapper.hpp b/libs/fakeservicemanager/rust/wrappers/FakeServiceManagerWrapper.hpp
new file mode 100644
index 0000000..1f5923a
--- /dev/null
+++ b/libs/fakeservicemanager/rust/wrappers/FakeServiceManagerWrapper.hpp
@@ -0,0 +1,25 @@
+/*
+ * 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 "fakeservicemanager/FakeServiceManager.h"
+
+extern "C" {
+    // Setup FakeServiceManager to mock dependencies in test using this API
+    void setupFakeServiceManager();
+
+    // Clear existing services from Fake SM.
+    void clearFakeServiceManager();
+} // extern "C"
diff --git a/libs/fakeservicemanager/test_sm.cpp b/libs/fakeservicemanager/test_sm.cpp
index 6fc21c6..cb6784c0 100644
--- a/libs/fakeservicemanager/test_sm.cpp
+++ b/libs/fakeservicemanager/test_sm.cpp
@@ -22,6 +22,7 @@
 #include <binder/IServiceManager.h>
 
 #include "fakeservicemanager/FakeServiceManager.h"
+#include "rust/wrappers/FakeServiceManagerWrapper.hpp"
 
 using android::sp;
 using android::BBinder;
@@ -31,6 +32,7 @@
 using android::FakeServiceManager;
 using android::String16;
 using android::IServiceManager;
+using android::defaultServiceManager;
 using testing::ElementsAre;
 
 static sp<IBinder> getBinder() {
@@ -83,7 +85,7 @@
     EXPECT_EQ(sm->getService(String16("foo")), service);
 }
 
-TEST(GetService, NonExistant) {
+TEST(GetService, NonExistent) {
     auto sm = new FakeServiceManager();
 
     EXPECT_EQ(sm->getService(String16("foo")), nullptr);
@@ -108,7 +110,7 @@
         String16("sd")));
 }
 
-TEST(WaitForService, NonExistant) {
+TEST(WaitForService, NonExistent) {
     auto sm = new FakeServiceManager();
 
     EXPECT_EQ(sm->waitForService(String16("foo")), nullptr);
@@ -124,7 +126,7 @@
     EXPECT_EQ(sm->waitForService(String16("foo")), service);
 }
 
-TEST(IsDeclared, NonExistant) {
+TEST(IsDeclared, NonExistent) {
     auto sm = new FakeServiceManager();
 
     EXPECT_FALSE(sm->isDeclared(String16("foo")));
@@ -139,3 +141,31 @@
 
     EXPECT_TRUE(sm->isDeclared(String16("foo")));
 }
+
+TEST(SetupFakeServiceManager, NonExistent) {
+    setupFakeServiceManager();
+
+    EXPECT_EQ(defaultServiceManager()->getService(String16("foo")), nullptr);
+}
+
+TEST(SetupFakeServiceManager, GetExistingService) {
+    setupFakeServiceManager();
+    sp<IBinder> service = getBinder();
+
+    EXPECT_EQ(defaultServiceManager()->addService(String16("foo"), service, false /*allowIsolated*/,
+    IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
+
+    EXPECT_EQ(defaultServiceManager()->getService(String16("foo")), service);
+    clearFakeServiceManager();
+}
+
+TEST(ClearFakeServiceManager, GetServiceAfterClear) {
+    setupFakeServiceManager();
+
+    sp<IBinder> service = getBinder();
+    EXPECT_EQ(defaultServiceManager()->addService(String16("foo"), service, false /*allowIsolated*/,
+    IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
+
+    clearFakeServiceManager();
+    EXPECT_EQ(defaultServiceManager()->getService(String16("foo")), nullptr);
+}
\ No newline at end of file
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 5f5f85a..64f8704 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -60,6 +60,17 @@
 typedef bool (*fpANGLEFreeRulesHandle)(void* handle);
 typedef bool (*fpANGLEFreeSystemInfoHandle)(void* handle);
 
+namespace {
+static bool isVndkEnabled() {
+#ifdef __BIONIC__
+    // TODO(b/290159430) Use ro.vndk.version to check if VNDK is enabled instead
+    static bool isVndkEnabled = !android::base::GetBoolProperty("ro.vndk.deprecate", false);
+    return isVndkEnabled;
+#endif
+    return false;
+}
+} // namespace
+
 namespace android {
 
 enum NativeLibrary {
@@ -71,6 +82,8 @@
         {"/apex/com.android.vndk.v{}/etc/llndk.libraries.{}.txt",
          "/apex/com.android.vndk.v{}/etc/vndksp.libraries.{}.txt"};
 
+static const char* kLlndkLibrariesTxtPath = "/system/etc/llndk.libraries.txt";
+
 static std::string vndkVersionStr() {
 #ifdef __BIONIC__
     return base::GetProperty("ro.vndk.version", "");
@@ -108,8 +121,14 @@
 }
 
 static const std::string getSystemNativeLibraries(NativeLibrary type) {
-    std::string nativeLibrariesSystemConfig = kNativeLibrariesSystemConfigPath[type];
-    insertVndkVersionStr(&nativeLibrariesSystemConfig);
+    std::string nativeLibrariesSystemConfig = "";
+
+    if (!isVndkEnabled() && type == NativeLibrary::LLNDK) {
+        nativeLibrariesSystemConfig = kLlndkLibrariesTxtPath;
+    } else {
+        nativeLibrariesSystemConfig = kNativeLibrariesSystemConfigPath[type];
+        insertVndkVersionStr(&nativeLibrariesSystemConfig);
+    }
 
     std::vector<std::string> soNames;
     if (!readConfig(nativeLibrariesSystemConfig, &soNames)) {
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index f50bc20..e6331e7 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -24,11 +24,11 @@
 #include <gui/BufferItem.h>
 #include <gui/BufferItemConsumer.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__)
 
 namespace android {
 
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 7f7a043..db51356 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -46,23 +46,23 @@
 
 // Macros for include BufferQueueCore information in log messages
 #define BQ_LOGV(x, ...)                                                                           \
-    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGD(x, ...)                                                                           \
-    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGI(x, ...)                                                                           \
-    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGW(x, ...)                                                                           \
-    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGE(x, ...)                                                                           \
-    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 
@@ -297,8 +297,7 @@
         // decrease.
         mCore->mDequeueCondition.notify_all();
 
-        ATRACE_INT(mCore->mConsumerName.string(),
-                static_cast<int32_t>(mCore->mQueue.size()));
+        ATRACE_INT(mCore->mConsumerName.c_str(), static_cast<int32_t>(mCore->mQueue.size()));
 #ifndef NO_BINDER
         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
 #endif
@@ -717,7 +716,7 @@
 
 status_t BufferQueueConsumer::setConsumerName(const String8& name) {
     ATRACE_CALL();
-    BQ_LOGV("setConsumerName: '%s'", name.string());
+    BQ_LOGV("setConsumerName: '%s'", name.c_str());
     std::lock_guard<std::mutex> lock(mCore->mMutex);
     mCore->mConsumerName = name;
     mConsumerName = name;
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 2930154..648db67 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -41,20 +41,20 @@
 namespace android {
 
 // Macros for include BufferQueueCore information in log messages
-#define BQ_LOGV(x, ...)                                                                           \
-    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(), mUniqueId, \
+#define BQ_LOGV(x, ...)                                                                          \
+    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
-#define BQ_LOGD(x, ...)                                                                           \
-    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(), mUniqueId, \
+#define BQ_LOGD(x, ...)                                                                          \
+    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
-#define BQ_LOGI(x, ...)                                                                           \
-    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(), mUniqueId, \
+#define BQ_LOGI(x, ...)                                                                          \
+    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
-#define BQ_LOGW(x, ...)                                                                           \
-    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(), mUniqueId, \
+#define BQ_LOGW(x, ...)                                                                          \
+    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
-#define BQ_LOGE(x, ...)                                                                           \
-    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(), mUniqueId, \
+#define BQ_LOGE(x, ...)                                                                          \
+    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
 
 static String8 getUniqueName() {
@@ -146,23 +146,23 @@
 void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    outResult->appendFormat("%s- BufferQueue ", prefix.string());
+    outResult->appendFormat("%s- BufferQueue ", prefix.c_str());
     outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
                             mMaxAcquiredBufferCount, mMaxDequeuedBufferCount);
-    outResult->appendFormat("%s  mDequeueBufferCannotBlock=%d mAsyncMode=%d\n", prefix.string(),
+    outResult->appendFormat("%s  mDequeueBufferCannotBlock=%d mAsyncMode=%d\n", prefix.c_str(),
                             mDequeueBufferCannotBlock, mAsyncMode);
-    outResult->appendFormat("%s  mQueueBufferCanDrop=%d mLegacyBufferDrop=%d\n", prefix.string(),
+    outResult->appendFormat("%s  mQueueBufferCanDrop=%d mLegacyBufferDrop=%d\n", prefix.c_str(),
                             mQueueBufferCanDrop, mLegacyBufferDrop);
-    outResult->appendFormat("%s  default-size=[%dx%d] default-format=%d ", prefix.string(),
+    outResult->appendFormat("%s  default-size=[%dx%d] default-format=%d ", prefix.c_str(),
                             mDefaultWidth, mDefaultHeight, mDefaultBufferFormat);
-    outResult->appendFormat("%s  transform-hint=%02x frame-counter=%" PRIu64 "\n", prefix.string(),
+    outResult->appendFormat("%s  transform-hint=%02x frame-counter=%" PRIu64 "\n", prefix.c_str(),
                             mTransformHint, mFrameCounter);
-    outResult->appendFormat("%s  mTransformHintInUse=%02x mAutoPrerotation=%d\n", prefix.string(),
+    outResult->appendFormat("%s  mTransformHintInUse=%02x mAutoPrerotation=%d\n", prefix.c_str(),
                             mTransformHintInUse, mAutoPrerotation);
 
-    outResult->appendFormat("%sFIFO(%zu):\n", prefix.string(), mQueue.size());
+    outResult->appendFormat("%sFIFO(%zu):\n", prefix.c_str(), mQueue.size());
 
-    outResult->appendFormat("%s(mConsumerName=%s, ", prefix.string(), mConsumerName.string());
+    outResult->appendFormat("%s(mConsumerName=%s, ", prefix.c_str(), mConsumerName.c_str());
 
     outResult->appendFormat("mConnectedApi=%d, mConsumerUsageBits=%" PRIu64 ", ", mConnectedApi,
                             mConsumerUsageBits);
@@ -173,12 +173,11 @@
     getProcessName(mConnectedPid, producerProcName);
     getProcessName(pid, consumerProcName);
     outResult->appendFormat("mId=%" PRIx64 ", producer=[%d:%s], consumer=[%d:%s])\n", mUniqueId,
-                            mConnectedPid, producerProcName.string(), pid,
-                            consumerProcName.string());
+                            mConnectedPid, producerProcName.c_str(), pid, consumerProcName.c_str());
     Fifo::const_iterator current(mQueue.begin());
     while (current != mQueue.end()) {
         double timestamp = current->mTimestamp / 1e9;
-        outResult->appendFormat("%s  %02d:%p ", prefix.string(), current->mSlot,
+        outResult->appendFormat("%s  %02d:%p ", prefix.c_str(), current->mSlot,
                                 current->mGraphicBuffer.get());
         outResult->appendFormat("crop=[%d,%d,%d,%d] ", current->mCrop.left, current->mCrop.top,
                                 current->mCrop.right, current->mCrop.bottom);
@@ -187,12 +186,12 @@
         ++current;
     }
 
-    outResult->appendFormat("%sSlots:\n", prefix.string());
+    outResult->appendFormat("%sSlots:\n", prefix.c_str());
     for (int s : mActiveBuffers) {
         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
         // A dequeued buffer might be null if it's still being allocated
         if (buffer.get()) {
-            outResult->appendFormat("%s %s[%02d:%p] ", prefix.string(),
+            outResult->appendFormat("%s %s[%02d:%p] ", prefix.c_str(),
                                     (mSlots[s].mBufferState.isAcquired()) ? ">" : " ", s,
                                     buffer.get());
             outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
@@ -200,14 +199,14 @@
             outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
                                     buffer->stride, buffer->format);
         } else {
-            outResult->appendFormat("%s  [%02d:%p] ", prefix.string(), s, buffer.get());
+            outResult->appendFormat("%s  [%02d:%p] ", prefix.c_str(), s, buffer.get());
             outResult->appendFormat("state=%-8s frame=%" PRIu64 "\n",
                                     mSlots[s].mBufferState.string(), mSlots[s].mFrameNumber);
         }
     }
     for (int s : mFreeBuffers) {
         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
-        outResult->appendFormat("%s  [%02d:%p] ", prefix.string(), s, buffer.get());
+        outResult->appendFormat("%s  [%02d:%p] ", prefix.c_str(), s, buffer.get());
         outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
                                 buffer->handle, mSlots[s].mFrameNumber);
         outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
@@ -216,7 +215,7 @@
 
     for (int s : mFreeSlots) {
         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
-        outResult->appendFormat("%s  [%02d:%p] state=%-8s\n", prefix.string(), s, buffer.get(),
+        outResult->appendFormat("%s  [%02d:%p] state=%-8s\n", prefix.c_str(), s, buffer.get(),
                                 mSlots[s].mBufferState.string());
     }
 }
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index f934680..36c2e58 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -46,23 +46,23 @@
 
 // Macros for include BufferQueueCore information in log messages
 #define BQ_LOGV(x, ...)                                                                           \
-    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGD(x, ...)                                                                           \
-    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGI(x, ...)                                                                           \
-    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGW(x, ...)                                                                           \
-    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 #define BQ_LOGE(x, ...)                                                                           \
-    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.string(),            \
+    ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(),             \
           mCore->mUniqueId, mCore->mConnectedApi, mCore->mConnectedPid, (mCore->mUniqueId) >> 32, \
           ##__VA_ARGS__)
 
@@ -554,9 +554,9 @@
 
     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
-        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
-                width, height, format, BQ_LAYER_COUNT, usage,
-                {mConsumerName.string(), mConsumerName.size()});
+        sp<GraphicBuffer> graphicBuffer =
+                new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage,
+                                  {mConsumerName.c_str(), mConsumerName.size()});
 
         status_t error = graphicBuffer->initCheck();
 
@@ -1018,8 +1018,7 @@
         output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
         output->nextFrameNumber = mCore->mFrameCounter + 1;
 
-        ATRACE_INT(mCore->mConsumerName.string(),
-                static_cast<int32_t>(mCore->mQueue.size()));
+        ATRACE_INT(mCore->mConsumerName.c_str(), static_cast<int32_t>(mCore->mQueue.size()));
 #ifndef NO_BINDER
         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
 #endif
@@ -1446,7 +1445,7 @@
 
             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
             allocUsage = usage | mCore->mConsumerUsageBits;
-            allocName.assign(mCore->mConsumerName.string(), mCore->mConsumerName.size());
+            allocName.assign(mCore->mConsumerName.c_str(), mCore->mConsumerName.size());
 
             mCore->mIsAllocating = true;
         } // Autolock scope
@@ -1548,7 +1547,7 @@
 String8 BufferQueueProducer::getConsumerName() const {
     ATRACE_CALL();
     std::lock_guard<std::mutex> lock(mCore->mMutex);
-    BQ_LOGV("getConsumerName: %s", mConsumerName.string());
+    BQ_LOGV("getConsumerName: %s", mConsumerName.c_str());
     return mConsumerName;
 }
 
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 9f91d9d..b625c3f 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -41,11 +41,11 @@
 #include <utils/Trace.h>
 
 // Macros for including the ConsumerBase name in log messages
-#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 namespace android {
 
@@ -86,8 +86,10 @@
     // be done by ConsumerBase::onLastStrongRef(), but it's possible for a
     // derived class to override that method and not call
     // ConsumerBase::onLastStrongRef().
-    LOG_ALWAYS_FATAL_IF(!mAbandoned, "[%s] ~ConsumerBase was called, but the "
-        "consumer is not abandoned!", mName.string());
+    LOG_ALWAYS_FATAL_IF(!mAbandoned,
+                        "[%s] ~ConsumerBase was called, but the "
+                        "consumer is not abandoned!",
+                        mName.c_str());
 }
 
 void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) {
@@ -451,7 +453,7 @@
     // them to get an accurate timestamp.
     if (currentStatus == incomingStatus) {
         char fenceName[32] = {};
-        snprintf(fenceName, 32, "%.28s:%d", mName.string(), slot);
+        snprintf(fenceName, 32, "%.28s:%d", mName.c_str(), slot);
         sp<Fence> mergedFence = Fence::merge(
                 fenceName, mSlots[slot].mFence, fence);
         if (!mergedFence.get()) {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index a626970..3031fa1 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -23,11 +23,11 @@
 #include <gui/BufferItem.h>
 #include <utils/Log.h>
 
-#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define CC_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 namespace android {
 
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index b3647d6..d49489c 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -52,11 +52,11 @@
 namespace android {
 
 // Macros for including the GLConsumer name in log messages
-#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 static const struct {
     uint32_t width, height;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 05beb07..6d44f10 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1056,7 +1056,7 @@
     sp<IBinder> display = nullptr;
     binder::Status status =
             ComposerServiceAIDL::getComposerService()->createDisplay(std::string(
-                                                                             displayName.string()),
+                                                                             displayName.c_str()),
                                                                      secure, &display);
     return status.isOk() ? display : nullptr;
 }
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 8d0828d..22c2be7 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -34,13 +34,13 @@
 #include <mutex>
 #include <condition_variable>
 
-#define ATRACE_BUFFER_INDEX(index)                                                         \
-    do {                                                                                   \
-        if (ATRACE_ENABLED()) {                                                            \
-            char ___traceBuf[1024];                                                        \
-            snprintf(___traceBuf, 1024, "%s: %d", mCore->mConsumerName.string(), (index)); \
-            android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);                    \
-        }                                                                                  \
+#define ATRACE_BUFFER_INDEX(index)                                                        \
+    do {                                                                                  \
+        if (ATRACE_ENABLED()) {                                                           \
+            char ___traceBuf[1024];                                                       \
+            snprintf(___traceBuf, 1024, "%s: %d", mCore->mConsumerName.c_str(), (index)); \
+            android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);                   \
+        }                                                                                 \
     } while (false)
 
 namespace android {
diff --git a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
index 004d875..32dc88b 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h
@@ -298,7 +298,7 @@
     }
 
     Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
-        _hidl_cb(mBase->getConsumerName().string());
+        _hidl_cb(mBase->getConsumerName().c_str());
         return Void();
     }
 
diff --git a/libs/gui/tests/GLTest.cpp b/libs/gui/tests/GLTest.cpp
index a1405fc..73e8fbe 100644
--- a/libs/gui/tests/GLTest.cpp
+++ b/libs/gui/tests/GLTest.cpp
@@ -185,7 +185,7 @@
         while ((err = glGetError()) != GL_NO_ERROR) {
             msg += String8::format(", %#x", err);
         }
-        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+        return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
     }
     if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
         msg += String8::format("r(%d isn't %d)", pixel[0], r);
@@ -209,7 +209,7 @@
         msg += String8::format("a(%d isn't %d)", pixel[3], a);
     }
     if (!msg.isEmpty()) {
-        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+        return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
     } else {
         return ::testing::AssertionSuccess();
     }
@@ -244,8 +244,8 @@
         msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
                                r1.left, r1.top, r1.right, r1.bottom,
                                r2.left, r2.top, r2.right, r2.bottom);
-        fprintf(stderr, "assertRectEq: %s\n", msg.string());
-        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+        fprintf(stderr, "assertRectEq: %s\n", msg.c_str());
+        return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
     } else {
         return ::testing::AssertionSuccess();
     }
diff --git a/libs/gui/tests/OWNERS b/libs/gui/tests/OWNERS
index 156efdb..48cd30d 100644
--- a/libs/gui/tests/OWNERS
+++ b/libs/gui/tests/OWNERS
@@ -1,3 +1,6 @@
 # Android > Android OS & Apps > Framework (Java + Native) > Window Manager > Surfaces
 # Bug component: 316245 = per-file BLASTBufferQueue_test.cpp, DisplayInfo_test.cpp, EndToEndNativeInputTest.cpp, WindowInfos_test.cpp
 # Buganizer template url: https://b.corp.google.com/issues/new?component=316245&template=1018194 = per-file BLASTBufferQueue_test.cpp, DisplayInfo_test.cpp, EndToEndNativeInputTest.cpp, WindowInfos_test.cpp
+
+# Android > Android OS & Apps > graphics > Core Graphics Stack (CoGS)
+# Bug component: 1075130
diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp
index f34561f..ccd0e59 100644
--- a/libs/gui/tests/SurfaceTextureFBO_test.cpp
+++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp
@@ -59,7 +59,7 @@
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
     for (int i = 0; i < 4; i++) {
-        SCOPED_TRACE(String8::format("frame %d", i).string());
+        SCOPED_TRACE(String8::format("frame %d", i).c_str());
 
         ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
                 &anb));
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index e2b4f3d..f76c0be 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -147,8 +147,9 @@
 
     for (int i = 0; i < 5; i++) {
         const android_native_rect_t& crop(crops[i]);
-        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
-                crop.left, crop.top, crop.right, crop.bottom).string());
+        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left, crop.top,
+                                     crop.right, crop.bottom)
+                             .c_str());
 
         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
 
@@ -308,7 +309,7 @@
     mFW->waitForFrame();
 
     for (int i = 0; i < numFrames; i++) {
-        SCOPED_TRACE(String8::format("frame %d", i).string());
+        SCOPED_TRACE(String8::format("frame %d", i).c_str());
 
         // We must wait for each frame to come in because if we ever do an
         // updateTexImage call that doesn't consume a newly available buffer
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 065cd7a..cb977f0 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -408,7 +408,7 @@
     sp<ANativeWindow> window(surface);
     native_window_api_connect(window.get(), NATIVE_WINDOW_API_CPU);
 
-    EXPECT_STREQ("TestConsumer", surface->getConsumerName().string());
+    EXPECT_STREQ("TestConsumer", surface->getConsumerName().c_str());
 }
 
 TEST_F(SurfaceTest, GetWideColorSupport) {
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 2039fa6..7a379f5 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -209,7 +209,7 @@
 #if DEBUG_PARSER_PERFORMANCE
     nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
     ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-          tokenizer->getFilename().string(), tokenizer->getLineNumber(), elapsedTime / 1000000.0);
+          tokenizer->getFilename().c_str(), tokenizer->getLineNumber(), elapsedTime / 1000000.0);
 #endif
     if (status != OK) {
         ALOGE("Loading KeyCharacterMap failed with status %s", statusToString(status).c_str());
@@ -363,8 +363,8 @@
     ExactMatch: ;
     }
 #if DEBUG_MAPPING
-    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
-            keyCode, toString(chars, numChars).string(), metaState, result);
+    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.", keyCode,
+          toString(chars, numChars).c_str(), metaState, result);
 #endif
     return result;
 }
@@ -379,7 +379,7 @@
         if (!findKey(ch, &keyCode, &metaState)) {
 #if DEBUG_MAPPING
             ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
-                    deviceId, toString(chars, numChars).string(), ch);
+                  deviceId, toString(chars, numChars).c_str(), ch);
 #endif
             return false;
         }
@@ -391,8 +391,8 @@
         addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
     }
 #if DEBUG_MAPPING
-    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
-            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
+    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.", deviceId,
+          toString(chars, numChars).c_str(), int32_t(outEvents.size()));
     for (size_t i = 0; i < outEvents.size(); i++) {
         ALOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
                 outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
@@ -849,8 +849,8 @@
 status_t KeyCharacterMap::Parser::parse() {
     while (!mTokenizer->isEof()) {
 #if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().c_str(),
+              mTokenizer->peekRemainderOfLine().c_str());
 #endif
 
         mTokenizer->skipDelimiters(WHITESPACE);
@@ -872,8 +872,8 @@
                     status_t status = parseKey();
                     if (status) return status;
                 } else {
-                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                            keywordToken.string());
+                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().c_str(),
+                          keywordToken.c_str());
                     return BAD_VALUE;
                 }
                 break;
@@ -889,8 +889,7 @@
             mTokenizer->skipDelimiters(WHITESPACE);
             if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
                 ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
+                      mTokenizer->getLocation().c_str(), mTokenizer->peekRemainderOfLine().c_str());
                 return BAD_VALUE;
             }
         }
@@ -900,27 +899,27 @@
 
     if (mState != STATE_TOP) {
         ALOGE("%s: Unterminated key description at end of file.",
-                mTokenizer->getLocation().string());
+              mTokenizer->getLocation().c_str());
         return BAD_VALUE;
     }
 
     if (mMap->mType == KeyboardType::UNKNOWN) {
         ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
+              mTokenizer->getLocation().c_str());
         return BAD_VALUE;
     }
 
     if (mFormat == Format::BASE) {
         if (mMap->mType == KeyboardType::OVERLAY) {
             ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
-                    mTokenizer->getLocation().string());
+                  mTokenizer->getLocation().c_str());
             return BAD_VALUE;
         }
     } else if (mFormat == Format::OVERLAY) {
         if (mMap->mType != KeyboardType::OVERLAY) {
             ALOGE("%s: Overlay keyboard layout missing required keyboard "
-                    "'type OVERLAY' declaration.",
-                    mTokenizer->getLocation().string());
+                  "'type OVERLAY' declaration.",
+                  mTokenizer->getLocation().c_str());
             return BAD_VALUE;
         }
     }
@@ -930,8 +929,7 @@
 
 status_t KeyCharacterMap::Parser::parseType() {
     if (mMap->mType != KeyboardType::UNKNOWN) {
-        ALOGE("%s: Duplicate keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
+        ALOGE("%s: Duplicate keyboard 'type' declaration.", mTokenizer->getLocation().c_str());
         return BAD_VALUE;
     }
 
@@ -953,8 +951,8 @@
     } else if (typeToken == "OVERLAY") {
         type = KeyboardType::OVERLAY;
     } else {
-        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
-                typeToken.string());
+        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().c_str(),
+              typeToken.c_str());
         return BAD_VALUE;
     }
 
@@ -971,8 +969,8 @@
         mTokenizer->skipDelimiters(WHITESPACE);
         return parseMapKey();
     }
-    ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
-            keywordToken.string());
+    ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().c_str(),
+          keywordToken.c_str());
     return BAD_VALUE;
 }
 
@@ -986,26 +984,26 @@
     }
 
     char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+    int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0));
     if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
     KeyedVector<int32_t, int32_t>& map =
             mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
     if (map.indexOfKey(code) >= 0) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     mTokenizer->skipDelimiters(WHITESPACE);
     String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.c_str());
     if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              keyCodeToken.c_str());
         return BAD_VALUE;
     }
 
@@ -1019,23 +1017,23 @@
 
 status_t KeyCharacterMap::Parser::parseKey() {
     String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.c_str());
     if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              keyCodeToken.c_str());
         return BAD_VALUE;
     }
     if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
-        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
+        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().c_str(),
+              keyCodeToken.c_str());
         return BAD_VALUE;
     }
 
     mTokenizer->skipDelimiters(WHITESPACE);
     String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
     if (openBraceToken != "{") {
-        ALOGE("%s: Expected '{' after key code label, got '%s'.",
-                mTokenizer->getLocation().string(), openBraceToken.string());
+        ALOGE("%s: Expected '{' after key code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              openBraceToken.c_str());
         return BAD_VALUE;
     }
 
@@ -1066,10 +1064,10 @@
             properties.add(Property(PROPERTY_NUMBER));
         } else {
             int32_t metaState;
-            status_t status = parseModifier(token.string(), &metaState);
+            status_t status = parseModifier(token.c_str(), &metaState);
             if (status) {
                 ALOGE("%s: Expected a property name or modifier, got '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
+                      mTokenizer->getLocation().c_str(), token.c_str());
                 return status;
             }
             properties.add(Property(PROPERTY_META, metaState));
@@ -1087,8 +1085,7 @@
             }
         }
 
-        ALOGE("%s: Expected ',' or ':' after property name.",
-                mTokenizer->getLocation().string());
+        ALOGE("%s: Expected ',' or ':' after property name.", mTokenizer->getLocation().c_str());
         return BAD_VALUE;
     }
 
@@ -1106,18 +1103,17 @@
             char16_t character;
             status_t status = parseCharacterLiteral(&character);
             if (status || !character) {
-                ALOGE("%s: Invalid character literal for key.",
-                        mTokenizer->getLocation().string());
+                ALOGE("%s: Invalid character literal for key.", mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
             if (haveCharacter) {
                 ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                        mTokenizer->getLocation().string());
+                      mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
             if (haveReplacement) {
                 ALOGE("%s: Cannot combine character literal with replace action.",
-                        mTokenizer->getLocation().string());
+                      mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
             behavior.character = character;
@@ -1127,28 +1123,27 @@
             if (token == "none") {
                 if (haveCharacter) {
                     ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
                 if (haveReplacement) {
                     ALOGE("%s: Cannot combine 'none' with replace action.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
                 haveCharacter = true;
             } else if (token == "fallback") {
                 mTokenizer->skipDelimiters(WHITESPACE);
                 token = mTokenizer->nextToken(WHITESPACE);
-                int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+                int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.c_str());
                 if (!keyCode) {
                     ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
-                            mTokenizer->getLocation().string(),
-                            token.string());
+                          mTokenizer->getLocation().c_str(), token.c_str());
                     return BAD_VALUE;
                 }
                 if (haveFallback || haveReplacement) {
                     ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
                 behavior.fallbackKeyCode = keyCode;
@@ -1156,29 +1151,27 @@
             } else if (token == "replace") {
                 mTokenizer->skipDelimiters(WHITESPACE);
                 token = mTokenizer->nextToken(WHITESPACE);
-                int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+                int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.c_str());
                 if (!keyCode) {
                     ALOGE("%s: Invalid key code label for replace, got '%s'.",
-                            mTokenizer->getLocation().string(),
-                            token.string());
+                          mTokenizer->getLocation().c_str(), token.c_str());
                     return BAD_VALUE;
                 }
                 if (haveCharacter) {
                     ALOGE("%s: Cannot combine character literal with replace action.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
                 if (haveFallback || haveReplacement) {
                     ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
                 behavior.replacementKeyCode = keyCode;
                 haveReplacement = true;
 
             } else {
-                ALOGE("%s: Expected a key behavior after ':'.",
-                        mTokenizer->getLocation().string());
+                ALOGE("%s: Expected a key behavior after ':'.", mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
         }
@@ -1192,8 +1185,7 @@
         switch (property.property) {
         case PROPERTY_LABEL:
             if (key->label) {
-                ALOGE("%s: Duplicate label for key.",
-                        mTokenizer->getLocation().string());
+                ALOGE("%s: Duplicate label for key.", mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
             key->label = behavior.character;
@@ -1203,8 +1195,7 @@
             break;
         case PROPERTY_NUMBER:
             if (key->number) {
-                ALOGE("%s: Duplicate number for key.",
-                        mTokenizer->getLocation().string());
+                ALOGE("%s: Duplicate number for key.", mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
             key->number = behavior.character;
@@ -1216,7 +1207,7 @@
             for (Behavior* b = key->firstBehavior; b; b = b->next) {
                 if (b->metaState == property.metaState) {
                     ALOGE("%s: Duplicate key behavior for modifier.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
             }
@@ -1285,8 +1276,8 @@
                 return BAD_VALUE;
             }
             if (combinedMeta & metaState) {
-                ALOGE("%s: Duplicate modifier combination '%s'.",
-                        mTokenizer->getLocation().string(), token.c_str());
+                ALOGE("%s: Duplicate modifier combination '%s'.", mTokenizer->getLocation().c_str(),
+                      token.c_str());
                 return BAD_VALUE;
             }
 
@@ -1359,7 +1350,7 @@
     }
 
 Error:
-    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
+    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().c_str());
     return BAD_VALUE;
 }
 
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 250c0dd..79b6cea 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -161,7 +161,7 @@
 #if DEBUG_PARSER_PERFORMANCE
         nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
         ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
-              tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+              tokenizer->getFilename().c_str(), tokenizer->getLineNumber(),
               elapsedTime / 1000000.0);
 #endif
         if (!status) {
@@ -289,8 +289,8 @@
 
 status_t KeyLayoutMap::Parser::parse() {
     while (!mTokenizer->isEof()) {
-        ALOGD_IF(DEBUG_PARSER, "Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                 mTokenizer->peekRemainderOfLine().string());
+        ALOGD_IF(DEBUG_PARSER, "Parsing %s: '%s'.", mTokenizer->getLocation().c_str(),
+                 mTokenizer->peekRemainderOfLine().c_str());
 
         mTokenizer->skipDelimiters(WHITESPACE);
 
@@ -317,16 +317,15 @@
                 status_t status = parseRequiredKernelConfig();
                 if (status) return status;
             } else {
-                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                        keywordToken.string());
+                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().c_str(),
+                      keywordToken.c_str());
                 return BAD_VALUE;
             }
 
             mTokenizer->skipDelimiters(WHITESPACE);
             if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
                 ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
+                      mTokenizer->getLocation().c_str(), mTokenizer->peekRemainderOfLine().c_str());
                 return BAD_VALUE;
             }
         }
@@ -346,26 +345,26 @@
     }
 
     char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+    int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0));
     if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
     std::unordered_map<int32_t, Key>& map =
             mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
     if (map.find(code) != map.end()) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     mTokenizer->skipDelimiters(WHITESPACE);
     String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.c_str());
     if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              keyCodeToken.c_str());
         return BAD_VALUE;
     }
 
@@ -375,15 +374,15 @@
         if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
 
         String8 flagToken = mTokenizer->nextToken(WHITESPACE);
-        uint32_t flag = InputEventLookup::getKeyFlagByLabel(flagToken.string());
+        uint32_t flag = InputEventLookup::getKeyFlagByLabel(flagToken.c_str());
         if (!flag) {
-            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
+            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().c_str(),
+                  flagToken.c_str());
             return BAD_VALUE;
         }
         if (flags & flag) {
-            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
+            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().c_str(),
+                  flagToken.c_str());
             return BAD_VALUE;
         }
         flags |= flag;
@@ -402,15 +401,15 @@
 status_t KeyLayoutMap::Parser::parseAxis() {
     String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
     char* end;
-    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+    int32_t scanCode = int32_t(strtol(scanCodeToken.c_str(), &end, 0));
     if (*end) {
-        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
+        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().c_str(),
+              scanCodeToken.c_str());
         return BAD_VALUE;
     }
     if (mMap->mAxes.find(scanCode) != mMap->mAxes.end()) {
-        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
+        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().c_str(),
+              scanCodeToken.c_str());
         return BAD_VALUE;
     }
 
@@ -423,10 +422,10 @@
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 axisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = InputEventLookup::getAxisByLabel(axisToken.string());
+        axisInfo.axis = InputEventLookup::getAxisByLabel(axisToken.c_str());
         if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected inverted axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), axisToken.string());
+            ALOGE("%s: Expected inverted axis label, got '%s'.", mTokenizer->getLocation().c_str(),
+                  axisToken.c_str());
             return BAD_VALUE;
         }
     } else if (token == "split") {
@@ -434,35 +433,35 @@
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 splitToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
+        axisInfo.splitValue = int32_t(strtol(splitToken.c_str(), &end, 0));
         if (*end) {
-            ALOGE("%s: Expected split value, got '%s'.",
-                    mTokenizer->getLocation().string(), splitToken.string());
+            ALOGE("%s: Expected split value, got '%s'.", mTokenizer->getLocation().c_str(),
+                  splitToken.c_str());
             return BAD_VALUE;
         }
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = InputEventLookup::getAxisByLabel(lowAxisToken.string());
+        axisInfo.axis = InputEventLookup::getAxisByLabel(lowAxisToken.c_str());
         if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected low axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), lowAxisToken.string());
+            ALOGE("%s: Expected low axis label, got '%s'.", mTokenizer->getLocation().c_str(),
+                  lowAxisToken.c_str());
             return BAD_VALUE;
         }
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string());
+        axisInfo.highAxis = InputEventLookup::getAxisByLabel(highAxisToken.c_str());
         if (axisInfo.highAxis < 0) {
-            ALOGE("%s: Expected high axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), highAxisToken.string());
+            ALOGE("%s: Expected high axis label, got '%s'.", mTokenizer->getLocation().c_str(),
+                  highAxisToken.c_str());
             return BAD_VALUE;
         }
     } else {
-        axisInfo.axis = InputEventLookup::getAxisByLabel(token.string());
+        axisInfo.axis = InputEventLookup::getAxisByLabel(token.c_str());
         if (axisInfo.axis < 0) {
             ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
-                    mTokenizer->getLocation().string(), token.string());
+                  mTokenizer->getLocation().c_str(), token.c_str());
             return BAD_VALUE;
         }
     }
@@ -476,15 +475,15 @@
         if (keywordToken == "flat") {
             mTokenizer->skipDelimiters(WHITESPACE);
             String8 flatToken = mTokenizer->nextToken(WHITESPACE);
-            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
+            axisInfo.flatOverride = int32_t(strtol(flatToken.c_str(), &end, 0));
             if (*end) {
-                ALOGE("%s: Expected flat value, got '%s'.",
-                        mTokenizer->getLocation().string(), flatToken.string());
+                ALOGE("%s: Expected flat value, got '%s'.", mTokenizer->getLocation().c_str(),
+                      flatToken.c_str());
                 return BAD_VALUE;
             }
         } else {
-            ALOGE("%s: Expected keyword 'flat', got '%s'.",
-                    mTokenizer->getLocation().string(), keywordToken.string());
+            ALOGE("%s: Expected keyword 'flat', got '%s'.", mTokenizer->getLocation().c_str(),
+                  keywordToken.c_str());
             return BAD_VALUE;
         }
     }
@@ -507,27 +506,27 @@
         codeToken = mTokenizer->nextToken(WHITESPACE);
     }
     char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+    int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0));
     if (*end) {
-        ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     std::unordered_map<int32_t, Led>& map =
             mapUsage ? mMap->mLedsByUsageCode : mMap->mLedsByScanCode;
     if (map.find(code) != map.end()) {
-        ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
+        ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().c_str(),
+              mapUsage ? "usage" : "scan code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     mTokenizer->skipDelimiters(WHITESPACE);
     String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string());
+    int32_t ledCode = InputEventLookup::getLedByLabel(ledCodeToken.c_str());
     if (ledCode < 0) {
-        ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().string(),
-                ledCodeToken.string());
+        ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              ledCodeToken.c_str());
         return BAD_VALUE;
     }
 
@@ -549,7 +548,7 @@
 }
 
 static std::optional<int32_t> getSensorDataIndex(String8 token) {
-    std::string tokenStr(token.string());
+    std::string tokenStr(token.c_str());
     if (tokenStr == "X") {
         return 0;
     } else if (tokenStr == "Y") {
@@ -575,26 +574,26 @@
 status_t KeyLayoutMap::Parser::parseSensor() {
     String8 codeToken = mTokenizer->nextToken(WHITESPACE);
     char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+    int32_t code = int32_t(strtol(codeToken.c_str(), &end, 0));
     if (*end) {
-        ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().string(),
-              "abs code", codeToken.string());
+        ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().c_str(),
+              "abs code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     std::unordered_map<int32_t, Sensor>& map = mMap->mSensorsByAbsCode;
     if (map.find(code) != map.end()) {
-        ALOGE("%s: Duplicate entry for sensor %s '%s'.", mTokenizer->getLocation().string(),
-              "abs code", codeToken.string());
+        ALOGE("%s: Duplicate entry for sensor %s '%s'.", mTokenizer->getLocation().c_str(),
+              "abs code", codeToken.c_str());
         return BAD_VALUE;
     }
 
     mTokenizer->skipDelimiters(WHITESPACE);
     String8 sensorTypeToken = mTokenizer->nextToken(WHITESPACE);
-    std::optional<InputDeviceSensorType> typeOpt = getSensorType(sensorTypeToken.string());
+    std::optional<InputDeviceSensorType> typeOpt = getSensorType(sensorTypeToken.c_str());
     if (!typeOpt) {
-        ALOGE("%s: Expected sensor code label, got '%s'.", mTokenizer->getLocation().string(),
-              sensorTypeToken.string());
+        ALOGE("%s: Expected sensor code label, got '%s'.", mTokenizer->getLocation().c_str(),
+              sensorTypeToken.c_str());
         return BAD_VALUE;
     }
     InputDeviceSensorType sensorType = typeOpt.value();
@@ -602,8 +601,8 @@
     String8 sensorDataIndexToken = mTokenizer->nextToken(WHITESPACE);
     std::optional<int32_t> indexOpt = getSensorDataIndex(sensorDataIndexToken);
     if (!indexOpt) {
-        ALOGE("%s: Expected sensor data index label, got '%s'.", mTokenizer->getLocation().string(),
-              sensorDataIndexToken.string());
+        ALOGE("%s: Expected sensor data index label, got '%s'.", mTokenizer->getLocation().c_str(),
+              sensorDataIndexToken.c_str());
         return BAD_VALUE;
     }
     int32_t sensorDataIndex = indexOpt.value();
@@ -624,12 +623,12 @@
 // requires_kernel_config CONFIG_HID_PLAYSTATION
 status_t KeyLayoutMap::Parser::parseRequiredKernelConfig() {
     String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    std::string configName = codeToken.string();
+    std::string configName = codeToken.c_str();
 
     const auto result = mMap->mRequiredKernelConfigs.emplace(configName);
     if (!result.second) {
         ALOGE("%s: Duplicate entry for required kernel config %s.",
-              mTokenizer->getLocation().string(), configName.c_str());
+              mTokenizer->getLocation().c_str(), configName.c_str());
         return BAD_VALUE;
     }
 
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
index c3f5151..5f06efa 100644
--- a/libs/input/Keyboard.cpp
+++ b/libs/input/Keyboard.cpp
@@ -55,8 +55,8 @@
             status_t status = loadKeyLayout(deviceIdentifier, keyLayoutName.c_str());
             if (status == NAME_NOT_FOUND) {
                 ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
-                        "it was not found.",
-                        deviceIdentifier.name.c_str(), keyLayoutName.string());
+                      "it was not found.",
+                      deviceIdentifier.name.c_str(), keyLayoutName.c_str());
             }
         }
 
@@ -66,8 +66,8 @@
             status_t status = loadKeyCharacterMap(deviceIdentifier, keyCharacterMapName.c_str());
             if (status == NAME_NOT_FOUND) {
                 ALOGE("Configuration for keyboard device '%s' requested keyboard character "
-                        "map '%s' but it was not found.",
-                        deviceIdentifier.name.c_str(), keyCharacterMapName.string());
+                      "map '%s' but it was not found.",
+                      deviceIdentifier.name.c_str(), keyCharacterMapName.c_str());
             }
         }
 
diff --git a/libs/input/PropertyMap.cpp b/libs/input/PropertyMap.cpp
index a842166..fc020ca 100644
--- a/libs/input/PropertyMap.cpp
+++ b/libs/input/PropertyMap.cpp
@@ -74,10 +74,10 @@
     }
 
     char* end;
-    int value = strtol(stringValue.string(), &end, 10);
+    int value = strtol(stringValue.c_str(), &end, 10);
     if (*end != '\0') {
-        ALOGW("Property key '%s' has invalid value '%s'.  Expected an integer.", key.string(),
-              stringValue.string());
+        ALOGW("Property key '%s' has invalid value '%s'.  Expected an integer.", key.c_str(),
+              stringValue.c_str());
         return false;
     }
     outValue = value;
@@ -91,10 +91,10 @@
     }
 
     char* end;
-    float value = strtof(stringValue.string(), &end);
+    float value = strtof(stringValue.c_str(), &end);
     if (*end != '\0') {
-        ALOGW("Property key '%s' has invalid value '%s'.  Expected a float.", key.string(),
-              stringValue.string());
+        ALOGW("Property key '%s' has invalid value '%s'.  Expected a float.", key.c_str(),
+              stringValue.c_str());
         return false;
     }
     outValue = value;
@@ -127,7 +127,7 @@
 #if DEBUG_PARSER_PERFORMANCE
             nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
             ALOGD("Parsed property file '%s' %d lines in %0.3fms.",
-                  tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                  tokenizer->getFilename().c_str(), tokenizer->getLineNumber(),
                   elapsedTime / 1000000.0);
 #endif
             if (status) {
@@ -147,8 +147,8 @@
 status_t PropertyMap::Parser::parse() {
     while (!mTokenizer->isEof()) {
 #if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-              mTokenizer->peekRemainderOfLine().string());
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().c_str(),
+              mTokenizer->peekRemainderOfLine().c_str());
 #endif
 
         mTokenizer->skipDelimiters(WHITESPACE);
@@ -156,7 +156,7 @@
         if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
             String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
             if (keyToken.isEmpty()) {
-                ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string());
+                ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
 
@@ -164,7 +164,7 @@
 
             if (mTokenizer->nextChar() != '=') {
                 ALOGE("%s: Expected '=' between property key and value.",
-                      mTokenizer->getLocation().string());
+                      mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
 
@@ -173,20 +173,20 @@
             String8 valueToken = mTokenizer->nextToken(WHITESPACE);
             if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) {
                 ALOGE("%s: Found reserved character '\\' or '\"' in property value.",
-                      mTokenizer->getLocation().string());
+                      mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
 
             mTokenizer->skipDelimiters(WHITESPACE);
             if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.", mTokenizer->getLocation().string(),
-                      mTokenizer->peekRemainderOfLine().string());
+                ALOGE("%s: Expected end of line, got '%s'.", mTokenizer->getLocation().c_str(),
+                      mTokenizer->peekRemainderOfLine().c_str());
                 return BAD_VALUE;
             }
 
             if (mMap->hasProperty(keyToken)) {
                 ALOGE("%s: Duplicate property value for key '%s'.",
-                      mTokenizer->getLocation().string(), keyToken.string());
+                      mTokenizer->getLocation().c_str(), keyToken.c_str());
                 return BAD_VALUE;
             }
 
diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp
index 865366b..de62c87 100644
--- a/libs/input/VirtualKeyMap.cpp
+++ b/libs/input/VirtualKeyMap.cpp
@@ -79,8 +79,8 @@
 status_t VirtualKeyMap::Parser::parse() {
     while (!mTokenizer->isEof()) {
 #if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().c_str(),
+              mTokenizer->peekRemainderOfLine().c_str());
 #endif
 
         mTokenizer->skipDelimiters(WHITESPACE);
@@ -91,7 +91,7 @@
                 String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
                 if (token != "0x01") {
                     ALOGE("%s: Unknown virtual key type, expected 0x01.",
-                          mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
 
@@ -103,7 +103,7 @@
                         && parseNextIntField(&defn.height);
                 if (!success) {
                     ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
-                          mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                 }
 
@@ -116,9 +116,8 @@
             } while (consumeFieldDelimiterAndSkipWhitespace());
 
             if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
+                ALOGE("%s: Expected end of line, got '%s'.", mTokenizer->getLocation().c_str(),
+                      mTokenizer->peekRemainderOfLine().c_str());
                 return BAD_VALUE;
             }
         }
@@ -146,9 +145,9 @@
 
     String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
     char* end;
-    *outValue = strtol(token.string(), &end, 0);
+    *outValue = strtol(token.c_str(), &end, 0);
     if (token.isEmpty() || *end != '\0') {
-        ALOGE("Expected an integer, got '%s'.", token.string());
+        ALOGE("Expected an integer, got '%s'.", token.c_str());
         return false;
     }
     return true;
diff --git a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
index 0128859..275b7a4 100644
--- a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
@@ -38,10 +38,10 @@
 namespace android {
 
 // Macros for including the SurfaceTexture name in log messages
-#define EGC_LOGV(x, ...) ALOGV("[%s] " x, st.mName.string(), ##__VA_ARGS__)
-#define EGC_LOGD(x, ...) ALOGD("[%s] " x, st.mName.string(), ##__VA_ARGS__)
-#define EGC_LOGW(x, ...) ALOGW("[%s] " x, st.mName.string(), ##__VA_ARGS__)
-#define EGC_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+#define EGC_LOGV(x, ...) ALOGV("[%s] " x, st.mName.c_str(), ##__VA_ARGS__)
+#define EGC_LOGD(x, ...) ALOGD("[%s] " x, st.mName.c_str(), ##__VA_ARGS__)
+#define EGC_LOGW(x, ...) ALOGW("[%s] " x, st.mName.c_str(), ##__VA_ARGS__)
+#define EGC_LOGE(x, ...) ALOGE("[%s] " x, st.mName.c_str(), ##__VA_ARGS__)
 
 static const struct {
     uint32_t width, height;
diff --git a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
index cf16739..32b229d 100644
--- a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
@@ -19,7 +19,7 @@
 #include <surfacetexture/SurfaceTexture.h>
 
 // Macro for including the SurfaceTexture name in log messages
-#define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+#define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.c_str(), ##__VA_ARGS__)
 
 namespace android {
 
diff --git a/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp b/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp
index d3d4cba..9f610e1 100644
--- a/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp
+++ b/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp
@@ -26,10 +26,10 @@
 namespace android {
 
 // Macros for including the SurfaceTexture name in log messages
-#define SFT_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define SFT_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define SFT_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define SFT_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define SFT_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define SFT_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define SFT_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define SFT_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 static const mat4 mtxIdentity;
 
diff --git a/libs/renderengine/gl/GLExtensions.cpp b/libs/renderengine/gl/GLExtensions.cpp
index 3dd534e..b479400 100644
--- a/libs/renderengine/gl/GLExtensions.cpp
+++ b/libs/renderengine/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) {
@@ -127,11 +127,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/libs/renderengine/gl/ProgramCache.cpp b/libs/renderengine/gl/ProgramCache.cpp
index 5ff9240..b1bfa3a 100644
--- a/libs/renderengine/gl/ProgramCache.cpp
+++ b/libs/renderengine/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);
@@ -797,7 +797,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/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index b865c4d..f76d5cf 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -74,7 +74,7 @@
         if (hwSensor.maxDelay > INT_MAX) {
             // Max delay is declared as a 64 bit integer for 64 bit architectures. But it should
             // always fit in a 32 bit integer, log error and cap it to INT_MAX.
-            ALOGE("Sensor maxDelay overflow error %s %" PRId64, mName.string(),
+            ALOGE("Sensor maxDelay overflow error %s %" PRId64, mName.c_str(),
                   static_cast<int64_t>(hwSensor.maxDelay));
             mMaxDelay = INT_MAX;
         } else {
@@ -339,7 +339,7 @@
         if (actualReportingMode != expectedReportingMode) {
             ALOGE("Reporting Mode incorrect: sensor %s handle=%#010" PRIx32 " type=%" PRId32 " "
                    "actual=%d expected=%d",
-                   mName.string(), mHandle, mType, actualReportingMode, expectedReportingMode);
+                   mName.c_str(), mHandle, mType, actualReportingMode, expectedReportingMode);
         }
     }
 
@@ -617,7 +617,7 @@
         const String8& string8) {
     uint32_t len = static_cast<uint32_t>(string8.length());
     FlattenableUtils::write(buffer, size, len);
-    memcpy(static_cast<char*>(buffer), string8.string(), len);
+    memcpy(static_cast<char*>(buffer), string8.c_str(), len);
     FlattenableUtils::advance(buffer, size, len);
     size -= FlattenableUtils::align<4>(buffer);
 }
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index cc96f83..4be0a3a 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -115,7 +115,7 @@
 
 sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
         const sp<Fence>& f2) {
-    return merge(name.string(), f1, f2);
+    return merge(name.c_str(), f1, f2);
 }
 
 int Fence::dup() const {
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 5f441ee..4b637dc 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -49,6 +49,7 @@
 #include "egl_trace.h"
 
 using namespace android;
+using PixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
 
 // ----------------------------------------------------------------------------
 
@@ -406,7 +407,7 @@
 // ----------------------------------------------------------------------------
 
 // Translates EGL color spaces to Android data spaces.
-static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
+static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace, PixelFormat pixelFormat) {
     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
         return HAL_DATASPACE_UNKNOWN;
     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
@@ -422,7 +423,13 @@
     } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
         return HAL_DATASPACE_V0_SCRGB_LINEAR;
     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT) {
-        return HAL_DATASPACE_BT2020_LINEAR;
+        if (pixelFormat == PixelFormat::RGBA_FP16) {
+            return static_cast<android_dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
+                                                  HAL_DATASPACE_TRANSFER_LINEAR |
+                                                  HAL_DATASPACE_RANGE_EXTENDED);
+        } else {
+            return HAL_DATASPACE_BT2020_LINEAR;
+        }
     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
         return HAL_DATASPACE_BT2020_PQ;
     }
@@ -566,8 +573,6 @@
     newList.push_back(EGL_NONE);
 }
 
-using PixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
-
 // Gets the native pixel format corrsponding to the passed EGLConfig.
 void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
                           PixelFormat* format) {
@@ -707,7 +712,7 @@
             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
         }
 
-        android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
+        android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace, format);
         // Set dataSpace even if it could be HAL_DATASPACE_UNKNOWN.
         // HAL_DATASPACE_UNKNOWN is the default value, but it may have changed
         // at this point.
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index 7b9782f..9171534 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -107,7 +107,7 @@
 
     ALOGV("shellCommand");
     for (size_t i = 0, n = args.size(); i < n; i++)
-        ALOGV("  arg[%zu]: '%s'", i, String8(args[i]).string());
+        ALOGV("  arg[%zu]: '%s'", i, String8(args[i]).c_str());
 
     if (args.size() >= 1) {
         if (args[0] == String16("vkjson")) return cmdVkjson(out, err);
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
index 2ebdbcf..94c839f 100644
--- a/services/inputflinger/host/InputDriver.cpp
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -259,14 +259,14 @@
 
 const char* InputDriver::inputGetPropertyKey(input_property_t* property) {
     if (property != nullptr) {
-        return property->key.string();
+        return property->key.c_str();
     }
     return nullptr;
 }
 
 const char* InputDriver::inputGetPropertyValue(input_property_t* property) {
     if (property != nullptr) {
-        return property->value.string();
+        return property->value.c_str();
     }
     return nullptr;
 }
@@ -284,7 +284,7 @@
 }
 
 void InputDriver::dump(String8& result) {
-    result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.string());
+    result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.c_str());
 }
 
 } // namespace android
diff --git a/services/inputflinger/host/InputFlinger.cpp b/services/inputflinger/host/InputFlinger.cpp
index 2da2a70..d974c43 100644
--- a/services/inputflinger/host/InputFlinger.cpp
+++ b/services/inputflinger/host/InputFlinger.cpp
@@ -57,7 +57,7 @@
     } else {
         dumpInternal(result);
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return OK;
 }
 
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index f4f3ae9..09b20fd 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -251,7 +251,7 @@
         if (cursorModeString == "navigation") {
             mParameters.mode = Parameters::Mode::NAVIGATION;
         } else if (cursorModeString != "pointer" && cursorModeString != "default") {
-            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
+            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.c_str());
         }
     }
 
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index ed3b0ec..bc1add5 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -429,7 +429,7 @@
         } else if (gestureModeString == "multi-touch") {
             mParameters.gestureMode = Parameters::GestureMode::MULTI_TOUCH;
         } else if (gestureModeString != "default") {
-            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
+            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.c_str());
         }
     }
 
@@ -463,7 +463,7 @@
         } else if (deviceTypeString == "pointer") {
             mParameters.deviceType = Parameters::DeviceType::POINTER;
         } else if (deviceTypeString != "default") {
-            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
+            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.c_str());
         }
     }
 
@@ -484,7 +484,7 @@
         } else if (orientationString == "ORIENTATION_270") {
             mParameters.orientation = Parameters::Orientation::ORIENTATION_270;
         } else if (orientationString != "ORIENTATION_0") {
-            ALOGW("Invalid value for touch.orientation: '%s'", orientationString.string());
+            ALOGW("Invalid value for touch.orientation: '%s'", orientationString.c_str());
         }
     }
 
@@ -1204,7 +1204,7 @@
         } else if (sizeCalibrationString == "area") {
             out.sizeCalibration = Calibration::SizeCalibration::AREA;
         } else if (sizeCalibrationString != "default") {
-            ALOGW("Invalid value for touch.size.calibration: '%s'", sizeCalibrationString.string());
+            ALOGW("Invalid value for touch.size.calibration: '%s'", sizeCalibrationString.c_str());
         }
     }
 
@@ -1224,7 +1224,7 @@
             out.pressureCalibration = Calibration::PressureCalibration::AMPLITUDE;
         } else if (pressureCalibrationString != "default") {
             ALOGW("Invalid value for touch.pressure.calibration: '%s'",
-                  pressureCalibrationString.string());
+                  pressureCalibrationString.c_str());
         }
     }
 
@@ -1242,7 +1242,7 @@
             out.orientationCalibration = Calibration::OrientationCalibration::VECTOR;
         } else if (orientationCalibrationString != "default") {
             ALOGW("Invalid value for touch.orientation.calibration: '%s'",
-                  orientationCalibrationString.string());
+                  orientationCalibrationString.c_str());
         }
     }
 
@@ -1256,7 +1256,7 @@
             out.distanceCalibration = Calibration::DistanceCalibration::SCALED;
         } else if (distanceCalibrationString != "default") {
             ALOGW("Invalid value for touch.distance.calibration: '%s'",
-                  distanceCalibrationString.string());
+                  distanceCalibrationString.c_str());
         }
     }
 
@@ -1271,7 +1271,7 @@
             out.coverageCalibration = Calibration::CoverageCalibration::BOX;
         } else if (coverageCalibrationString != "default") {
             ALOGW("Invalid value for touch.coverage.calibration: '%s'",
-                  coverageCalibrationString.string());
+                  coverageCalibrationString.c_str());
         }
     }
 }
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 03fbf07..ad6cf01 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2784,7 +2784,7 @@
     String8 propertyValue;
     ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue))
             << "Device should have read configuration during configuration phase.";
-    ASSERT_STREQ("value", propertyValue.string());
+    ASSERT_STREQ("value", propertyValue.c_str());
 
     ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
     ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
index d7ca6e1..47fa8b3 100644
--- a/services/sensorservice/RecentEventLogger.cpp
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -83,7 +83,7 @@
         }
         buffer.append("\n");
     }
-    return std::string(buffer.string());
+    return std::string(buffer.c_str());
 }
 
 /**
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index de050e0..184fa76 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -299,7 +299,7 @@
         result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
     }
 
-    return result.string();
+    return result.c_str();
 }
 
 /**
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 2dd12e9..7548742 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -63,7 +63,7 @@
 void SensorService::SensorDirectConnection::dump(String8& result) const {
     Mutex::Autolock _l(mConnectionLock);
     result.appendFormat("\tPackage %s, HAL channel handle %d, total sensor activated %zu\n",
-            String8(mOpPackageName).string(), getHalChannelHandle(), mActivated.size());
+            String8(mOpPackageName).c_str(), getHalChannelHandle(), mActivated.size());
     for (auto &i : mActivated) {
         result.appendFormat("\t\tSensor %#08x, rate %d\n", i.first, i.second);
     }
@@ -79,7 +79,7 @@
 void SensorService::SensorDirectConnection::dump(ProtoOutputStream* proto) const {
     using namespace service::SensorDirectConnectionProto;
     Mutex::Autolock _l(mConnectionLock);
-    proto->write(PACKAGE_NAME, std::string(String8(mOpPackageName).string()));
+    proto->write(PACKAGE_NAME, std::string(String8(mOpPackageName).c_str()));
     proto->write(HAL_CHANNEL_HANDLE, getHalChannelHandle());
     proto->write(NUM_SENSOR_ACTIVATED, int(mActivated.size()));
     for (auto &i : mActivated) {
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index f06f947..aa96377 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -90,12 +90,12 @@
         result.append("NORMAL\n");
     }
     result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
-            "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
+            "max cache size %d\n", mPackageName.c_str(), mWakeLockRefCount, mUid, mCacheSize,
             mMaxCacheSize);
     for (auto& it : mSensorInfo) {
         const FlushInfo& flushInfo = it.second;
         result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
-                            mService->getSensorName(it.first).string(),
+                            mService->getSensorName(it.first).c_str(),
                             it.first,
                             flushInfo.mFirstFlushPending ? "First flush pending" :
                                                            "active",
@@ -131,7 +131,7 @@
     } else {
         proto->write(OPERATING_MODE, OP_MODE_NORMAL);
     }
-    proto->write(PACKAGE_NAME, std::string(mPackageName.string()));
+    proto->write(PACKAGE_NAME, std::string(mPackageName.c_str()));
     proto->write(WAKE_LOCK_REF_COUNT, int32_t(mWakeLockRefCount));
     proto->write(UID, int32_t(mUid));
     proto->write(CACHE_SIZE, int32_t(mCacheSize));
@@ -846,7 +846,7 @@
             if (numBytesRead == sizeof(sensors_event_t)) {
                 if (!mDataInjectionMode) {
                     ALOGE("Data injected in normal mode, dropping event"
-                          "package=%s uid=%d", mPackageName.string(), mUid);
+                          "package=%s uid=%d", mPackageName.c_str(), mUid);
                     // Unregister call backs.
                     return 0;
                 }
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index 85ce0f0..02f22c5 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -134,12 +134,12 @@
                     "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
                         ") | perm: %s | flags: 0x%08x\n",
                     s.getHandle(),
-                    s.getName().string(),
-                    s.getVendor().string(),
+                    s.getName().c_str(),
+                    s.getVendor().c_str(),
                     s.getVersion(),
-                    s.getStringType().string(),
+                    s.getStringType().c_str(),
                     s.getType(),
-                    s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a",
+                    s.getRequiredPermission().size() ? s.getRequiredPermission().c_str() : "n/a",
                     static_cast<int>(s.getFlags()));
 
             result.append("\t");
@@ -208,7 +208,7 @@
             }
             return true;
         });
-    return std::string(result.string());
+    return std::string(result.c_str());
 }
 
 /**
@@ -225,13 +225,13 @@
     forEachSensor([&proto] (const Sensor& s) -> bool {
         const uint64_t token = proto->start(SENSORS);
         proto->write(HANDLE, s.getHandle());
-        proto->write(NAME, std::string(s.getName().string()));
-        proto->write(VENDOR, std::string(s.getVendor().string()));
+        proto->write(NAME, std::string(s.getName().c_str()));
+        proto->write(VENDOR, std::string(s.getVendor().c_str()));
         proto->write(VERSION, s.getVersion());
-        proto->write(STRING_TYPE, std::string(s.getStringType().string()));
+        proto->write(STRING_TYPE, std::string(s.getStringType().c_str()));
         proto->write(TYPE, s.getType());
         proto->write(REQUIRED_PERMISSION, std::string(s.getRequiredPermission().size() ?
-                s.getRequiredPermission().string() : ""));
+                s.getRequiredPermission().c_str() : ""));
         proto->write(FLAGS, int(s.getFlags()));
         switch (s.getReportingMode()) {
             case AREPORTING_MODE_CONTINUOUS:
diff --git a/services/sensorservice/SensorRegistrationInfo.h b/services/sensorservice/SensorRegistrationInfo.h
index a34a65b..dc9e821 100644
--- a/services/sensorservice/SensorRegistrationInfo.h
+++ b/services/sensorservice/SensorRegistrationInfo.h
@@ -93,7 +93,7 @@
         using namespace service::SensorRegistrationInfoProto;
         proto->write(TIMESTAMP_SEC, int64_t(mRealtimeSec));
         proto->write(SENSOR_HANDLE, mSensorHandle);
-        proto->write(PACKAGE_NAME, std::string(mPackageName.string()));
+        proto->write(PACKAGE_NAME, std::string(mPackageName.c_str()));
         proto->write(PID, int32_t(mPid));
         proto->write(UID, int32_t(mUid));
         proto->write(SAMPLING_RATE_US, mSamplingRateUs);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e0a4f03..260e61a 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -537,7 +537,7 @@
                         i.second->setFormat("mask_data");
                     }
                     // if there is events and sensor does not need special permission.
-                    result.appendFormat("%s: ", s->getSensor().getName().string());
+                    result.appendFormat("%s: ", s->getSensor().getName().c_str());
                     result.append(i.second->dump().c_str());
                 }
             }
@@ -548,7 +548,7 @@
                 int handle = mActiveSensors.keyAt(i);
                 if (dev.isSensorActive(handle)) {
                     result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
-                            getSensorName(handle).string(),
+                            getSensorName(handle).c_str(),
                             handle,
                             mActiveSensors.valueAt(i)->getNumConnections());
                 }
@@ -564,10 +564,10 @@
                    result.appendFormat(" NORMAL\n");
                    break;
                case RESTRICTED:
-                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
+                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.c_str());
                    break;
                case DATA_INJECTION:
-                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
+                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.c_str());
             }
             result.appendFormat("Sensor Privacy: %s\n",
                     mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
@@ -605,7 +605,7 @@
             } while(startIndex != currentIndex);
         }
     }
-    write(fd, result.string(), result.size());
+    write(fd, result.c_str(), result.size());
     return NO_ERROR;
 }
 
@@ -653,7 +653,7 @@
                     "normal" : "mask_data");
             const uint64_t mToken = proto.start(service::SensorEventsProto::RECENT_EVENTS_LOGS);
             proto.write(service::SensorEventsProto::RecentEventsLog::NAME,
-                    std::string(s->getSensor().getName().string()));
+                    std::string(s->getSensor().getName().c_str()));
             i.second->dump(&proto);
             proto.end(mToken);
         }
@@ -667,7 +667,7 @@
         if (dev.isSensorActive(handle)) {
             token = proto.start(ACTIVE_SENSORS);
             proto.write(service::ActiveSensorProto::NAME,
-                    std::string(getSensorName(handle).string()));
+                    std::string(getSensorName(handle).c_str()));
             proto.write(service::ActiveSensorProto::HANDLE, handle);
             proto.write(service::ActiveSensorProto::NUM_CONNECTIONS,
                     int(mActiveSensors.valueAt(i)->getNumConnections()));
@@ -685,11 +685,11 @@
             break;
         case RESTRICTED:
             proto.write(OPERATING_MODE, OP_MODE_RESTRICTED);
-            proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string()));
+            proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.c_str()));
             break;
         case DATA_INJECTION:
             proto.write(OPERATING_MODE, OP_MODE_DATA_INJECTION);
-            proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string()));
+            proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.c_str()));
             break;
         default:
             proto.write(OPERATING_MODE, OP_MODE_UNKNOWN);
@@ -832,8 +832,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;
     }
 
@@ -858,7 +858,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;
     }
 
@@ -1351,8 +1351,8 @@
                         accessibleSensorList.add(sensor);
                     } else if (sensor.getType() != SENSOR_TYPE_HEAD_TRACKER) {
                         ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32,
-                              sensor.getName().string(),
-                              sensor.getRequiredPermission().string(),
+                              sensor.getName().c_str(),
+                              sensor.getRequiredPermission().c_str(),
                               sensor.getRequiredAppOp());
                     }
                 }
@@ -1996,10 +1996,10 @@
             !isAudioServerOrSystemServerUid(IPCThreadState::self()->getCallingUid())) {
         if (!mHtRestricted) {
             ALOGI("Permitting access to HT sensor type outside system (%s)",
-                  String8(opPackageName).string());
+                  String8(opPackageName).c_str());
         } else {
-            ALOGW("%s %s a sensor (%s) as a non-system client", String8(opPackageName).string(),
-                  operation, sensor.getName().string());
+            ALOGW("%s %s a sensor (%s) as a non-system client", String8(opPackageName).c_str(),
+                  operation, sensor.getName().c_str());
             return false;
         }
     }
@@ -2032,8 +2032,8 @@
     }
 
     if (!canAccess) {
-        ALOGE("%s %s a sensor (%s) without holding %s", String8(opPackageName).string(),
-              operation, sensor.getName().string(), sensor.getRequiredPermission().string());
+        ALOGE("%s %s a sensor (%s) without holding %s", String8(opPackageName).c_str(),
+              operation, sensor.getName().c_str(), sensor.getRequiredPermission().c_str());
     }
 
     return canAccess;
@@ -2124,7 +2124,7 @@
 }
 
 bool SensorService::isWhiteListedPackage(const String8& packageName) {
-    return (packageName.contains(mWhiteListedPackage.string()));
+    return (packageName.contains(mWhiteListedPackage.c_str()));
 }
 
 bool SensorService::isOperationRestrictedLocked(const String16& opPackageName) {
diff --git a/services/sensorservice/hidl/utils.cpp b/services/sensorservice/hidl/utils.cpp
index 5fa594d..d338d02 100644
--- a/services/sensorservice/hidl/utils.cpp
+++ b/services/sensorservice/hidl/utils.cpp
@@ -32,8 +32,8 @@
     SensorInfo dst;
     const String8& name = src.getName();
     const String8& vendor = src.getVendor();
-    dst.name = hidl_string{name.string(), name.size()};
-    dst.vendor = hidl_string{vendor.string(), vendor.size()};
+    dst.name = hidl_string{name.c_str(), name.size()};
+    dst.vendor = hidl_string{vendor.c_str(), vendor.size()};
     dst.version = src.getVersion();
     dst.sensorHandle = src.getHandle();
     dst.type = static_cast<::android::hardware::sensors::V1_0::SensorType>(
diff --git a/services/sensorservice/tests/sensorservicetest.cpp b/services/sensorservice/tests/sensorservicetest.cpp
index 1406bb3..8b4b3f6 100644
--- a/services/sensorservice/tests/sensorservicetest.cpp
+++ b/services/sensorservice/tests/sensorservicetest.cpp
@@ -105,7 +105,7 @@
 
     Sensor const* accelerometer = mgr.getDefaultSensor(Sensor::TYPE_ACCELEROMETER);
     printf("accelerometer=%p (%s)\n",
-            accelerometer, accelerometer->getName().string());
+            accelerometer, accelerometer->getName().c_str());
 
     sStartTime = systemTime();
 
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 7361a4f..a1035f0 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -49,11 +49,11 @@
 namespace android {
 
 // Macros for including the BufferLayerConsumer name in log messages
-#define BLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
-//#define BLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
-#define BLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BLC_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BLC_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+// #define BLC_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BLC_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
+#define BLC_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
 
 static const mat4 mtxIdentity;
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index f439caf..8dab6ce 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -34,7 +34,7 @@
                          [](const mat4& mat) {
                              using namespace std::string_literals;
                              std::vector<std::string> split =
-                                     base::Split(std::string(mat.asString().string()), "\n"s);
+                                     base::Split(std::string(mat.asString().c_str()), "\n"s);
                              split.pop_back(); // Strip the last (empty) line
                              return split;
                          }}) {
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 54133d9..5e6cade 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -216,32 +216,32 @@
                 base::StringAppendF(&result,
                                     "Expected two layer stack hashes, e.g. '--planner %s "
                                     "<left_hash> <right_hash>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
             if (args.size() > 4) {
                 base::StringAppendF(&result,
                                     "Too many arguments found, expected '--planner %s <left_hash> "
                                     "<right_hash>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
 
             const String8 leftHashString(args[2]);
             size_t leftHash = 0;
-            int fieldsRead = sscanf(leftHashString.string(), "%zx", &leftHash);
+            int fieldsRead = sscanf(leftHashString.c_str(), "%zx", &leftHash);
             if (fieldsRead != 1) {
                 base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
-                                    leftHashString.string());
+                                    leftHashString.c_str());
                 return;
             }
 
             const String8 rightHashString(args[3]);
             size_t rightHash = 0;
-            fieldsRead = sscanf(rightHashString.string(), "%zx", &rightHash);
+            fieldsRead = sscanf(rightHashString.c_str(), "%zx", &rightHash);
             if (fieldsRead != 1) {
                 base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
-                                    rightHashString.string());
+                                    rightHashString.c_str());
                 return;
             }
 
@@ -252,22 +252,22 @@
             if (args.size() < 3) {
                 base::StringAppendF(&result,
                                     "Expected a layer stack hash, e.g. '--planner %s <hash>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
             if (args.size() > 3) {
                 base::StringAppendF(&result,
                                     "Too many arguments found, expected '--planner %s <hash>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
 
             const String8 hashString(args[2]);
             size_t hash = 0;
-            const int fieldsRead = sscanf(hashString.string(), "%zx", &hash);
+            const int fieldsRead = sscanf(hashString.c_str(), "%zx", &hash);
             if (fieldsRead != 1) {
                 base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
-                                    hashString.string());
+                                    hashString.c_str());
                 return;
             }
 
@@ -279,20 +279,20 @@
         } else if (command == "--similar" || command == "-s") {
             if (args.size() < 3) {
                 base::StringAppendF(&result, "Expected a plan string, e.g. '--planner %s <plan>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
             if (args.size() > 3) {
                 base::StringAppendF(&result,
                                     "Too many arguments found, expected '--planner %s <plan>'\n",
-                                    command.string());
+                                    command.c_str());
                 return;
             }
 
             const String8 planString(args[2]);
-            std::optional<Plan> plan = Plan::fromString(std::string(planString.string()));
+            std::optional<Plan> plan = Plan::fromString(std::string(planString.c_str()));
             if (!plan) {
-                base::StringAppendF(&result, "Failed to parse %s as a Plan\n", planString.string());
+                base::StringAppendF(&result, "Failed to parse %s as a Plan\n", planString.c_str());
                 return;
             }
 
@@ -302,7 +302,7 @@
         } else if (command == "--layers" || command == "-l") {
             mFlattener.dumpLayers(result);
         } else {
-            base::StringAppendF(&result, "Unknown command '%s'\n\n", command.string());
+            base::StringAppendF(&result, "Unknown command '%s'\n\n", command.c_str());
             dumpUsage(result);
         }
         return;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 64348a5..314b4cd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5141,7 +5141,7 @@
     if (args.size() > 1) {
         const auto name = String8(args[1]);
         mCurrentState.traverseInZOrder([&](Layer* layer) {
-            if (layer->getName() == name.string()) {
+            if (layer->getName() == name.c_str()) {
                 layer->dumpFrameStats(result);
             }
         });
@@ -5155,7 +5155,7 @@
     const auto name = clearAll ? String8() : String8(args[1]);
 
     mCurrentState.traverse([&](Layer* layer) {
-        if (clearAll || layer->getName() == name.string()) {
+        if (clearAll || layer->getName() == name.c_str()) {
             layer->clearFrameStats();
         }
     });
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 0782fef..bace6cc 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -559,7 +559,7 @@
         DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
         DispSurfaceChange* surfaceChange(dispChange->mutable_surface());
         surfaceChange->set_buffer_queue_id(bufferQueueId);
-        surfaceChange->set_buffer_queue_name(surface->getConsumerName().string());
+        surfaceChange->set_buffer_queue_name(surface->getConsumerName().c_str());
     }
     else {
         ALOGE("invalid graphic buffer producer received while tracing a display change (%s)",
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 28e8b8c..68cd45e 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -775,7 +775,7 @@
 }
 
 bool SurfaceInterceptorTest::displayCreationFound(const Increment& increment, bool foundDisplay) {
-    bool isMatch(increment.display_creation().name() == DISPLAY_NAME.string() &&
+    bool isMatch(increment.display_creation().name() == DISPLAY_NAME.c_str() &&
                  !increment.display_creation().is_secure());
     if (isMatch && !foundDisplay) {
         foundDisplay = true;
@@ -816,7 +816,7 @@
                     break;
                 case Increment::IncrementCase::kDisplayDeletion:
                     // Find the id of created display.
-                    targetId = getDisplayId(trace, DISPLAY_NAME.string());
+                    targetId = getDisplayId(trace, DISPLAY_NAME.c_str());
                     foundIncrement = displayDeletionFound(increment, targetId, foundIncrement);
                     break;
                 default:
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index f7d34ac..e20818c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -46,7 +46,7 @@
     const auto& display = getCurrentDisplayState(displayToken);
     EXPECT_TRUE(display.isVirtual());
     EXPECT_FALSE(display.isSecure);
-    EXPECT_EQ(name.string(), display.displayName);
+    EXPECT_EQ(name.c_str(), display.displayName);
 
     // --------------------------------------------------------------------
     // Cleanup conditions
@@ -81,7 +81,7 @@
     const auto& display = getCurrentDisplayState(displayToken);
     EXPECT_TRUE(display.isVirtual());
     EXPECT_TRUE(display.isSecure);
-    EXPECT_EQ(name.string(), display.displayName);
+    EXPECT_EQ(name.c_str(), display.displayName);
 
     // --------------------------------------------------------------------
     // Cleanup conditions
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index f879430..b75cf08 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -161,7 +161,7 @@
             String8 err(String8::format("pixel @ (%3d, %3d): "
                                         "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
                                         x, y, r, g, b, pixel[0], pixel[1], pixel[2]));
-            EXPECT_EQ(String8(), err) << err.string();
+            EXPECT_EQ(String8(), err) << err.c_str();
         }
     }
 
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
index 523f890..d0a9da1 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
@@ -113,7 +113,7 @@
                         static_cast<long>(client_pid_));
     touchpad_->dumpInternal(result);
   }
-  write(fd, result.string(), result.size());
+  write(fd, result.c_str(), result.size());
   return OK;
 }
 
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index a99355f..f92078d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -747,6 +747,17 @@
         if (strcmp(name, props.extensionName) != 0)
             continue;
 
+        // Ignore duplicate extensions (see: b/288929054)
+        bool duplicate_entry = false;
+        for (uint32_t j = 0; j < filter.name_count; j++) {
+            if (strcmp(name, filter.names[j]) == 0) {
+                duplicate_entry = true;
+                break;
+            }
+        }
+        if (duplicate_entry == true)
+            continue;
+
         filter.names[filter.name_count++] = name;
         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
             if (ext_bit == ProcHook::ANDROID_native_buffer)
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index a14fed2..d059f8f 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -23,6 +23,7 @@
 #include <dlfcn.h>
 #include <string.h>
 #include <sys/prctl.h>
+#include <unistd.h>
 
 #include <mutex>
 #include <string>
@@ -362,6 +363,7 @@
 void ForEachFileInZip(const std::string& zipname,
                       const std::string& dir_in_zip,
                       Functor functor) {
+    static const size_t kPageSize = getpagesize();
     int32_t err;
     ZipArchiveHandle zip = nullptr;
     if ((err = OpenArchive(zipname.c_str(), &zip)) != 0) {
@@ -389,7 +391,7 @@
         // the APK. Loading still may fail for other reasons, but this at least
         // lets us avoid failed-to-load log messages in the typical case of
         // compressed and/or unaligned libraries.
-        if (entry.method != kCompressStored || entry.offset % PAGE_SIZE != 0)
+        if (entry.method != kCompressStored || entry.offset % kPageSize != 0)
             continue;
         functor(filename);
     }
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 64393be..570c01e 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -518,7 +518,8 @@
     return native_format;
 }
 
-android_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace) {
+android_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace,
+                                     PixelFormat pixelFormat) {
     switch (colorspace) {
         case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
             return HAL_DATASPACE_V0_SRGB;
@@ -537,7 +538,14 @@
         case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
             return HAL_DATASPACE_V0_SRGB;
         case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
-            return HAL_DATASPACE_BT2020_LINEAR;
+            if (pixelFormat == PixelFormat::RGBA_FP16) {
+                return static_cast<android_dataspace>(
+                    HAL_DATASPACE_STANDARD_BT2020 |
+                    HAL_DATASPACE_TRANSFER_LINEAR |
+                    HAL_DATASPACE_RANGE_EXTENDED);
+            } else {
+                return HAL_DATASPACE_BT2020_LINEAR;
+            }
         case VK_COLOR_SPACE_HDR10_ST2084_EXT:
             return static_cast<android_dataspace>(
                 HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
@@ -547,9 +555,7 @@
                 HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
                 HAL_DATASPACE_RANGE_FULL);
         case VK_COLOR_SPACE_HDR10_HLG_EXT:
-            return static_cast<android_dataspace>(
-                HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
-                HAL_DATASPACE_RANGE_FULL);
+            return static_cast<android_dataspace>(HAL_DATASPACE_BT2020_HLG);
         case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
             return static_cast<android_dataspace>(
                 HAL_DATASPACE_STANDARD_ADOBE_RGB |
@@ -1259,7 +1265,7 @@
     PixelFormat native_pixel_format =
         GetNativePixelFormat(create_info->imageFormat);
     android_dataspace native_dataspace =
-        GetNativeDataspace(create_info->imageColorSpace);
+        GetNativeDataspace(create_info->imageColorSpace, native_pixel_format);
     if (native_dataspace == HAL_DATASPACE_UNKNOWN) {
         ALOGE(
             "CreateSwapchainKHR(VkSwapchainCreateInfoKHR.imageColorSpace = %d) "