Merge "Use String8/16 c_str [sensors]" into udc-dev-plus-aosp
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/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/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/test_fuzzer/TestServiceFuzzer.cpp b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
index ba1a6a1..d2fa581 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
@@ -35,6 +35,7 @@
     ON_ROOT_AID,
     ON_DUMP_TRANSACT,
     ON_SHELL_CMD_TRANSACT,
+    CRASH_ALWAYS,
 };
 
 // This service is to verify that fuzzService is functioning properly
@@ -112,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]);
@@ -146,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/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/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 5fbae3c..9d3e674 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 5217209..5b34ba1 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -47,23 +47,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__)
 
@@ -298,8 +298,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
@@ -718,7 +717,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 808388f..cf5ad7b 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -47,23 +47,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__)
 
@@ -569,9 +569,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();
 
@@ -1033,8 +1033,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
@@ -1461,7 +1460,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
@@ -1563,7 +1562,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 0fda358..aff03e0 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1269,7 +1269,7 @@
     sp<IBinder> display = nullptr;
     binder::Status status =
             ComposerServiceAIDL::getComposerService()->createDisplay(std::string(
-                                                                             displayName.string()),
+                                                                             displayName.c_str()),
                                                                      secure, requestedRefereshRate,
                                                                      &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 3ae4b6d..9024b70 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/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 096a43c..4f4f1f5 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -413,7 +413,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 12c9e53..d571917 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -140,7 +140,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());
@@ -297,7 +297,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;
         }
@@ -309,8 +309,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(),
@@ -756,8 +756,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);
@@ -779,8 +779,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;
@@ -795,10 +795,9 @@
 
             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());
-                return BAD_VALUE;
+            ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
+                  mTokenizer->getLocation().c_str(), mTokenizer->peekRemainderOfLine().c_str());
+            return BAD_VALUE;
             }
         }
 
@@ -807,27 +806,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;
         }
     }
@@ -837,8 +836,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;
     }
 
@@ -860,8 +858,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;
     }
 
@@ -878,8 +876,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;
 }
 
@@ -893,26 +891,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::map<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
     const auto it = map.find(code);
     if (it != 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);
-    std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    std::optional<int> 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;
     }
 
@@ -926,23 +924,23 @@
 
 status_t KeyCharacterMap::Parser::parseKey() {
     String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    std::optional<int> 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.find(*keyCode) != mMap->mKeys.end()) {
-        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;
     }
 
@@ -971,10 +969,10 @@
             properties.emplace_back(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.emplace_back(PROPERTY_META, metaState);
@@ -992,8 +990,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;
     }
 
@@ -1011,18 +1008,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;
@@ -1032,28 +1028,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);
-                std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+                std::optional<int> 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;
@@ -1061,29 +1056,27 @@
             } else if (token == "replace") {
                 mTokenizer->skipDelimiters(WHITESPACE);
                 token = mTokenizer->nextToken(WHITESPACE);
-                std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+                std::optional<int> 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;
             }
         }
@@ -1096,7 +1089,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;
@@ -1106,7 +1099,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;
@@ -1118,7 +1111,7 @@
             for (const Behavior& b : key.behaviors) {
                     if (b.metaState == property.metaState) {
                     ALOGE("%s: Duplicate key behavior for modifier.",
-                            mTokenizer->getLocation().string());
+                          mTokenizer->getLocation().c_str());
                     return BAD_VALUE;
                     }
             }
@@ -1185,8 +1178,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;
             }
 
@@ -1259,7 +1252,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 a194513..ddc9ea4 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -177,7 +177,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) {
@@ -306,8 +306,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);
 
@@ -334,16 +334,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;
             }
         }
@@ -362,26 +361,26 @@
         codeToken = mTokenizer->nextToken(WHITESPACE);
     }
 
-    std::optional<int> code = parseInt(codeToken.string());
+    std::optional<int> code = parseInt(codeToken.c_str());
     if (!code) {
-        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);
-    std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+    std::optional<int> 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;
     }
 
@@ -391,15 +390,15 @@
         if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
 
         String8 flagToken = mTokenizer->nextToken(WHITESPACE);
-        std::optional<int> flag = InputEventLookup::getKeyFlagByLabel(flagToken.string());
+        std::optional<int> 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;
@@ -417,15 +416,15 @@
 
 status_t KeyLayoutMap::Parser::parseAxis() {
     String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
-    std::optional<int> scanCode = parseInt(scanCodeToken.string());
+    std::optional<int> scanCode = parseInt(scanCodeToken.c_str());
     if (!scanCode) {
-        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;
     }
 
@@ -438,10 +437,10 @@
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 axisToken = mTokenizer->nextToken(WHITESPACE);
-        std::optional<int> axis = InputEventLookup::getAxisByLabel(axisToken.string());
+        std::optional<int> axis = InputEventLookup::getAxisByLabel(axisToken.c_str());
         if (!axis) {
             ALOGE("%s: Expected inverted axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), axisToken.string());
+                    mTokenizer->getLocation().c_str(), axisToken.c_str());
             return BAD_VALUE;
         }
         axisInfo.axis = *axis;
@@ -450,38 +449,38 @@
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 splitToken = mTokenizer->nextToken(WHITESPACE);
-        std::optional<int> splitValue = parseInt(splitToken.string());
+        std::optional<int> splitValue = parseInt(splitToken.c_str());
         if (!splitValue) {
             ALOGE("%s: Expected split value, got '%s'.",
-                    mTokenizer->getLocation().string(), splitToken.string());
+                    mTokenizer->getLocation().c_str(), splitToken.c_str());
             return BAD_VALUE;
         }
         axisInfo.splitValue = *splitValue;
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
-        std::optional<int> axis = InputEventLookup::getAxisByLabel(lowAxisToken.string());
+        std::optional<int> axis = InputEventLookup::getAxisByLabel(lowAxisToken.c_str());
         if (!axis) {
             ALOGE("%s: Expected low axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), lowAxisToken.string());
+                    mTokenizer->getLocation().c_str(), lowAxisToken.c_str());
             return BAD_VALUE;
         }
         axisInfo.axis = *axis;
 
         mTokenizer->skipDelimiters(WHITESPACE);
         String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
-        std::optional<int> highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string());
+        std::optional<int> highAxis = InputEventLookup::getAxisByLabel(highAxisToken.c_str());
         if (!highAxis) {
             ALOGE("%s: Expected high axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), highAxisToken.string());
+                    mTokenizer->getLocation().c_str(), highAxisToken.c_str());
             return BAD_VALUE;
         }
         axisInfo.highAxis = *highAxis;
     } else {
-        std::optional<int> axis = InputEventLookup::getAxisByLabel(token.string());
+        std::optional<int> axis = InputEventLookup::getAxisByLabel(token.c_str());
         if (!axis) {
             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;
         }
         axisInfo.axis = *axis;
@@ -496,16 +495,16 @@
         if (keywordToken == "flat") {
             mTokenizer->skipDelimiters(WHITESPACE);
             String8 flatToken = mTokenizer->nextToken(WHITESPACE);
-            std::optional<int> flatOverride = parseInt(flatToken.string());
+            std::optional<int> flatOverride = parseInt(flatToken.c_str());
             if (!flatOverride) {
                 ALOGE("%s: Expected flat value, got '%s'.",
-                        mTokenizer->getLocation().string(), flatToken.string());
+                        mTokenizer->getLocation().c_str(), flatToken.c_str());
                 return BAD_VALUE;
             }
             axisInfo.flatOverride = *flatOverride;
         } 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;
         }
     }
@@ -527,27 +526,27 @@
         mTokenizer->skipDelimiters(WHITESPACE);
         codeToken = mTokenizer->nextToken(WHITESPACE);
     }
-    std::optional<int> code = parseInt(codeToken.string());
+    std::optional<int> code = parseInt(codeToken.c_str());
     if (!code) {
-        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);
-    std::optional<int> ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string());
+    std::optional<int> ledCode = InputEventLookup::getLedByLabel(ledCodeToken.c_str());
     if (!ledCode) {
-        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;
     }
 
@@ -569,7 +568,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") {
@@ -594,26 +593,26 @@
 // sensor 0x05 GYROSCOPE Z
 status_t KeyLayoutMap::Parser::parseSensor() {
     String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    std::optional<int> code = parseInt(codeToken.string());
+    std::optional<int> code = parseInt(codeToken.c_str());
     if (!code) {
-        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();
@@ -621,8 +620,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();
@@ -643,12 +642,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/PropertyMap.cpp b/libs/input/PropertyMap.cpp
index 548f894..315f5a6 100644
--- a/libs/input/PropertyMap.cpp
+++ b/libs/input/PropertyMap.cpp
@@ -163,8 +163,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);
@@ -172,7 +172,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;
             }
 
@@ -180,7 +180,7 @@
 
             if (mTokenizer->nextChar() != '=') {
                 ALOGE("%s: Expected '=' between property key and value.",
-                      mTokenizer->getLocation().string());
+                      mTokenizer->getLocation().c_str());
                 return BAD_VALUE;
             }
 
@@ -189,20 +189,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.string())) {
                 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 f7f2d54..422b070 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/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 48718bb..aefa1f0 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) {
@@ -424,7 +425,13 @@
     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_HLG_EXT) {
         return static_cast<android_dataspace>(HAL_DATASPACE_BT2020_HLG);
     } 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;
     }
@@ -573,8 +580,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) {
@@ -714,7 +719,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 4a08c11..48d793a 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -143,7 +143,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 ec0388d..de99fc7 100644
--- a/services/inputflinger/host/InputDriver.cpp
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -256,14 +256,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;
 }
@@ -281,7 +281,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/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 fe2db94..da4186b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5709,7 +5709,7 @@
 
     const auto name = String8(args[1]);
     mCurrentState.traverseInZOrder([&](Layer* layer) {
-        if (layer->getName() == name.string()) {
+        if (layer->getName() == name.c_str()) {
             layer->dumpFrameStats(result);
         }
     });
@@ -5720,7 +5720,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/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index 1cc9ba4..dbf0cd8 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -91,7 +91,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
@@ -123,7 +123,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 f297da5..1675584 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -170,7 +170,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/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 8e3971d..a257f06 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -532,7 +532,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;
@@ -551,7 +552,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 |
@@ -561,9 +569,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 |
@@ -1359,7 +1365,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) "